/
validation.ts
110 lines (103 loc) · 3.07 KB
/
validation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { bold } from 'kleur/colors';
import type { ComponentInstance, GetStaticPathsResult, RouteData } from '../../@types/astro';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { LogOptions } from '../logger/core';
import { warn } from '../logger/core.js';
const VALID_PARAM_TYPES = ['string', 'number', 'undefined'];
/** Throws error for invalid parameter in getStaticPaths() response */
export function validateGetStaticPathsParameter([key, value]: [string, any], route: string) {
if (!VALID_PARAM_TYPES.includes(typeof value)) {
throw new AstroError({
...AstroErrorData.GetStaticPathsInvalidRouteParam,
message: AstroErrorData.GetStaticPathsInvalidRouteParam.message(key, value, typeof value),
location: {
file: route,
},
});
}
}
/** Warn or error for deprecated or malformed route components */
export function validateDynamicRouteModule(
mod: ComponentInstance,
{
ssr,
logging,
route,
}: {
ssr: boolean;
logging: LogOptions;
route: RouteData;
}
) {
if (ssr && mod.getStaticPaths && !route.prerender) {
warn(
logging,
'getStaticPaths',
`getStaticPaths() in ${bold(route.component)} is ignored when "output: server" is set.`
);
}
if ((!ssr || route.prerender) && !mod.getStaticPaths) {
throw new AstroError({
...AstroErrorData.GetStaticPathsRequired,
location: { file: route.component },
});
}
}
/** Throw error and log warnings for malformed getStaticPaths() response */
export function validateGetStaticPathsResult(
result: GetStaticPathsResult,
logging: LogOptions,
route: RouteData
) {
if (!Array.isArray(result)) {
throw new AstroError({
...AstroErrorData.InvalidGetStaticPathsReturn,
message: AstroErrorData.InvalidGetStaticPathsReturn.message(typeof result),
location: {
file: route.component,
},
});
}
result.forEach((pathObject) => {
if (
pathObject.params === undefined ||
pathObject.params === null ||
(pathObject.params && Object.keys(pathObject.params).length === 0)
) {
throw new AstroError({
...AstroErrorData.GetStaticPathsExpectedParams,
location: {
file: route.component,
},
});
}
if (typeof pathObject.params !== 'object') {
throw new AstroError({
...AstroErrorData.InvalidGetStaticPathParam,
message: AstroErrorData.InvalidGetStaticPathParam.message(typeof pathObject.params),
location: {
file: route.component,
},
});
}
// TODO: Replace those with errors? They technically don't crash the build, but users might miss the warning. - erika, 2022-11-07
for (const [key, val] of Object.entries(pathObject.params)) {
if (!(typeof val === 'undefined' || typeof val === 'string' || typeof val === 'number')) {
warn(
logging,
'getStaticPaths',
`invalid path param: ${key}. A string, number or undefined value was expected, but got \`${JSON.stringify(
val
)}\`.`
);
}
if (typeof val === 'string' && val === '') {
warn(
logging,
'getStaticPaths',
`invalid path param: ${key}. \`undefined\` expected for an optional param, but got empty string.`
);
}
}
});
}