@vercel/redwood 2.5.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +260 -19
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -814,10 +814,11 @@ var require_superstatic = __commonJS({
|
|
|
814
814
|
var superstatic_exports = {};
|
|
815
815
|
__export2(superstatic_exports, {
|
|
816
816
|
collectHasSegments: () => collectHasSegments,
|
|
817
|
+
compilePathToRegexpTemplate: () => compilePathToRegexpTemplate2,
|
|
817
818
|
convertCleanUrls: () => convertCleanUrls,
|
|
818
819
|
convertHeaders: () => convertHeaders,
|
|
819
820
|
convertRedirects: () => convertRedirects,
|
|
820
|
-
convertRewrites: () =>
|
|
821
|
+
convertRewrites: () => convertRewrites2,
|
|
821
822
|
convertTrailingSlash: () => convertTrailingSlash,
|
|
822
823
|
getCleanUrls: () => getCleanUrls2,
|
|
823
824
|
pathToRegexp: () => pathToRegexp,
|
|
@@ -933,21 +934,46 @@ var require_superstatic = __commonJS({
|
|
|
933
934
|
}
|
|
934
935
|
});
|
|
935
936
|
}
|
|
936
|
-
function
|
|
937
|
+
function convertRewrites2(rewrites, internalParamNames) {
|
|
937
938
|
return rewrites.map((r) => {
|
|
938
939
|
const { src, segments } = sourceToRegex2(r.source);
|
|
939
940
|
const hasSegments = collectHasSegments(r.has);
|
|
940
941
|
normalizeHasKeys(r.has);
|
|
941
942
|
normalizeHasKeys(r.missing);
|
|
942
943
|
try {
|
|
943
|
-
const
|
|
944
|
+
const interpolate = (value) => replaceSegments(
|
|
944
945
|
segments,
|
|
945
946
|
hasSegments,
|
|
946
|
-
|
|
947
|
+
value,
|
|
947
948
|
false,
|
|
948
949
|
internalParamNames
|
|
949
950
|
);
|
|
950
|
-
|
|
951
|
+
let route;
|
|
952
|
+
if (typeof r.destination === "string") {
|
|
953
|
+
route = { src, dest: interpolate(r.destination), check: true };
|
|
954
|
+
} else {
|
|
955
|
+
const destination = { ...r.destination, type: "service" };
|
|
956
|
+
if (typeof destination.path === "string") {
|
|
957
|
+
destination.path = interpolate(destination.path);
|
|
958
|
+
}
|
|
959
|
+
route = { src, destination };
|
|
960
|
+
}
|
|
961
|
+
if (r.transforms) {
|
|
962
|
+
route.transforms = r.transforms.map((transform) => {
|
|
963
|
+
if (transform.type !== "request.path") {
|
|
964
|
+
return { ...transform };
|
|
965
|
+
}
|
|
966
|
+
return {
|
|
967
|
+
...transform,
|
|
968
|
+
args: compilePathToRegexpTemplateFromSegments(
|
|
969
|
+
transform.args,
|
|
970
|
+
segments,
|
|
971
|
+
hasSegments,
|
|
972
|
+
transform.env
|
|
973
|
+
)
|
|
974
|
+
};
|
|
975
|
+
});
|
|
976
|
+
}
|
|
951
977
|
if (typeof r.env !== "undefined") {
|
|
952
978
|
route.env = r.env;
|
|
953
979
|
}
|
|
@@ -1088,6 +1114,81 @@ var require_superstatic = __commonJS({
|
|
|
1088
1114
|
}
|
|
1089
1115
|
var escapeSegment = (str, segmentName) => str.replace(new RegExp(`:${segmentName}`, "g"), `__ESC_COLON_${segmentName}`);
|
|
1090
1116
|
var unescapeSegments = (str) => str.replace(/__ESC_COLON_/gi, ":");
|
|
1117
|
+
var pathTemplateSegmentNameRegex = /^([a-zA-Z_][a-zA-Z0-9_]*)/;
|
|
1118
|
+
function isEscaped(value, index) {
|
|
1119
|
+
let backslashCount = 0;
|
|
1120
|
+
for (let i = index - 1; i >= 0 && value[i] === "\\"; i--) {
|
|
1121
|
+
backslashCount++;
|
|
1122
|
+
}
|
|
1123
|
+
return backslashCount % 2 === 1;
|
|
1124
|
+
}
|
|
1125
|
+
function collectPathTemplateSegments(template) {
|
|
1126
|
+
const segments = [];
|
|
1127
|
+
for (let i = 0; i < template.length; i++) {
|
|
1128
|
+
if (template[i] !== ":" || isEscaped(template, i)) {
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
const match = template.slice(i + 1).match(pathTemplateSegmentNameRegex);
|
|
1132
|
+
if (match) {
|
|
1133
|
+
segments.push(match[1]);
|
|
1134
|
+
i += match[1].length;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
return segments;
|
|
1138
|
+
}
|
|
1139
|
+
function collectNamedDollarReferences(template) {
|
|
1140
|
+
const references = [];
|
|
1141
|
+
for (let i = 0; i < template.length; i++) {
|
|
1142
|
+
if (template[i] !== "$" || isEscaped(template, i)) {
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
const remainder = template.slice(i + 1);
|
|
1146
|
+
const bracedMatch = remainder.match(/^\{([a-zA-Z_][a-zA-Z0-9_]*)\}/);
|
|
1147
|
+
const unbracedMatch = remainder.match(pathTemplateSegmentNameRegex);
|
|
1148
|
+
const name = bracedMatch?.[1] || unbracedMatch?.[1];
|
|
1149
|
+
if (name) {
|
|
1150
|
+
references.push(name);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
return references;
|
|
1154
|
+
}
|
|
1155
|
+
function compilePathToRegexpTemplateFromSegments(template, segments, hasItemSegments, env = []) {
|
|
1156
|
+
const indexes = {};
|
|
1157
|
+
segments.forEach((name, index) => {
|
|
1158
|
+
indexes[name] = toSegmentDest(index);
|
|
1159
|
+
});
|
|
1160
|
+
hasItemSegments.forEach((name) => {
|
|
1161
|
+
indexes[name] = `$${name}`;
|
|
1162
|
+
});
|
|
1163
|
+
for (const name of collectPathTemplateSegments(template)) {
|
|
1164
|
+
if (!(name in indexes)) {
|
|
1165
|
+
throw new Error(
|
|
1166
|
+
`Path template references parameter ":${name}" that is not present in the source or has conditions.`
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
const routeParameters = /* @__PURE__ */ new Set([
|
|
1171
|
+
...segments.filter((name) => name !== UN_NAMED_SEGMENT),
|
|
1172
|
+
...hasItemSegments
|
|
1173
|
+
]);
|
|
1174
|
+
for (const name of collectNamedDollarReferences(template)) {
|
|
1175
|
+
if (routeParameters.has(name) && !env.includes(name)) {
|
|
1176
|
+
throw new Error(
|
|
1177
|
+
`Path template references route parameter "${name}" as \`$${name}\`. Use \`:${name}\` path-to-regexp syntax in high-level rewrites, or list "${name}" in the transform env allowlist if it is an environment variable.`
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
return safelyCompile(template, indexes, true);
|
|
1182
|
+
}
|
|
1183
|
+
function compilePathToRegexpTemplate2(source, template, has, env) {
|
|
1184
|
+
const { segments } = sourceToRegex2(source);
|
|
1185
|
+
return compilePathToRegexpTemplateFromSegments(
|
|
1186
|
+
template,
|
|
1187
|
+
segments,
|
|
1188
|
+
collectHasSegments(has),
|
|
1189
|
+
env
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1091
1192
|
function replaceSegments(segments, hasItemSegments, destination, isRedirect, internalParamNames) {
|
|
1092
1193
|
const namedSegments = segments.filter((name) => name !== UN_NAMED_SEGMENT);
|
|
1093
1194
|
const canNeedReplacing = destination.includes(":") && namedSegments.length > 0 || hasItemSegments.length > 0 || !isRedirect;
|
|
@@ -1489,7 +1590,8 @@ var require_schemas = __commonJS({
|
|
|
1489
1590
|
redirectsSchema: () => redirectsSchema,
|
|
1490
1591
|
rewritesSchema: () => rewritesSchema,
|
|
1491
1592
|
routesSchema: () => routesSchema,
|
|
1492
|
-
trailingSlashSchema: () => trailingSlashSchema
|
|
1593
|
+
trailingSlashSchema: () => trailingSlashSchema,
|
|
1594
|
+
transformsSchema: () => transformsSchema
|
|
1493
1595
|
});
|
|
1494
1596
|
module2.exports = __toCommonJS2(schemas_exports);
|
|
1495
1597
|
var mitigateSchema = {
|
|
@@ -1505,6 +1607,32 @@ var require_schemas = __commonJS({
|
|
|
1505
1607
|
}
|
|
1506
1608
|
}
|
|
1507
1609
|
};
|
|
1610
|
+
var serviceNameSchema = {
|
|
1611
|
+
description: "A service name identifier.",
|
|
1612
|
+
type: "string",
|
|
1613
|
+
minLength: 1,
|
|
1614
|
+
maxLength: 64,
|
|
1615
|
+
pattern: "^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$"
|
|
1616
|
+
};
|
|
1617
|
+
var serviceDestinationSchema = {
|
|
1618
|
+
description: "A service-targeted destination that delegates routing into a named service from `services`. Identified by the presence of `service`.",
|
|
1619
|
+
type: "object",
|
|
1620
|
+
additionalProperties: false,
|
|
1621
|
+
required: ["service"],
|
|
1622
|
+
properties: {
|
|
1623
|
+
type: {
|
|
1624
|
+
description: "Optional explicit format marker. The destination shape is identified by the `service` property, so `type` is no longer required. When present it must be `service`.",
|
|
1625
|
+
type: "string",
|
|
1626
|
+
enum: ["service"]
|
|
1627
|
+
},
|
|
1628
|
+
service: serviceNameSchema,
|
|
1629
|
+
path: {
|
|
1630
|
+
description: "Routing-only path used to select a route inside the target service. It does not mutate the URL observed by user code.",
|
|
1631
|
+
type: "string",
|
|
1632
|
+
maxLength: 4096
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
};
|
|
1508
1636
|
var matchableValueSchema = {
|
|
1509
1637
|
description: "A value to match against. Can be a string (regex) or a condition operation object",
|
|
1510
1638
|
anyOf: [
|
|
@@ -1628,18 +1756,23 @@ var require_schemas = __commonJS({
|
|
|
1628
1756
|
}
|
|
1629
1757
|
};
|
|
1630
1758
|
var transformsSchema = {
|
|
1631
|
-
description: "A list of transform rules to adjust
|
|
1759
|
+
description: "A list of transform rules to adjust a request path, request query parameters, or request/response headers",
|
|
1632
1760
|
type: "array",
|
|
1633
1761
|
minItems: 1,
|
|
1634
1762
|
items: {
|
|
1635
1763
|
type: "object",
|
|
1636
1764
|
additionalProperties: false,
|
|
1637
|
-
required: ["type", "op"
|
|
1765
|
+
required: ["type", "op"],
|
|
1638
1766
|
properties: {
|
|
1639
1767
|
type: {
|
|
1640
1768
|
description: "The scope of the transform to apply",
|
|
1641
1769
|
type: "string",
|
|
1642
|
-
enum: [
|
|
1770
|
+
enum: [
|
|
1771
|
+
"request.headers",
|
|
1772
|
+
"request.query",
|
|
1773
|
+
"response.headers",
|
|
1774
|
+
"request.path"
|
|
1775
|
+
]
|
|
1643
1776
|
},
|
|
1644
1777
|
op: {
|
|
1645
1778
|
description: "The operation to perform on the target",
|
|
@@ -1825,10 +1958,90 @@ var require_schemas = __commonJS({
|
|
|
1825
1958
|
}
|
|
1826
1959
|
}
|
|
1827
1960
|
}
|
|
1961
|
+
},
|
|
1962
|
+
{
|
|
1963
|
+
if: {
|
|
1964
|
+
required: ["type"],
|
|
1965
|
+
properties: {
|
|
1966
|
+
type: {
|
|
1967
|
+
enum: ["request.headers", "request.query", "response.headers"]
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
},
|
|
1971
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then keyword
|
|
1972
|
+
then: {
|
|
1973
|
+
required: ["target"]
|
|
1974
|
+
}
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
if: {
|
|
1978
|
+
required: ["type"],
|
|
1979
|
+
properties: {
|
|
1980
|
+
type: {
|
|
1981
|
+
enum: ["request.path"]
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then keyword
|
|
1986
|
+
then: {
|
|
1987
|
+
required: ["args"],
|
|
1988
|
+
not: {
|
|
1989
|
+
required: ["target"]
|
|
1990
|
+
},
|
|
1991
|
+
properties: {
|
|
1992
|
+
op: {
|
|
1993
|
+
enum: ["set"]
|
|
1994
|
+
},
|
|
1995
|
+
args: {
|
|
1996
|
+
description: "The runtime-visible request path. Must be an origin-form path without query or fragment.",
|
|
1997
|
+
type: "string",
|
|
1998
|
+
maxLength: 2048,
|
|
1999
|
+
pattern: "^/(?!/)(?!.*[?#\\s\\x00-\\x1F\\x7F]).*$"
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
1828
2003
|
}
|
|
1829
2004
|
]
|
|
1830
2005
|
}
|
|
1831
2006
|
};
|
|
2007
|
+
var rewriteTransformsSchema = {
|
|
2008
|
+
description: "A list of request path transforms using path-to-regexp parameters.",
|
|
2009
|
+
type: "array",
|
|
2010
|
+
minItems: 1,
|
|
2011
|
+
items: {
|
|
2012
|
+
type: "object",
|
|
2013
|
+
additionalProperties: false,
|
|
2014
|
+
required: ["type", "op", "args"],
|
|
2015
|
+
properties: {
|
|
2016
|
+
type: {
|
|
2017
|
+
description: "The request path to expose to the target runtime",
|
|
2018
|
+
type: "string",
|
|
2019
|
+
enum: ["request.path"]
|
|
2020
|
+
},
|
|
2021
|
+
op: {
|
|
2022
|
+
description: "Replace the runtime-visible request path",
|
|
2023
|
+
type: "string",
|
|
2024
|
+
enum: ["set"]
|
|
2025
|
+
},
|
|
2026
|
+
args: {
|
|
2027
|
+
description: "An origin-form request path. Route parameters use path-to-regexp syntax such as `/:path*`.",
|
|
2028
|
+
type: "string",
|
|
2029
|
+
maxLength: 2048,
|
|
2030
|
+
pattern: "^/(?!/)(?!.*[?#\\s\\x00-\\x1F\\x7F]).*$"
|
|
2031
|
+
},
|
|
2032
|
+
env: {
|
|
2033
|
+
description: "An array of environment variable names that should be replaced at runtime in the args value",
|
|
2034
|
+
type: "array",
|
|
2035
|
+
minItems: 1,
|
|
2036
|
+
maxItems: 64,
|
|
2037
|
+
items: {
|
|
2038
|
+
type: "string",
|
|
2039
|
+
maxLength: 256
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
1832
2045
|
var routesSchema = {
|
|
1833
2046
|
type: "array",
|
|
1834
2047
|
description: "A list of routes objects used to rewrite paths to point towards other internal or external paths",
|
|
@@ -1853,8 +2066,10 @@ var require_schemas = __commonJS({
|
|
|
1853
2066
|
maxLength: 4096
|
|
1854
2067
|
},
|
|
1855
2068
|
destination: {
|
|
1856
|
-
|
|
1857
|
-
|
|
2069
|
+
anyOf: [
|
|
2070
|
+
{ type: "string", maxLength: 4096 },
|
|
2071
|
+
serviceDestinationSchema
|
|
2072
|
+
]
|
|
1858
2073
|
},
|
|
1859
2074
|
headers: {
|
|
1860
2075
|
type: "object",
|
|
@@ -2003,10 +2218,10 @@ var require_schemas = __commonJS({
|
|
|
2003
2218
|
maxLength: 4096
|
|
2004
2219
|
},
|
|
2005
2220
|
destination: {
|
|
2006
|
-
description: "An absolute pathname to an existing resource
|
|
2007
|
-
type: "string",
|
|
2008
|
-
maxLength: 4096
|
|
2221
|
+
description: "An absolute pathname to an existing resource, an external URL, or a service-targeted destination object.",
|
|
2222
|
+
anyOf: [{ type: "string", maxLength: 4096 }, serviceDestinationSchema]
|
|
2009
2223
|
},
|
|
2224
|
+
transforms: rewriteTransformsSchema,
|
|
2010
2225
|
has: hasSchema,
|
|
2011
2226
|
missing: hasSchema,
|
|
2012
2227
|
statusCode: {
|
|
@@ -2175,6 +2390,8 @@ var require_dist3 = __commonJS({
|
|
|
2175
2390
|
var src_exports2 = {};
|
|
2176
2391
|
__export2(src_exports2, {
|
|
2177
2392
|
appendRoutesToPhase: () => import_append.appendRoutesToPhase,
|
|
2393
|
+
compilePathToRegexpTemplate: () => import_superstatic2.compilePathToRegexpTemplate,
|
|
2394
|
+
convertRewrites: () => import_superstatic2.convertRewrites,
|
|
2178
2395
|
getCleanUrls: () => import_superstatic2.getCleanUrls,
|
|
2179
2396
|
getOwnershipGuard: () => import_service_route_ownership.getOwnershipGuard,
|
|
2180
2397
|
getTransformedRoutes: () => getTransformedRoutes2,
|
|
@@ -2226,8 +2443,12 @@ var require_dist3 = __commonJS({
|
|
|
2226
2443
|
`Route at index ${index} cannot define both \`dest\` and \`destination\`. Please use only one.`
|
|
2227
2444
|
);
|
|
2228
2445
|
}
|
|
2229
|
-
|
|
2230
|
-
|
|
2446
|
+
if (typeof route.destination === "string") {
|
|
2447
|
+
route.dest = route.destination;
|
|
2448
|
+
delete route.destination;
|
|
2449
|
+
} else if (typeof route.destination.service === "string") {
|
|
2450
|
+
route.destination = { ...route.destination, type: "service" };
|
|
2451
|
+
}
|
|
2231
2452
|
}
|
|
2232
2453
|
if (route.statusCode !== void 0) {
|
|
2233
2454
|
if (route.status !== void 0) {
|
|
@@ -2287,6 +2508,11 @@ var require_dist3 = __commonJS({
|
|
|
2287
2508
|
if (regError) {
|
|
2288
2509
|
errors.push(regError);
|
|
2289
2510
|
}
|
|
2511
|
+
if (route.destination && typeof route.destination === "object" && route.continue) {
|
|
2512
|
+
errors.push(
|
|
2513
|
+
`Route at index ${i} cannot define \`continue: true\` with a service \`destination\`. The service handoff is terminal.`
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2290
2516
|
const handleValue = handling[handling.length - 1];
|
|
2291
2517
|
if (handleValue === "hit") {
|
|
2292
2518
|
if (route.dest) {
|
|
@@ -2341,7 +2567,8 @@ var require_dist3 = __commonJS({
|
|
|
2341
2567
|
function checkPatternSyntax(type, index, {
|
|
2342
2568
|
source,
|
|
2343
2569
|
destination,
|
|
2344
|
-
has
|
|
2570
|
+
has,
|
|
2571
|
+
transforms
|
|
2345
2572
|
}) {
|
|
2346
2573
|
let sourceSegments = /* @__PURE__ */ new Set();
|
|
2347
2574
|
const destinationSegments = /* @__PURE__ */ new Set();
|
|
@@ -2353,9 +2580,10 @@ var require_dist3 = __commonJS({
|
|
|
2353
2580
|
link: "https://vercel.link/invalid-route-source-pattern"
|
|
2354
2581
|
};
|
|
2355
2582
|
}
|
|
2356
|
-
|
|
2583
|
+
const destinationString = typeof destination === "string" ? destination : typeof destination?.path === "string" ? destination.path : void 0;
|
|
2584
|
+
if (destinationString !== void 0) {
|
|
2357
2585
|
try {
|
|
2358
|
-
const { hostname, pathname, query } = (0, import_url.parse)(
|
|
2586
|
+
const { hostname, pathname, query } = (0, import_url.parse)(destinationString, true);
|
|
2359
2587
|
(0, import_superstatic.sourceToRegex)(hostname || "").segments.forEach(
|
|
2360
2588
|
(name) => destinationSegments.add(name)
|
|
2361
2589
|
);
|
|
@@ -2380,6 +2608,19 @@ var require_dist3 = __commonJS({
|
|
|
2380
2608
|
}
|
|
2381
2609
|
}
|
|
2382
2610
|
}
|
|
2611
|
+
for (const transform of transforms || []) {
|
|
2612
|
+
if (transform.type !== "request.path") {
|
|
2613
|
+
continue;
|
|
2614
|
+
}
|
|
2615
|
+
try {
|
|
2616
|
+
(0, import_superstatic.compilePathToRegexpTemplate)(source, transform.args, has, transform.env);
|
|
2617
|
+
} catch (error) {
|
|
2618
|
+
return {
|
|
2619
|
+
message: `${type} at index ${index} has an invalid \`request.path\` transform: ${error instanceof Error ? error.message : String(error)}`,
|
|
2620
|
+
link: "https://vercel.link/invalid-route-destination-segment"
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2383
2624
|
return null;
|
|
2384
2625
|
}
|
|
2385
2626
|
function checkRedirect(r, index) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/redwood",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://vercel.com/docs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@vercel/nft": "1.10.0",
|
|
17
17
|
"semver": "6.3.1",
|
|
18
18
|
"ts-morph": "12.0.0",
|
|
19
|
-
"@vercel/static-config": "3.4.
|
|
19
|
+
"@vercel/static-config": "3.4.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/aws-lambda": "8.10.19",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"execa": "3.2.0",
|
|
26
26
|
"fs-extra": "11.1.0",
|
|
27
27
|
"vitest": "2.0.3",
|
|
28
|
-
"@vercel/build-utils": "
|
|
29
|
-
"@vercel/routing-utils": "6.
|
|
28
|
+
"@vercel/build-utils": "14.0.1",
|
|
29
|
+
"@vercel/routing-utils": "6.4.1"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "node ../../utils/build-builder.mjs",
|