@marko/run 0.5.13 → 0.5.15
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/README.md +85 -76
- package/dist/.tsbuildinfo +1 -1
- package/dist/adapter/default-entry.mjs +12 -13
- package/dist/adapter/index.cjs +476 -453
- package/dist/adapter/index.d.ts +2 -2
- package/dist/adapter/index.js +480 -457
- package/dist/adapter/load-dev-worker.mjs +5 -5
- package/dist/adapter/middleware.cjs +5 -3
- package/dist/adapter/middleware.d.ts +1 -1
- package/dist/adapter/middleware.js +5 -3
- package/dist/adapter/polyfill.d.ts +1 -1
- package/dist/cli/default.config.mjs +2 -2
- package/dist/cli/index.mjs +1353 -1280
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/internal.cjs +12 -2
- package/dist/runtime/internal.d.ts +3 -1
- package/dist/runtime/internal.js +9 -1
- package/dist/runtime/namespace.d.ts +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/vite/codegen/index.d.ts +1 -1
- package/dist/vite/constants.d.ts +2 -2
- package/dist/vite/index.cjs +1468 -1395
- package/dist/vite/index.d.ts +2 -2
- package/dist/vite/index.js +1463 -1390
- package/dist/vite/plugin.d.ts +1 -1
- package/dist/vite/routes/vdir.d.ts +1 -1
- package/dist/vite/types.d.ts +3 -3
- package/dist/vite/utils/config.d.ts +1 -1
- package/dist/vite/utils/log.d.ts +1 -1
- package/dist/vite/utils/route.d.ts +2 -2
- package/dist/vite/utils/server.d.ts +1 -1
- package/package.json +60 -63
package/dist/cli/index.mjs
CHANGED
|
@@ -14,74 +14,66 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
14
14
|
import sade from "sade";
|
|
15
15
|
|
|
16
16
|
// src/cli/commands.ts
|
|
17
|
-
import path5 from "path";
|
|
18
17
|
import fs5 from "fs";
|
|
18
|
+
import path5 from "path";
|
|
19
19
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20
20
|
import {
|
|
21
21
|
build as viteBuild,
|
|
22
22
|
resolveConfig
|
|
23
23
|
} from "vite";
|
|
24
24
|
|
|
25
|
-
// src/vite/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
var setExternalPluginOptions = (viteConfig, value) => setConfig(viteConfig, PluginConfigKey, value);
|
|
37
|
-
var getExternalAdapterOptions = (viteConfig) => getConfig(viteConfig, AdapterConfigKey);
|
|
38
|
-
var setExternalAdapterOptions = (viteConfig, value) => setConfig(viteConfig, AdapterConfigKey, value);
|
|
25
|
+
// src/vite/plugin.ts
|
|
26
|
+
import markoVitePlugin from "@marko/vite";
|
|
27
|
+
import browserslist from "browserslist";
|
|
28
|
+
import { createHash } from "crypto";
|
|
29
|
+
import createDebug from "debug";
|
|
30
|
+
import { resolveToEsbuildTarget } from "esbuild-plugin-browserslist";
|
|
31
|
+
import fs3 from "fs";
|
|
32
|
+
import { glob } from "glob";
|
|
33
|
+
import path4 from "path";
|
|
34
|
+
import { fileURLToPath } from "url";
|
|
35
|
+
import { buildErrorMessage, mergeConfig } from "vite";
|
|
39
36
|
|
|
40
|
-
// src/
|
|
41
|
-
import
|
|
42
|
-
import
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const connection = net.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () => {
|
|
49
|
-
connection.end();
|
|
50
|
-
resolve(null);
|
|
51
|
-
}).on("connect", () => {
|
|
52
|
-
resolve(connection);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
37
|
+
// src/adapter/utils.ts
|
|
38
|
+
import kleur from "kleur";
|
|
39
|
+
import supporsColor from "supports-color";
|
|
40
|
+
function stripAnsi(string) {
|
|
41
|
+
return string.replace(
|
|
42
|
+
/([\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><])/g,
|
|
43
|
+
""
|
|
44
|
+
);
|
|
55
45
|
}
|
|
56
|
-
|
|
57
|
-
return
|
|
46
|
+
function cleanStack(stack) {
|
|
47
|
+
return stack.split(/\n/).filter((l) => /^\s*at/.test(l)).join("\n");
|
|
58
48
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
function prepareError(err) {
|
|
50
|
+
var _a;
|
|
51
|
+
return {
|
|
52
|
+
message: stripAnsi(err.message),
|
|
53
|
+
stack: stripAnsi(cleanStack(err.stack || "")),
|
|
54
|
+
id: err.id,
|
|
55
|
+
frame: stripAnsi(err.frame || ""),
|
|
56
|
+
plugin: err.plugin,
|
|
57
|
+
pluginCode: (_a = err.pluginCode) == null ? void 0 : _a.toString(),
|
|
58
|
+
loc: err.loc
|
|
59
|
+
};
|
|
69
60
|
}
|
|
70
61
|
|
|
71
|
-
// src/vite/
|
|
72
|
-
import
|
|
73
|
-
import fs4 from "fs";
|
|
74
|
-
import { glob } from "glob";
|
|
75
|
-
import { fileURLToPath } from "url";
|
|
76
|
-
import browserslist from "browserslist";
|
|
77
|
-
import { resolveToEsbuildTarget } from "esbuild-plugin-browserslist";
|
|
78
|
-
import { buildErrorMessage, mergeConfig } from "vite";
|
|
79
|
-
import markoVitePlugin from "@marko/vite";
|
|
62
|
+
// src/vite/codegen/index.ts
|
|
63
|
+
import path from "path";
|
|
80
64
|
|
|
81
65
|
// src/vite/constants.ts
|
|
82
66
|
var markoRunFilePrefix = "__marko-run__";
|
|
83
67
|
var virtualFilePrefix = "virtual:marko-run";
|
|
84
|
-
var httpVerbs = [
|
|
68
|
+
var httpVerbs = [
|
|
69
|
+
"get",
|
|
70
|
+
"head",
|
|
71
|
+
"post",
|
|
72
|
+
"put",
|
|
73
|
+
"delete",
|
|
74
|
+
"patch",
|
|
75
|
+
"options"
|
|
76
|
+
];
|
|
85
77
|
var serverEntryQuery = "?marko-server-entry";
|
|
86
78
|
var RoutableFileTypes = {
|
|
87
79
|
Page: "page",
|
|
@@ -93,557 +85,62 @@ var RoutableFileTypes = {
|
|
|
93
85
|
Error: "500"
|
|
94
86
|
};
|
|
95
87
|
|
|
96
|
-
// src/vite/
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
this.parent = null;
|
|
110
|
-
this.source = null;
|
|
111
|
-
this.path = "/";
|
|
112
|
-
this.fullPath = "/";
|
|
113
|
-
this.segment = {
|
|
114
|
-
raw: "",
|
|
115
|
-
name: ""
|
|
116
|
-
};
|
|
117
|
-
} else {
|
|
118
|
-
this.parent = parent;
|
|
119
|
-
this.source = source;
|
|
120
|
-
this.path = parent.path + (parent.path === "/" ? segment.name : `/${segment.name}`);
|
|
121
|
-
this.fullPath = parent.fullPath + (parent.fullPath === "/" ? segment.name : `/${segment.name}`);
|
|
122
|
-
if (segment.param) {
|
|
123
|
-
this.fullPath += segment.param;
|
|
124
|
-
}
|
|
125
|
-
this.segment = segment;
|
|
126
|
-
}
|
|
88
|
+
// src/vite/utils/route.ts
|
|
89
|
+
var httpVerbOrder = httpVerbs.reduce(
|
|
90
|
+
(order, verb, index) => {
|
|
91
|
+
order[verb] = index;
|
|
92
|
+
return order;
|
|
93
|
+
},
|
|
94
|
+
{}
|
|
95
|
+
);
|
|
96
|
+
function getVerbs(route, noAutoHead) {
|
|
97
|
+
var _a;
|
|
98
|
+
const verbs = new Set((_a = route.handler) == null ? void 0 : _a.verbs);
|
|
99
|
+
if (route.page) {
|
|
100
|
+
verbs.add("get");
|
|
127
101
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
id: "/",
|
|
131
|
-
path: "/",
|
|
132
|
-
segments: []
|
|
133
|
-
};
|
|
134
|
-
let sep = "";
|
|
135
|
-
for (const { segment } of this) {
|
|
136
|
-
const { type, name, param } = segment;
|
|
137
|
-
if (name && type !== "_") {
|
|
138
|
-
value.id += sep + (type || name);
|
|
139
|
-
value.path += sep + name;
|
|
140
|
-
value.isEnd = type === "$$";
|
|
141
|
-
if (param) {
|
|
142
|
-
value.path += param;
|
|
143
|
-
let index = type === "$$" ? null : value.segments.length;
|
|
144
|
-
if (!value.params) {
|
|
145
|
-
value.params = { [param]: index };
|
|
146
|
-
} else if (!(param in value.params)) {
|
|
147
|
-
value.params[param] = index;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
value.segments.push(name);
|
|
151
|
-
sep = "/";
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
Object.defineProperty(this, "pathInfo", {
|
|
155
|
-
value,
|
|
156
|
-
enumerable: true
|
|
157
|
-
});
|
|
158
|
-
return value;
|
|
102
|
+
if (!noAutoHead && verbs.has("get")) {
|
|
103
|
+
verbs.add("head");
|
|
159
104
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
105
|
+
return [...verbs].sort((a, b) => httpVerbOrder[a] - httpVerbOrder[b]);
|
|
106
|
+
}
|
|
107
|
+
function hasVerb(route, verb) {
|
|
108
|
+
var _a, _b;
|
|
109
|
+
return verb === "get" && !!route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes(verb)) || verb === "head" && hasVerb(route, "get");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/vite/codegen/writer.ts
|
|
113
|
+
function createWriter(sink, options) {
|
|
114
|
+
let buffer = "";
|
|
115
|
+
let indentLevel = 0;
|
|
116
|
+
let indentString = "";
|
|
117
|
+
let firstOpenIndex = 0;
|
|
118
|
+
const branches = [];
|
|
119
|
+
const openWriters = /* @__PURE__ */ new Map();
|
|
120
|
+
function write(data) {
|
|
121
|
+
if (!writer.__isActive) {
|
|
122
|
+
throw new Error("Cannot write to branch that has been joined");
|
|
166
123
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
addFile(file) {
|
|
170
|
-
if (!this.files) {
|
|
171
|
-
this.files = /* @__PURE__ */ new Map();
|
|
172
|
-
this.files.set(file.type, file);
|
|
173
|
-
} else if (!this.files.has(file.type)) {
|
|
174
|
-
this.files.set(file.type, file);
|
|
124
|
+
if (openWriters.size) {
|
|
125
|
+
buffer += data;
|
|
175
126
|
} else {
|
|
176
|
-
|
|
177
|
-
if (existing !== file) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`Duplicate file type '${file.type}' added at path '${this.path}'. File '${file.importPath}' collides with '${existing.importPath}'.`
|
|
180
|
-
);
|
|
181
|
-
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
182
|
-
throw new Error(
|
|
183
|
-
`Ambiguous path definition: route '${this.path}' is defined multiple times by ${file.importPath}`
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Ambiguous path definition: file '${this.path}' is included multiple times by ${file.importPath}`
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
*dirs() {
|
|
192
|
-
if (__privateGet(this, _pathlessDirs)) {
|
|
193
|
-
yield* __privateGet(this, _pathlessDirs).values();
|
|
194
|
-
}
|
|
195
|
-
if (__privateGet(this, _dirs)) {
|
|
196
|
-
yield* __privateGet(this, _dirs).values();
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
*[Symbol.iterator]() {
|
|
200
|
-
if (this.parent) {
|
|
201
|
-
yield* this.parent;
|
|
127
|
+
sink(data);
|
|
202
128
|
}
|
|
203
|
-
|
|
129
|
+
return writer;
|
|
204
130
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
131
|
+
const writer = {
|
|
132
|
+
__isActive: true,
|
|
133
|
+
get indent() {
|
|
134
|
+
return indentLevel;
|
|
135
|
+
},
|
|
136
|
+
set indent(value) {
|
|
137
|
+
if (options == null ? void 0 : options.indentWith) {
|
|
138
|
+
if (value < 0) {
|
|
139
|
+
value = 0;
|
|
213
140
|
}
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
for (const { source } of dir) {
|
|
218
|
-
if (source && !sources.has(source.source)) {
|
|
219
|
-
sources.add(source.source);
|
|
220
|
-
sourcePath += source.source + "/";
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
throw new Error(
|
|
224
|
-
`Ambiguous directory structure: '${sourcePath}${path6.source}' defines '${dir.path}' multiple times.`
|
|
225
|
-
);
|
|
226
|
-
} else {
|
|
227
|
-
unique.add(dir.path);
|
|
228
|
-
dirs.push(dir);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return dirs;
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
_dirs = new WeakMap();
|
|
236
|
-
_pathlessDirs = new WeakMap();
|
|
237
|
-
var VDir = _VDir;
|
|
238
|
-
|
|
239
|
-
// src/vite/routes/parse.ts
|
|
240
|
-
function parseFlatRoute(pattern) {
|
|
241
|
-
if (!pattern) throw new Error("Empty pattern");
|
|
242
|
-
const len = pattern.length;
|
|
243
|
-
let i = 0;
|
|
244
|
-
return parse2([
|
|
245
|
-
{
|
|
246
|
-
id: "/",
|
|
247
|
-
segments: [],
|
|
248
|
-
source: pattern
|
|
249
|
-
}
|
|
250
|
-
]);
|
|
251
|
-
function parse2(basePaths, group) {
|
|
252
|
-
const pathMap = /* @__PURE__ */ new Map();
|
|
253
|
-
const delimiters = group ? ").," : ".,";
|
|
254
|
-
let charCode;
|
|
255
|
-
let segmentStart = i;
|
|
256
|
-
let type;
|
|
257
|
-
let current;
|
|
258
|
-
do {
|
|
259
|
-
charCode = pattern.charCodeAt(i);
|
|
260
|
-
if (charCode === 41 && group) {
|
|
261
|
-
break;
|
|
262
|
-
} else if (charCode === 44) {
|
|
263
|
-
if (!current) {
|
|
264
|
-
segmentEnd(
|
|
265
|
-
basePaths.map((path6) => ({
|
|
266
|
-
...path6,
|
|
267
|
-
segments: path6.segments.slice()
|
|
268
|
-
})),
|
|
269
|
-
"",
|
|
270
|
-
"_",
|
|
271
|
-
pathMap
|
|
272
|
-
);
|
|
273
|
-
} else {
|
|
274
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type, pathMap);
|
|
275
|
-
}
|
|
276
|
-
current = void 0;
|
|
277
|
-
type = void 0;
|
|
278
|
-
segmentStart = ++i;
|
|
279
|
-
} else if (charCode === 46) {
|
|
280
|
-
if (current) {
|
|
281
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
282
|
-
}
|
|
283
|
-
type = void 0;
|
|
284
|
-
segmentStart = ++i;
|
|
285
|
-
} else if (charCode === 40) {
|
|
286
|
-
const groupPaths = parse2(current || basePaths, ++i);
|
|
287
|
-
if (groupPaths.length) {
|
|
288
|
-
current = groupPaths;
|
|
289
|
-
}
|
|
290
|
-
segmentStart = ++i;
|
|
291
|
-
} else {
|
|
292
|
-
if (charCode === 95) {
|
|
293
|
-
type = "_";
|
|
294
|
-
} else if (charCode === 36) {
|
|
295
|
-
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
296
|
-
}
|
|
297
|
-
current ?? (current = basePaths.map((path6) => ({
|
|
298
|
-
...path6,
|
|
299
|
-
segments: path6.segments.slice()
|
|
300
|
-
})));
|
|
301
|
-
i = len;
|
|
302
|
-
for (const char of delimiters) {
|
|
303
|
-
const index = pattern.indexOf(char, segmentStart);
|
|
304
|
-
if (index >= 0 && index < i) {
|
|
305
|
-
i = index;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
} while (i < len);
|
|
310
|
-
if (group && charCode !== 41) {
|
|
311
|
-
throw new Error(
|
|
312
|
-
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
313
|
-
group
|
|
314
|
-
)}' in '${pattern}'`
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
if (!current) {
|
|
318
|
-
segmentEnd(
|
|
319
|
-
basePaths.map((path6) => ({
|
|
320
|
-
...path6,
|
|
321
|
-
segments: path6.segments.slice()
|
|
322
|
-
})),
|
|
323
|
-
"",
|
|
324
|
-
"_",
|
|
325
|
-
pathMap
|
|
326
|
-
);
|
|
327
|
-
} else {
|
|
328
|
-
segmentEnd(current, pattern.slice(segmentStart, i), type, pathMap);
|
|
329
|
-
}
|
|
330
|
-
return [...pathMap.values()];
|
|
331
|
-
}
|
|
332
|
-
function segmentEnd(paths, raw, type, map) {
|
|
333
|
-
let segment;
|
|
334
|
-
if (raw) {
|
|
335
|
-
segment = {
|
|
336
|
-
raw,
|
|
337
|
-
name: raw,
|
|
338
|
-
type
|
|
339
|
-
};
|
|
340
|
-
if (type === "$" || type === "$$") {
|
|
341
|
-
segment.name = type;
|
|
342
|
-
segment.param = raw.slice(type.length);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
for (const path6 of paths) {
|
|
346
|
-
if (segment) {
|
|
347
|
-
if (path6.isCatchall) {
|
|
348
|
-
throw new Error(
|
|
349
|
-
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
350
|
-
0,
|
|
351
|
-
i
|
|
352
|
-
)}' in '${pattern}'.`
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
path6.segments.push(segment);
|
|
356
|
-
path6.id += path6.id === "/" ? segment.name : `/${segment.name}`;
|
|
357
|
-
if (type === "$$") {
|
|
358
|
-
path6.isCatchall = true;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (map) {
|
|
362
|
-
if (map.has(path6.id)) {
|
|
363
|
-
const existing = map.get(path6.id);
|
|
364
|
-
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
365
|
-
const currentExpansion = path6.segments.map((s) => s.raw).join(".");
|
|
366
|
-
throw new Error(
|
|
367
|
-
`Invalid route pattern: route '${path6.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
map.set(path6.id, path6);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// src/vite/routes/builder.ts
|
|
377
|
-
var markoFiles = `(${RoutableFileTypes.Layout}|${RoutableFileTypes.Page}|${RoutableFileTypes.NotFound}|${RoutableFileTypes.Error})\\.(?:.*\\.)?(marko)`;
|
|
378
|
-
var nonMarkoFiles = `(${RoutableFileTypes.Middleware}|${RoutableFileTypes.Handler}|${RoutableFileTypes.Meta})\\.(?:.*\\.)?(.+)`;
|
|
379
|
-
var routeableFileRegex = new RegExp(
|
|
380
|
-
`[+](?:${markoFiles}|${nonMarkoFiles})$`,
|
|
381
|
-
"i"
|
|
382
|
-
);
|
|
383
|
-
function matchRoutableFile(filename) {
|
|
384
|
-
const match = filename.match(routeableFileRegex);
|
|
385
|
-
return match && (match[1] || match[3]).toLowerCase();
|
|
386
|
-
}
|
|
387
|
-
function isSpecialType(type) {
|
|
388
|
-
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
389
|
-
}
|
|
390
|
-
async function buildRoutes(sources) {
|
|
391
|
-
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
392
|
-
const routes = [];
|
|
393
|
-
const special = {};
|
|
394
|
-
const middlewares = /* @__PURE__ */ new Set();
|
|
395
|
-
const unusedFiles = /* @__PURE__ */ new Set();
|
|
396
|
-
const currentLayouts = /* @__PURE__ */ new Set();
|
|
397
|
-
const currentMiddleware = /* @__PURE__ */ new Set();
|
|
398
|
-
const root = new VDir();
|
|
399
|
-
const dirStack = [];
|
|
400
|
-
let basePath;
|
|
401
|
-
let importPrefix;
|
|
402
|
-
let activeDirs;
|
|
403
|
-
let isBaseDir;
|
|
404
|
-
let nextFileId = 1;
|
|
405
|
-
let nextRouteIndex = 1;
|
|
406
|
-
const walkOptions = {
|
|
407
|
-
onEnter({ name }) {
|
|
408
|
-
const prevDirStackLength = dirStack.length;
|
|
409
|
-
if (isBaseDir) {
|
|
410
|
-
isBaseDir = false;
|
|
411
|
-
if (!basePath) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
name = basePath;
|
|
415
|
-
} else {
|
|
416
|
-
dirStack.push(name);
|
|
417
|
-
}
|
|
418
|
-
const previousDirs = activeDirs;
|
|
419
|
-
const paths = parseFlatRoute(name);
|
|
420
|
-
activeDirs = VDir.addPaths(previousDirs, paths);
|
|
421
|
-
return () => {
|
|
422
|
-
activeDirs = previousDirs;
|
|
423
|
-
dirStack.length = prevDirStackLength;
|
|
424
|
-
};
|
|
425
|
-
},
|
|
426
|
-
onFile({ name, path: path6 }) {
|
|
427
|
-
const match = name.match(routeableFileRegex);
|
|
428
|
-
if (!match) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
const type = (match[1] || match[3]).toLowerCase();
|
|
432
|
-
if (dirStack.length && isSpecialType(type)) {
|
|
433
|
-
console.warn(
|
|
434
|
-
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${path6}`
|
|
435
|
-
);
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
let dirs = activeDirs;
|
|
439
|
-
if (match.index) {
|
|
440
|
-
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
441
|
-
dirs = VDir.addPaths(activeDirs, paths);
|
|
442
|
-
}
|
|
443
|
-
const dirPath = dirStack.join("/");
|
|
444
|
-
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
445
|
-
const file = {
|
|
446
|
-
id: String(nextFileId++),
|
|
447
|
-
name,
|
|
448
|
-
type,
|
|
449
|
-
filePath: path6,
|
|
450
|
-
relativePath,
|
|
451
|
-
importPath: `${importPrefix}/${relativePath}`,
|
|
452
|
-
verbs: type === RoutableFileTypes.Page ? ["get"] : void 0
|
|
453
|
-
};
|
|
454
|
-
for (const dir of dirs) {
|
|
455
|
-
dir.addFile(file);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
if (!Array.isArray(sources)) {
|
|
460
|
-
sources = [sources];
|
|
461
|
-
}
|
|
462
|
-
for (const source of sources) {
|
|
463
|
-
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
464
|
-
basePath = source.basePath || "";
|
|
465
|
-
activeDirs = [root];
|
|
466
|
-
isBaseDir = true;
|
|
467
|
-
await source.walker(walkOptions);
|
|
468
|
-
}
|
|
469
|
-
traverse(root);
|
|
470
|
-
return {
|
|
471
|
-
list: routes,
|
|
472
|
-
middleware: [...middlewares],
|
|
473
|
-
special
|
|
474
|
-
};
|
|
475
|
-
function traverse(dir) {
|
|
476
|
-
let middleware;
|
|
477
|
-
let layout;
|
|
478
|
-
if (dir.files) {
|
|
479
|
-
middleware = dir.files.get(RoutableFileTypes.Middleware);
|
|
480
|
-
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
481
|
-
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
482
|
-
const page = dir.files.get(RoutableFileTypes.Page);
|
|
483
|
-
let hasSpecial = false;
|
|
484
|
-
if (middleware) {
|
|
485
|
-
if (currentMiddleware.has(middleware)) {
|
|
486
|
-
middleware = void 0;
|
|
487
|
-
} else {
|
|
488
|
-
currentMiddleware.add(middleware);
|
|
489
|
-
unusedFiles.add(middleware);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
if (layout) {
|
|
493
|
-
if (currentLayouts.has(layout)) {
|
|
494
|
-
layout = void 0;
|
|
495
|
-
} else {
|
|
496
|
-
currentLayouts.add(layout);
|
|
497
|
-
unusedFiles.add(layout);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
if (page || handler) {
|
|
501
|
-
const path6 = dir.pathInfo;
|
|
502
|
-
if (uniqueRoutes.has(path6.id)) {
|
|
503
|
-
const existing = uniqueRoutes.get(path6.id);
|
|
504
|
-
const route = routes[existing.index];
|
|
505
|
-
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
506
|
-
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
507
|
-
throw new Error(`Duplicate routes for path '${path6.path}' were defined. A route established by:
|
|
508
|
-
${existingFiles.join(" and ")} via '${existing.dir.path}'
|
|
509
|
-
collides with
|
|
510
|
-
${currentFiles.join(" and ")} via '${dir.path}'
|
|
511
|
-
`);
|
|
512
|
-
}
|
|
513
|
-
uniqueRoutes.set(path6.id, { dir, index: routes.length });
|
|
514
|
-
routes.push({
|
|
515
|
-
index: nextRouteIndex++,
|
|
516
|
-
key: dir.fullPath,
|
|
517
|
-
paths: [path6],
|
|
518
|
-
middleware: [...currentMiddleware],
|
|
519
|
-
layouts: page ? [...currentLayouts] : [],
|
|
520
|
-
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
521
|
-
page,
|
|
522
|
-
handler,
|
|
523
|
-
entryName: `${markoRunFilePrefix}route` + (dir.path !== "/" ? dir.fullPath.replace(/\//g, ".").replace(/(%[A-Fa-f0-9]{2})+/g, "_") : "")
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
if (dir === root) {
|
|
527
|
-
for (const [type, file] of dir.files) {
|
|
528
|
-
if (isSpecialType(type)) {
|
|
529
|
-
hasSpecial = true;
|
|
530
|
-
special[type] = {
|
|
531
|
-
index: 0,
|
|
532
|
-
key: type,
|
|
533
|
-
paths: [],
|
|
534
|
-
middleware: [],
|
|
535
|
-
layouts: [...currentLayouts],
|
|
536
|
-
page: file,
|
|
537
|
-
entryName: `${markoRunFilePrefix}special.${type}`
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
if (handler || page) {
|
|
543
|
-
for (const middleware2 of currentMiddleware) {
|
|
544
|
-
middlewares.add(middleware2);
|
|
545
|
-
unusedFiles.delete(middleware2);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
if (page || hasSpecial) {
|
|
549
|
-
for (const layout2 of currentLayouts) {
|
|
550
|
-
unusedFiles.delete(layout2);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
if (dir.dirs) {
|
|
555
|
-
for (const child of dir.dirs()) {
|
|
556
|
-
traverse(child);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (middleware) {
|
|
560
|
-
currentMiddleware.delete(middleware);
|
|
561
|
-
}
|
|
562
|
-
if (layout) {
|
|
563
|
-
currentLayouts.delete(layout);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// src/vite/routes/walk.ts
|
|
569
|
-
import fs2 from "fs";
|
|
570
|
-
import path from "path";
|
|
571
|
-
function createFSWalker(dir) {
|
|
572
|
-
return async function walkFS({
|
|
573
|
-
onEnter,
|
|
574
|
-
onFile,
|
|
575
|
-
onDir,
|
|
576
|
-
maxDepth = 50
|
|
577
|
-
}) {
|
|
578
|
-
async function walk(dir2, depth) {
|
|
579
|
-
const onExit = onEnter == null ? void 0 : onEnter(dir2);
|
|
580
|
-
if (onExit !== false) {
|
|
581
|
-
const dirs = [];
|
|
582
|
-
const entries = await fs2.promises.readdir(dir2.path, {
|
|
583
|
-
withFileTypes: true
|
|
584
|
-
});
|
|
585
|
-
const prefix = dir2.path + path.sep;
|
|
586
|
-
for (const entry of entries) {
|
|
587
|
-
const walkEntry = {
|
|
588
|
-
name: entry.name,
|
|
589
|
-
path: prefix + entry.name
|
|
590
|
-
};
|
|
591
|
-
if (entry.isDirectory()) {
|
|
592
|
-
dirs.push(walkEntry);
|
|
593
|
-
} else {
|
|
594
|
-
onFile == null ? void 0 : onFile(walkEntry);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
if ((onDir == null ? void 0 : onDir()) !== false && --depth > 0) {
|
|
598
|
-
for (const entry of dirs) {
|
|
599
|
-
await walk(entry, depth);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
onExit == null ? void 0 : onExit();
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
await walk(
|
|
606
|
-
{
|
|
607
|
-
path: dir,
|
|
608
|
-
name: path.basename(dir)
|
|
609
|
-
},
|
|
610
|
-
maxDepth
|
|
611
|
-
);
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
// src/vite/codegen/writer.ts
|
|
616
|
-
function createWriter(sink, options) {
|
|
617
|
-
let buffer = "";
|
|
618
|
-
let indentLevel = 0;
|
|
619
|
-
let indentString = "";
|
|
620
|
-
let firstOpenIndex = 0;
|
|
621
|
-
const branches = [];
|
|
622
|
-
const openWriters = /* @__PURE__ */ new Map();
|
|
623
|
-
function write(data) {
|
|
624
|
-
if (!writer.__isActive) {
|
|
625
|
-
throw new Error("Cannot write to branch that has been joined");
|
|
626
|
-
}
|
|
627
|
-
if (openWriters.size) {
|
|
628
|
-
buffer += data;
|
|
629
|
-
} else {
|
|
630
|
-
sink(data);
|
|
631
|
-
}
|
|
632
|
-
return writer;
|
|
633
|
-
}
|
|
634
|
-
const writer = {
|
|
635
|
-
__isActive: true,
|
|
636
|
-
get indent() {
|
|
637
|
-
return indentLevel;
|
|
638
|
-
},
|
|
639
|
-
set indent(value) {
|
|
640
|
-
if (options == null ? void 0 : options.indentWith) {
|
|
641
|
-
if (value < 0) {
|
|
642
|
-
value = 0;
|
|
643
|
-
}
|
|
644
|
-
if (value !== indentLevel) {
|
|
645
|
-
indentLevel = value;
|
|
646
|
-
indentString = options.indentWith.repeat(indentLevel);
|
|
141
|
+
if (value !== indentLevel) {
|
|
142
|
+
indentLevel = value;
|
|
143
|
+
indentString = options.indentWith.repeat(indentLevel);
|
|
647
144
|
}
|
|
648
145
|
}
|
|
649
146
|
},
|
|
@@ -675,7 +172,7 @@ function createWriter(sink, options) {
|
|
|
675
172
|
return writer.writeBlockStart(start).writeLines(...lines).writeBlockEnd(end);
|
|
676
173
|
},
|
|
677
174
|
branch(name) {
|
|
678
|
-
|
|
175
|
+
const existing = openWriters.get(name);
|
|
679
176
|
if (existing) {
|
|
680
177
|
return existing;
|
|
681
178
|
}
|
|
@@ -738,9 +235,12 @@ function createWriter(sink, options) {
|
|
|
738
235
|
}
|
|
739
236
|
function createStringWriter(opts) {
|
|
740
237
|
let code = "";
|
|
741
|
-
const writer = createWriter(
|
|
742
|
-
|
|
743
|
-
|
|
238
|
+
const writer = createWriter(
|
|
239
|
+
(data) => {
|
|
240
|
+
code += data;
|
|
241
|
+
},
|
|
242
|
+
{ indentWith: " ", ...opts }
|
|
243
|
+
);
|
|
744
244
|
return Object.assign(writer, {
|
|
745
245
|
end() {
|
|
746
246
|
writer.join(true);
|
|
@@ -749,22 +249,7 @@ function createStringWriter(opts) {
|
|
|
749
249
|
});
|
|
750
250
|
}
|
|
751
251
|
|
|
752
|
-
// src/vite/utils/route.ts
|
|
753
|
-
function getVerbs(route) {
|
|
754
|
-
var _a, _b;
|
|
755
|
-
const verbs = ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.slice()) || [];
|
|
756
|
-
if (route.page && !verbs.includes("get")) {
|
|
757
|
-
verbs.unshift("get");
|
|
758
|
-
}
|
|
759
|
-
return verbs;
|
|
760
|
-
}
|
|
761
|
-
function hasVerb(route, verb) {
|
|
762
|
-
var _a, _b;
|
|
763
|
-
return verb === "get" && route.page || ((_b = (_a = route.handler) == null ? void 0 : _a.verbs) == null ? void 0 : _b.includes(verb));
|
|
764
|
-
}
|
|
765
|
-
|
|
766
252
|
// src/vite/codegen/index.ts
|
|
767
|
-
import path2 from "path";
|
|
768
253
|
function renderRouteTemplate(route, getRelativePath) {
|
|
769
254
|
if (!route.page) {
|
|
770
255
|
throw new Error(`Route ${route.key} has no page to render`);
|
|
@@ -825,12 +310,15 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
825
310
|
if (handler || middleware.length) {
|
|
826
311
|
runtimeImports.push("call");
|
|
827
312
|
}
|
|
828
|
-
if (!page || verbs.
|
|
313
|
+
if (!page || verbs.some((verb) => verb !== "get" && verb !== "head")) {
|
|
829
314
|
runtimeImports.push("noContent");
|
|
830
315
|
}
|
|
831
316
|
if (page) {
|
|
832
317
|
runtimeImports.push("pageResponse");
|
|
833
318
|
}
|
|
319
|
+
if (verbs.includes("head")) {
|
|
320
|
+
runtimeImports.push("stripResponseBody");
|
|
321
|
+
}
|
|
834
322
|
if (runtimeImports.length) {
|
|
835
323
|
imports.writeLines(
|
|
836
324
|
`import { ${runtimeImports.join(
|
|
@@ -859,628 +347,1173 @@ function renderRouteEntry(route, entriesDir) {
|
|
|
859
347
|
);
|
|
860
348
|
}
|
|
861
349
|
if (page) {
|
|
862
|
-
const
|
|
350
|
+
const pageNameIndex = page.name.indexOf("+page");
|
|
351
|
+
const pageNamePrefix = pageNameIndex > 0 ? `${page.name.slice(0, pageNameIndex)}.` : "";
|
|
352
|
+
const importPath = route.layouts.length ? `./${path.posix.join(entriesDir, page.relativePath, "..", pageNamePrefix + "route.marko")}` : `./${page.importPath}`;
|
|
863
353
|
imports.writeLines(`import page from '${importPath}${serverEntryQuery}';`);
|
|
864
354
|
}
|
|
865
|
-
if (meta) {
|
|
355
|
+
if (meta) {
|
|
356
|
+
imports.writeLines(
|
|
357
|
+
`export { default as meta${index} } from './${meta.importPath}';`
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
for (const verb of verbs) {
|
|
361
|
+
writeRouteEntryHandler(writer, route, verb);
|
|
362
|
+
}
|
|
363
|
+
return writer.end();
|
|
364
|
+
}
|
|
365
|
+
function writeRouteEntryHandler(writer, route, verb) {
|
|
366
|
+
var _a, _b, _c, _d;
|
|
367
|
+
const { key, index, page, handler, middleware } = route;
|
|
368
|
+
const len = middleware.length;
|
|
369
|
+
let nextName;
|
|
370
|
+
let currentName;
|
|
371
|
+
let hasBody = false;
|
|
372
|
+
writer.writeLines("");
|
|
373
|
+
if (page && (verb === "get" || verb === "head")) {
|
|
374
|
+
writer.writeBlockStart(
|
|
375
|
+
`export function ${verb}${index}(context, buildInput) {`
|
|
376
|
+
);
|
|
377
|
+
} else {
|
|
378
|
+
writer.writeBlockStart(`export function ${verb}${index}(context) {`);
|
|
379
|
+
}
|
|
380
|
+
const continuations = writer.branch("cont");
|
|
381
|
+
if (page && (verb === "get" || verb === "head")) {
|
|
382
|
+
currentName = "__page";
|
|
383
|
+
if ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes(verb)) {
|
|
384
|
+
const name = `${verb}Handler`;
|
|
385
|
+
continuations.writeLines(
|
|
386
|
+
`const ${currentName} = () => pageResponse(page, buildInput());`
|
|
387
|
+
);
|
|
388
|
+
if (len) {
|
|
389
|
+
nextName = currentName;
|
|
390
|
+
currentName = `__${name}`;
|
|
391
|
+
continuations.writeLines(
|
|
392
|
+
`const ${currentName} = () => call(${name}, ${nextName}, context);`
|
|
393
|
+
);
|
|
394
|
+
} else {
|
|
395
|
+
if (verb === "head") {
|
|
396
|
+
writer.writeLines(
|
|
397
|
+
`return stripResponseBody(call(${name}, ${currentName}, context));`
|
|
398
|
+
);
|
|
399
|
+
} else {
|
|
400
|
+
writer.writeLines(`return call(${name}, ${currentName}, context);`);
|
|
401
|
+
}
|
|
402
|
+
hasBody = true;
|
|
403
|
+
}
|
|
404
|
+
} else if (verb === "head") {
|
|
405
|
+
writer.writeLines(
|
|
406
|
+
`return stripResponseBody(get${index}(context, buildInput));`
|
|
407
|
+
);
|
|
408
|
+
hasBody = true;
|
|
409
|
+
} else if (len) {
|
|
410
|
+
continuations.writeLines(
|
|
411
|
+
`const ${currentName} = () => pageResponse(page, buildInput());`
|
|
412
|
+
);
|
|
413
|
+
nextName = currentName;
|
|
414
|
+
} else {
|
|
415
|
+
writer.writeLines(`return pageResponse(page, buildInput());`);
|
|
416
|
+
hasBody = true;
|
|
417
|
+
}
|
|
418
|
+
} else if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes(verb)) {
|
|
419
|
+
const name = `${verb}Handler`;
|
|
420
|
+
currentName = `__${name}`;
|
|
421
|
+
nextName = "noContent";
|
|
422
|
+
if (len) {
|
|
423
|
+
continuations.writeLines(
|
|
424
|
+
`const ${currentName} = () => call(${name}, ${nextName}, context);`
|
|
425
|
+
);
|
|
426
|
+
} else {
|
|
427
|
+
if (verb === "head") {
|
|
428
|
+
writer.writeLines(
|
|
429
|
+
`return stripResponseBody(call(${name}, ${nextName}, context));`
|
|
430
|
+
);
|
|
431
|
+
} else {
|
|
432
|
+
writer.writeLines(`return call(${name}, ${nextName}, context);`);
|
|
433
|
+
}
|
|
434
|
+
hasBody = true;
|
|
435
|
+
}
|
|
436
|
+
} else if (verb === "head" && ((_d = (_c = route.handler) == null ? void 0 : _c.verbs) == null ? void 0 : _d.includes("get"))) {
|
|
437
|
+
writer.writeLines(`return stripResponseBody(get${index}(context));`);
|
|
438
|
+
hasBody = true;
|
|
439
|
+
} else {
|
|
440
|
+
throw new Error(`Route ${key} has no handler for ${verb} requests`);
|
|
441
|
+
}
|
|
442
|
+
if (!hasBody) {
|
|
443
|
+
let i = len;
|
|
444
|
+
while (i--) {
|
|
445
|
+
const { id } = middleware[i];
|
|
446
|
+
const name = `mware${id}`;
|
|
447
|
+
nextName = currentName;
|
|
448
|
+
currentName = i ? `__${name}` : "";
|
|
449
|
+
if (currentName) {
|
|
450
|
+
continuations.writeLines(
|
|
451
|
+
`const ${currentName} = () => call(${name}, ${nextName}, context);`
|
|
452
|
+
);
|
|
453
|
+
} else if (verb === "head") {
|
|
454
|
+
continuations.writeLines(
|
|
455
|
+
`return stripResponseBody(call(${name}, ${nextName}, context));`
|
|
456
|
+
);
|
|
457
|
+
} else {
|
|
458
|
+
continuations.writeLines(`return call(${name}, ${nextName}, context);`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
continuations.join();
|
|
463
|
+
writer.writeBlockEnd("}");
|
|
464
|
+
}
|
|
465
|
+
function renderRouter(routes, entriesDir, options = {
|
|
466
|
+
trailingSlashes: "RedirectWithout"
|
|
467
|
+
}) {
|
|
468
|
+
const writer = createStringWriter();
|
|
469
|
+
writer.writeLines(`// @marko/run/router`);
|
|
470
|
+
const imports = writer.branch("imports");
|
|
471
|
+
imports.writeLines(
|
|
472
|
+
`import { NotHandled, NotMatched, createContext } from '${virtualFilePrefix}/runtime/internal';`
|
|
473
|
+
);
|
|
474
|
+
for (const route of routes.list) {
|
|
475
|
+
const verbs = getVerbs(route);
|
|
476
|
+
const names = verbs.map((verb) => `${verb}${route.index}`);
|
|
477
|
+
route.meta && names.push(`meta${route.index}`);
|
|
478
|
+
imports.writeLines(
|
|
479
|
+
`import { ${names.join(", ")} } from '${virtualFilePrefix}/${route.entryName}.js';`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
for (const route of Object.values(routes.special)) {
|
|
483
|
+
const importPath = route.layouts.length ? `./${path.posix.join(entriesDir, route.page.relativePath, "..", `route.${route.key}.marko`)}` : `./${route.page.importPath}`;
|
|
484
|
+
imports.writeLines(
|
|
485
|
+
`import page${route.key} from '${importPath}${serverEntryQuery}';`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
writer.writeLines(
|
|
489
|
+
`
|
|
490
|
+
globalThis.__marko_run__ = { match, fetch, invoke };
|
|
491
|
+
`
|
|
492
|
+
).writeBlockStart(`export function match(method, pathname) {`).writeLines(
|
|
493
|
+
`if (!pathname) {
|
|
494
|
+
pathname = '/';
|
|
495
|
+
} else if (pathname.charAt(0) !== '/') {
|
|
496
|
+
pathname = '/' + pathname;
|
|
497
|
+
}`
|
|
498
|
+
).writeBlockStart(`switch (method) {`);
|
|
499
|
+
for (const verb of httpVerbs) {
|
|
500
|
+
const filteredRoutes = routes.list.filter((route) => hasVerb(route, verb));
|
|
501
|
+
if (filteredRoutes.length) {
|
|
502
|
+
const trie = createRouteTrie(filteredRoutes);
|
|
503
|
+
writer.writeLines(`case '${verb.toUpperCase()}':`);
|
|
504
|
+
writer.writeBlockStart(`case '${verb.toLowerCase()}': {`);
|
|
505
|
+
writeRouterVerb(writer, trie, verb);
|
|
506
|
+
writer.writeBlockEnd("}");
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
writer.writeBlockEnd("}").writeLines("return null;").writeBlockEnd("}");
|
|
510
|
+
writer.writeLines("").writeBlockStart(
|
|
511
|
+
"export async function invoke(route, request, platform, url) {"
|
|
512
|
+
).writeLines(
|
|
513
|
+
"const [context, buildInput] = createContext(route, request, platform, url);"
|
|
514
|
+
);
|
|
515
|
+
const hasErrorPage = Boolean(routes.special[RoutableFileTypes.Error]);
|
|
516
|
+
if (hasErrorPage) {
|
|
517
|
+
writer.writeBlockStart("try {");
|
|
518
|
+
}
|
|
519
|
+
writer.writeBlockStart("if (route) {").writeBlockStart("try {").writeLines(
|
|
520
|
+
"const response = await route.handler(context, buildInput);",
|
|
521
|
+
"if (response) return response;"
|
|
522
|
+
).indent--;
|
|
523
|
+
writer.writeBlockStart("} catch (error) {").writeLines(
|
|
524
|
+
"if (error === NotHandled) return;",
|
|
525
|
+
"if (error !== NotMatched) throw error;"
|
|
526
|
+
).writeBlockEnd("}").writeBlockEnd("}");
|
|
527
|
+
if (routes.special[RoutableFileTypes.NotFound]) {
|
|
866
528
|
imports.writeLines(
|
|
867
|
-
`
|
|
529
|
+
`
|
|
530
|
+
const page404ResponseInit = {
|
|
531
|
+
status: 404,
|
|
532
|
+
headers: { "content-type": "text/html;charset=UTF-8" },
|
|
533
|
+
};`
|
|
868
534
|
);
|
|
535
|
+
writer.write(`
|
|
536
|
+
if (context.request.headers.get('Accept')?.includes('text/html')) {
|
|
537
|
+
return new Response(page404.stream(buildInput()), page404ResponseInit);
|
|
538
|
+
}
|
|
539
|
+
`);
|
|
869
540
|
}
|
|
870
|
-
|
|
871
|
-
|
|
541
|
+
writer.indent--;
|
|
542
|
+
if (hasErrorPage) {
|
|
543
|
+
imports.writeLines(`
|
|
544
|
+
const page500ResponseInit = {
|
|
545
|
+
status: 500,
|
|
546
|
+
headers: { "content-type": "text/html;charset=UTF-8" },
|
|
547
|
+
};`);
|
|
548
|
+
writer.writeBlockStart(`} catch (error) {`).writeBlockStart(
|
|
549
|
+
`if (context.request.headers.get('Accept')?.includes('text/html')) {`
|
|
550
|
+
).writeLines(
|
|
551
|
+
`return new Response(page500.stream(buildInput({ error })), page500ResponseInit);`
|
|
552
|
+
).writeBlockEnd("}").writeLines("throw error;").writeBlockEnd("}");
|
|
872
553
|
}
|
|
554
|
+
writer.writeBlockEnd("}");
|
|
555
|
+
renderFetch(writer, options);
|
|
873
556
|
return writer.end();
|
|
874
557
|
}
|
|
875
|
-
function
|
|
876
|
-
writer.
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
`
|
|
884
|
-
)
|
|
885
|
-
|
|
886
|
-
|
|
558
|
+
function renderFetch(writer, options) {
|
|
559
|
+
writer.write(`
|
|
560
|
+
export async function fetch(request, platform) {
|
|
561
|
+
try {
|
|
562
|
+
const url = new URL(request.url);
|
|
563
|
+
let { pathname } = url;`);
|
|
564
|
+
switch (options.trailingSlashes) {
|
|
565
|
+
case "RedirectWithout":
|
|
566
|
+
writer.write(`
|
|
567
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
568
|
+
url.pathname = pathname.slice(0, -1);
|
|
569
|
+
return Response.redirect(url);
|
|
570
|
+
}`);
|
|
571
|
+
break;
|
|
572
|
+
case "RedirectWith":
|
|
573
|
+
writer.write(`
|
|
574
|
+
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
575
|
+
url.pathname = pathname + '/';
|
|
576
|
+
return Response.redirect(url);
|
|
577
|
+
}`);
|
|
578
|
+
break;
|
|
579
|
+
case "RewriteWithout":
|
|
580
|
+
writer.write(`
|
|
581
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
582
|
+
url.pathname = pathname = pathname.slice(0, -1);
|
|
583
|
+
}`);
|
|
584
|
+
break;
|
|
585
|
+
case "RewriteWith":
|
|
586
|
+
writer.write(`
|
|
587
|
+
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
588
|
+
url.pathname = pathname = pathname + '/';
|
|
589
|
+
}`);
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
writer.write(`
|
|
593
|
+
|
|
594
|
+
const route = match(request.method, pathname);
|
|
595
|
+
return await invoke(route, request, platform, url);
|
|
596
|
+
} catch (error) {
|
|
597
|
+
if (import.meta.env.DEV) {
|
|
598
|
+
throw error;
|
|
599
|
+
}
|
|
600
|
+
return new Response(null, {
|
|
601
|
+
status: 500
|
|
602
|
+
});
|
|
887
603
|
}
|
|
604
|
+
}`);
|
|
888
605
|
}
|
|
889
|
-
function
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
`
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
writer.writeBlockStart(`export async function ${verb}${index}(context) {`);
|
|
606
|
+
function writeRouterVerb(writer, trie, verb, level = 0, offset = 1) {
|
|
607
|
+
const { route, dynamic, catchAll } = trie;
|
|
608
|
+
let closeCount = 0;
|
|
609
|
+
if (level === 0) {
|
|
610
|
+
writer.writeLines(`const len = pathname.length;`);
|
|
611
|
+
if (route) {
|
|
612
|
+
writer.writeLines(
|
|
613
|
+
`if (len === 1) return ${renderMatch(verb, route, trie.path)}; // ${trie.path.path}`
|
|
614
|
+
);
|
|
615
|
+
} else if (trie.static || dynamic) {
|
|
616
|
+
writer.writeBlockStart(`if (len > 1) {`);
|
|
617
|
+
closeCount++;
|
|
618
|
+
}
|
|
903
619
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
620
|
+
if (trie.static || dynamic) {
|
|
621
|
+
const next = level + 1;
|
|
622
|
+
const index = `i${next}`;
|
|
623
|
+
let terminal;
|
|
624
|
+
let children;
|
|
625
|
+
writer.writeLines(`const ${index} = pathname.indexOf('/', ${offset}) + 1;`);
|
|
626
|
+
if (trie.static) {
|
|
627
|
+
for (const child of trie.static.values()) {
|
|
628
|
+
if (child.route) {
|
|
629
|
+
(terminal ?? (terminal = [])).push(child);
|
|
630
|
+
}
|
|
631
|
+
if (child.static || child.dynamic || child.catchAll) {
|
|
632
|
+
(children ?? (children = [])).push(child);
|
|
633
|
+
}
|
|
917
634
|
}
|
|
918
|
-
} else if (len) {
|
|
919
|
-
writePageResponse(continuations, currentName);
|
|
920
|
-
nextName = currentName;
|
|
921
|
-
} else {
|
|
922
|
-
writePageResponse(continuations);
|
|
923
|
-
hasBody = true;
|
|
924
635
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
636
|
+
if (terminal || (dynamic == null ? void 0 : dynamic.route)) {
|
|
637
|
+
closeCount++;
|
|
638
|
+
writer.writeBlockStart(`if (!${index} || ${index} === len) {`);
|
|
639
|
+
let value = `pathname.slice(${offset}, ${index} ? -1 : len)`;
|
|
640
|
+
if (dynamic == null ? void 0 : dynamic.route) {
|
|
641
|
+
const segment = `s${next}`;
|
|
642
|
+
writer.writeLines(`const ${segment} = decodeURIComponent(${value});`);
|
|
643
|
+
value = segment;
|
|
644
|
+
} else if (terminal == null ? void 0 : terminal.some(
|
|
645
|
+
(terminal2) => decodeURIComponent(terminal2.key) !== terminal2.key
|
|
646
|
+
)) {
|
|
647
|
+
value = `decodeURIComponent(${value})`;
|
|
648
|
+
}
|
|
649
|
+
if (terminal) {
|
|
650
|
+
const useSwitch = terminal.length > 1;
|
|
651
|
+
if (useSwitch) {
|
|
652
|
+
writer.writeBlockStart(`switch (${value}) {`);
|
|
653
|
+
}
|
|
654
|
+
for (const { key, path: path6, route: route2 } of terminal) {
|
|
655
|
+
const decodedKey = decodeURIComponent(key);
|
|
656
|
+
if (useSwitch) {
|
|
657
|
+
writer.write(`case '${decodedKey}': `, true);
|
|
658
|
+
} else {
|
|
659
|
+
writer.write(`if (${value} === '${decodedKey}') `, true);
|
|
660
|
+
}
|
|
661
|
+
writer.write(
|
|
662
|
+
`return ${renderMatch(verb, route2, path6)}; // ${path6.path}
|
|
663
|
+
`
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
if (useSwitch) {
|
|
667
|
+
writer.writeBlockEnd("}");
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
if (dynamic == null ? void 0 : dynamic.route) {
|
|
671
|
+
writer.writeLines(
|
|
672
|
+
`if (${value}) return ${renderMatch(
|
|
673
|
+
verb,
|
|
674
|
+
dynamic.route,
|
|
675
|
+
dynamic.path
|
|
676
|
+
)}; // ${dynamic.path.path}`
|
|
677
|
+
);
|
|
678
|
+
}
|
|
934
679
|
}
|
|
935
|
-
|
|
936
|
-
|
|
680
|
+
if (children || (dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
681
|
+
if (terminal || (dynamic == null ? void 0 : dynamic.route)) {
|
|
682
|
+
writer.writeBlockEnd("} else {").indent++;
|
|
683
|
+
} else {
|
|
684
|
+
writer.writeBlockStart(`if (${index} && ${index} !== len) {`);
|
|
685
|
+
closeCount++;
|
|
686
|
+
}
|
|
687
|
+
let value = `pathname.slice(${offset}, ${index} - 1)`;
|
|
688
|
+
if ((dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
689
|
+
const segment = `s${next}`;
|
|
690
|
+
writer.writeLines(`const ${segment} = decodeURIComponent(${value});`);
|
|
691
|
+
value = segment;
|
|
692
|
+
} else if (children == null ? void 0 : children.some((child) => decodeURIComponent(child.key) !== child.key)) {
|
|
693
|
+
value = `decodeURIComponent(${value})`;
|
|
694
|
+
}
|
|
695
|
+
if (children) {
|
|
696
|
+
const useSwitch = children.length > 1;
|
|
697
|
+
if (useSwitch) {
|
|
698
|
+
writer.writeBlockStart(`switch (${value}) {`);
|
|
699
|
+
}
|
|
700
|
+
for (const child of children) {
|
|
701
|
+
const decodedKey = decodeURIComponent(child.key);
|
|
702
|
+
if (useSwitch) {
|
|
703
|
+
writer.writeBlockStart(`case '${decodedKey}': {`);
|
|
704
|
+
} else {
|
|
705
|
+
writer.writeBlockStart(`if (${value} === '${decodedKey}') {`);
|
|
706
|
+
}
|
|
707
|
+
const nextOffset = typeof offset === "string" ? index : offset + child.key.length + 1;
|
|
708
|
+
writeRouterVerb(writer, child, verb, next, nextOffset);
|
|
709
|
+
if (useSwitch) {
|
|
710
|
+
writer.writeBlockEnd("} break;");
|
|
711
|
+
} else {
|
|
712
|
+
writer.writeBlockEnd("}");
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (useSwitch) {
|
|
716
|
+
writer.writeBlockEnd("}");
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
if ((dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
720
|
+
writer.writeBlockStart(`if (${value}) {`);
|
|
721
|
+
writeRouterVerb(writer, dynamic, verb, next, index);
|
|
722
|
+
writer.writeBlockEnd(`}`);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
while (closeCount--) {
|
|
727
|
+
writer.writeBlockEnd("}");
|
|
728
|
+
}
|
|
729
|
+
if (catchAll) {
|
|
730
|
+
writer.writeLines(
|
|
731
|
+
`return ${renderMatch(
|
|
732
|
+
verb,
|
|
733
|
+
catchAll.route,
|
|
734
|
+
catchAll.path,
|
|
735
|
+
String(offset)
|
|
736
|
+
)}; // ${catchAll.path.path}`
|
|
737
|
+
);
|
|
738
|
+
} else if (level === 0) {
|
|
739
|
+
writer.writeLines("return null;");
|
|
937
740
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
741
|
+
}
|
|
742
|
+
function wrapPropertyName(name) {
|
|
743
|
+
name = decodeURIComponent(name);
|
|
744
|
+
return /^[^A-Za-z_$]|[^A-Za-z0-9$_]/.test(name) ? `'${name}'` : name;
|
|
745
|
+
}
|
|
746
|
+
function renderParams(params, pathIndex) {
|
|
747
|
+
let result = "";
|
|
748
|
+
let catchAll = "";
|
|
749
|
+
let sep = "{";
|
|
750
|
+
for (const [name, index] of Object.entries(params)) {
|
|
751
|
+
if (typeof index === "number") {
|
|
752
|
+
result += `${sep} ${wrapPropertyName(name)}: s${index + 1}`;
|
|
753
|
+
sep = ",";
|
|
754
|
+
} else if (pathIndex) {
|
|
755
|
+
catchAll = name;
|
|
946
756
|
}
|
|
947
757
|
}
|
|
948
|
-
|
|
949
|
-
|
|
758
|
+
if (catchAll) {
|
|
759
|
+
result += `${sep} ${wrapPropertyName(
|
|
760
|
+
catchAll
|
|
761
|
+
)}: pathname.slice(${pathIndex})`;
|
|
762
|
+
}
|
|
763
|
+
return result ? result + " }" : "{}";
|
|
950
764
|
}
|
|
951
|
-
function
|
|
952
|
-
|
|
953
|
-
|
|
765
|
+
function renderMatch(verb, route, path6, pathIndex) {
|
|
766
|
+
const handler = `${verb}${route.index}`;
|
|
767
|
+
const params = path6.params ? renderParams(path6.params, pathIndex) : "{}";
|
|
768
|
+
const meta = route.meta ? `meta${route.index}` : "{}";
|
|
769
|
+
const pathPattern = pathToURLPatternString(path6.path);
|
|
770
|
+
return `{ handler: ${handler}, params: ${params}, meta: ${meta}, path: '${pathPattern}' }`;
|
|
771
|
+
}
|
|
772
|
+
function renderMiddleware(middleware) {
|
|
954
773
|
const writer = createStringWriter();
|
|
955
|
-
writer.writeLines(
|
|
774
|
+
writer.writeLines(
|
|
775
|
+
`// ${virtualFilePrefix}/${markoRunFilePrefix}middleware.js`
|
|
776
|
+
);
|
|
956
777
|
const imports = writer.branch("imports");
|
|
957
778
|
imports.writeLines(
|
|
958
|
-
`import {
|
|
779
|
+
`import { normalize } from '${virtualFilePrefix}/runtime/internal';`
|
|
959
780
|
);
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
`import { ${names.join(", ")} } from '${virtualFilePrefix}/${route.entryName}.js';`
|
|
966
|
-
);
|
|
781
|
+
writer.writeLines("");
|
|
782
|
+
for (const { id, importPath } of middleware) {
|
|
783
|
+
const importName = `middleware${id}`;
|
|
784
|
+
imports.writeLines(`import ${importName} from './${importPath}';`);
|
|
785
|
+
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
967
786
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
787
|
+
imports.join();
|
|
788
|
+
return writer.end();
|
|
789
|
+
}
|
|
790
|
+
function stripTsExtension(path6) {
|
|
791
|
+
const index = path6.lastIndexOf(".");
|
|
792
|
+
if (index !== -1) {
|
|
793
|
+
const ext = path6.slice(index + 1);
|
|
794
|
+
if (ext.toLowerCase() === "ts") {
|
|
795
|
+
return path6.slice(0, index);
|
|
796
|
+
}
|
|
973
797
|
}
|
|
798
|
+
return path6;
|
|
799
|
+
}
|
|
800
|
+
async function renderRouteTypeInfo(routes, pathPrefix = ".", adapter) {
|
|
801
|
+
var _a, _b;
|
|
802
|
+
const writer = createStringWriter();
|
|
974
803
|
writer.writeLines(
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
).writeBlockStart(`
|
|
985
|
-
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
writer.
|
|
991
|
-
|
|
992
|
-
writer.writeBlockEnd("}");
|
|
804
|
+
`/*
|
|
805
|
+
WARNING: This file is automatically generated and any changes made to it will be overwritten without warning.
|
|
806
|
+
Do NOT manually edit this file or your changes will be lost.
|
|
807
|
+
*/
|
|
808
|
+
`,
|
|
809
|
+
`import { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform } from "@marko/run/namespace";`,
|
|
810
|
+
`import type * as Run from "@marko/run";`
|
|
811
|
+
);
|
|
812
|
+
const headWriter = writer.branch("head");
|
|
813
|
+
writer.writeLines("\n").writeBlockStart(`declare module "@marko/run" {`);
|
|
814
|
+
if (adapter && adapter.typeInfo) {
|
|
815
|
+
const platformType = await adapter.typeInfo(
|
|
816
|
+
(data) => headWriter.write(data)
|
|
817
|
+
);
|
|
818
|
+
if (platformType) {
|
|
819
|
+
writer.writeLines(`interface Platform extends ${platformType} {}
|
|
820
|
+
`);
|
|
993
821
|
}
|
|
994
822
|
}
|
|
995
|
-
|
|
996
|
-
writer.
|
|
997
|
-
|
|
998
|
-
).
|
|
999
|
-
|
|
1000
|
-
)
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
823
|
+
headWriter.join();
|
|
824
|
+
writer.writeBlockStart(`interface AppData extends Run.DefineApp<{`).writeBlockStart("routes: {");
|
|
825
|
+
const routesWriter = writer.branch("routes");
|
|
826
|
+
writer.writeBlockEnd("}").writeBlockEnd(`}> {}`).writeBlockEnd(`}`);
|
|
827
|
+
const routeTypes = /* @__PURE__ */ new Map();
|
|
828
|
+
for (const route of routes.list) {
|
|
829
|
+
let routeType = "";
|
|
830
|
+
for (const path6 of route.paths) {
|
|
831
|
+
const pathType = `"${pathToURLPatternString(path6.path)}"`;
|
|
832
|
+
routeType += routeType ? " | " + pathType : pathType;
|
|
833
|
+
routesWriter.writeLines(`${pathType}: Routes["${route.key}"];`);
|
|
834
|
+
}
|
|
835
|
+
for (const file of [route.handler, route.page]) {
|
|
836
|
+
if (file) {
|
|
837
|
+
const existing = routeTypes.get(file);
|
|
838
|
+
if (!existing) {
|
|
839
|
+
routeTypes.set(file, [routeType]);
|
|
840
|
+
} else {
|
|
841
|
+
existing.push(routeType);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
for (const files of [route.middleware, route.layouts]) {
|
|
846
|
+
if (files) {
|
|
847
|
+
for (const file of files) {
|
|
848
|
+
const existing = routeTypes.get(file);
|
|
849
|
+
if (!existing) {
|
|
850
|
+
routeTypes.set(file, [routeType]);
|
|
851
|
+
} else {
|
|
852
|
+
existing.push(routeType);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
1004
857
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
)
|
|
1009
|
-
writer.
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
858
|
+
for (const special of Object.values(routes.special)) {
|
|
859
|
+
routeTypes.set(special.page, []);
|
|
860
|
+
}
|
|
861
|
+
routesWriter.join();
|
|
862
|
+
const handlerWriter = writer.branch("handler");
|
|
863
|
+
const middlewareWriter = writer.branch("middleware");
|
|
864
|
+
const pageWriter = writer.branch("page");
|
|
865
|
+
const layoutWriter = writer.branch("layout");
|
|
866
|
+
for (const [file, types] of routeTypes) {
|
|
867
|
+
const path6 = `${pathPrefix}/${file.relativePath}`;
|
|
868
|
+
const routeType = `Run.Routes[${types.join(" | ")}]`;
|
|
869
|
+
switch (file.type) {
|
|
870
|
+
case RoutableFileTypes.Handler:
|
|
871
|
+
writeModuleDeclaration(handlerWriter, path6, routeType);
|
|
872
|
+
break;
|
|
873
|
+
case RoutableFileTypes.Middleware:
|
|
874
|
+
writeModuleDeclaration(middlewareWriter, path6, routeType);
|
|
875
|
+
break;
|
|
876
|
+
case RoutableFileTypes.Page:
|
|
877
|
+
writeModuleDeclaration(pageWriter, path6, routeType);
|
|
878
|
+
break;
|
|
879
|
+
case RoutableFileTypes.Layout:
|
|
880
|
+
writeModuleDeclaration(
|
|
881
|
+
layoutWriter,
|
|
882
|
+
path6,
|
|
883
|
+
routeType,
|
|
884
|
+
`
|
|
885
|
+
export interface Input {
|
|
886
|
+
renderBody: Marko.Body;
|
|
887
|
+
}`
|
|
888
|
+
);
|
|
889
|
+
break;
|
|
890
|
+
case RoutableFileTypes.Error:
|
|
891
|
+
writeModuleDeclaration(
|
|
892
|
+
writer,
|
|
893
|
+
path6,
|
|
894
|
+
"globalThis.MarkoRun.Route",
|
|
895
|
+
`
|
|
896
|
+
export interface Input {
|
|
897
|
+
error: unknown;
|
|
898
|
+
}`
|
|
899
|
+
);
|
|
900
|
+
break;
|
|
901
|
+
case RoutableFileTypes.NotFound:
|
|
902
|
+
writeModuleDeclaration(writer, path6, "Run.Route");
|
|
903
|
+
break;
|
|
1024
904
|
}
|
|
1025
|
-
`);
|
|
1026
905
|
}
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
906
|
+
handlerWriter.join();
|
|
907
|
+
middlewareWriter.join();
|
|
908
|
+
pageWriter.join();
|
|
909
|
+
layoutWriter.join();
|
|
910
|
+
writer.writeBlockStart(`
|
|
911
|
+
type Routes = {`);
|
|
912
|
+
for (const route of routes.list) {
|
|
913
|
+
const { meta, handler, page } = route;
|
|
914
|
+
if (page || handler) {
|
|
915
|
+
const verbs = [];
|
|
916
|
+
if (page || ((_a = handler == null ? void 0 : handler.verbs) == null ? void 0 : _a.includes("get"))) {
|
|
917
|
+
verbs.push(`"get"`);
|
|
918
|
+
}
|
|
919
|
+
if ((_b = handler == null ? void 0 : handler.verbs) == null ? void 0 : _b.includes("post")) {
|
|
920
|
+
verbs.push(`"post"`);
|
|
921
|
+
}
|
|
922
|
+
let routeType = `{ verb: ${verbs.join(" | ")};`;
|
|
923
|
+
if (meta) {
|
|
924
|
+
const metaPath = stripTsExtension(`${pathPrefix}/${meta.relativePath}`);
|
|
925
|
+
let metaType = `typeof import("${metaPath}")`;
|
|
926
|
+
if (/\.(ts|js|mjs)$/.test(meta.name)) {
|
|
927
|
+
metaType += `["default"]`;
|
|
928
|
+
}
|
|
929
|
+
routeType += ` meta: ${metaType};`;
|
|
930
|
+
}
|
|
931
|
+
writer.writeLines(`"${route.key}": ${routeType} };`);
|
|
932
|
+
}
|
|
1039
933
|
}
|
|
1040
934
|
writer.writeBlockEnd("}");
|
|
1041
|
-
renderFetch(writer, options);
|
|
1042
935
|
return writer.end();
|
|
1043
936
|
}
|
|
1044
|
-
function
|
|
1045
|
-
writer.write(`
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
const url = new URL(request.url);
|
|
1049
|
-
let { pathname } = url;`);
|
|
1050
|
-
switch (options.trailingSlashes) {
|
|
1051
|
-
case "RedirectWithout":
|
|
1052
|
-
writer.write(`
|
|
1053
|
-
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
1054
|
-
url.pathname = pathname.slice(0, -1);
|
|
1055
|
-
return Response.redirect(url);
|
|
1056
|
-
}`);
|
|
1057
|
-
break;
|
|
1058
|
-
case "RedirectWith":
|
|
1059
|
-
writer.write(`
|
|
1060
|
-
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
1061
|
-
url.pathname = pathname + '/';
|
|
1062
|
-
return Response.redirect(url);
|
|
1063
|
-
}`);
|
|
1064
|
-
break;
|
|
1065
|
-
case "RewriteWithout":
|
|
1066
|
-
writer.write(`
|
|
1067
|
-
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
1068
|
-
url.pathname = pathname = pathname.slice(0, -1);
|
|
1069
|
-
}`);
|
|
1070
|
-
break;
|
|
1071
|
-
case "RewriteWith":
|
|
1072
|
-
writer.write(`
|
|
1073
|
-
if (pathname !== '/' && !pathname.endsWith('/')) {
|
|
1074
|
-
url.pathname = pathname = pathname + '/';
|
|
1075
|
-
}`);
|
|
1076
|
-
break;
|
|
937
|
+
function writeModuleDeclaration(writer, path6, routeType, moduleTypes) {
|
|
938
|
+
writer.writeLines("").write(`declare module "${stripTsExtension(path6)}" {`);
|
|
939
|
+
if (moduleTypes) {
|
|
940
|
+
writer.write(moduleTypes);
|
|
1077
941
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
942
|
+
if (routeType) {
|
|
943
|
+
const isMarko = path6.endsWith(".marko");
|
|
944
|
+
writer.write(`
|
|
945
|
+
namespace MarkoRun {
|
|
946
|
+
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
947
|
+
export type Route = ${routeType};
|
|
948
|
+
export type Context = Run.MultiRouteContext<Route>${isMarko ? " & Marko.Global" : ""};
|
|
949
|
+
export type Handler = Run.HandlerLike<Route>;
|
|
950
|
+
/** @deprecated use \`((context, next) => { ... }) satisfies MarkoRun.Handler\` instead */
|
|
951
|
+
export const route: Run.HandlerTypeFn<Route>;
|
|
952
|
+
}`);
|
|
1089
953
|
}
|
|
954
|
+
writer.writeLines(`
|
|
1090
955
|
}`);
|
|
1091
956
|
}
|
|
1092
|
-
function
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
957
|
+
function pathToURLPatternString(path6) {
|
|
958
|
+
return path6.replace(/\/\$(\$?)([^/]*)/g, (_, catchAll, name) => {
|
|
959
|
+
name = decodeURIComponent(name);
|
|
960
|
+
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
function createRouteTrie(routes) {
|
|
964
|
+
const root = {
|
|
965
|
+
key: ""
|
|
966
|
+
};
|
|
967
|
+
function insert(path6, route) {
|
|
968
|
+
let node = root;
|
|
969
|
+
for (const segment of path6.segments) {
|
|
970
|
+
if (segment === "$$") {
|
|
971
|
+
node.catchAll ?? (node.catchAll = { route, path: path6 });
|
|
972
|
+
return;
|
|
973
|
+
} else if (segment === "$") {
|
|
974
|
+
node = node.dynamic ?? (node.dynamic = {
|
|
975
|
+
key: ""
|
|
976
|
+
});
|
|
977
|
+
} else {
|
|
978
|
+
node.static ?? (node.static = /* @__PURE__ */ new Map());
|
|
979
|
+
let next = node.static.get(segment);
|
|
980
|
+
if (!next) {
|
|
981
|
+
next = {
|
|
982
|
+
key: segment
|
|
983
|
+
};
|
|
984
|
+
node.static.set(segment, next);
|
|
985
|
+
}
|
|
986
|
+
node = next;
|
|
987
|
+
}
|
|
1104
988
|
}
|
|
989
|
+
node.path ?? (node.path = path6);
|
|
990
|
+
node.route ?? (node.route = route);
|
|
1105
991
|
}
|
|
1106
|
-
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
992
|
+
for (const route of routes) {
|
|
993
|
+
for (const path6 of route.paths) {
|
|
994
|
+
insert(path6, route);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return root;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// src/vite/routes/parse.ts
|
|
1001
|
+
function parseFlatRoute(pattern) {
|
|
1002
|
+
if (!pattern) throw new Error("Empty pattern");
|
|
1003
|
+
const len = pattern.length;
|
|
1004
|
+
let i = 0;
|
|
1005
|
+
return parse2([
|
|
1006
|
+
{
|
|
1007
|
+
id: "/",
|
|
1008
|
+
segments: [],
|
|
1009
|
+
source: pattern
|
|
1010
|
+
}
|
|
1011
|
+
]);
|
|
1012
|
+
function parse2(basePaths, group) {
|
|
1013
|
+
const pathMap = /* @__PURE__ */ new Map();
|
|
1014
|
+
const delimiters = group ? ").," : ".,";
|
|
1015
|
+
let charCode;
|
|
1016
|
+
let segmentStart = i;
|
|
1017
|
+
let type;
|
|
1018
|
+
let current;
|
|
1019
|
+
do {
|
|
1020
|
+
charCode = pattern.charCodeAt(i);
|
|
1021
|
+
if (charCode === 41 && group) {
|
|
1022
|
+
break;
|
|
1023
|
+
} else if (charCode === 44) {
|
|
1024
|
+
if (!current) {
|
|
1025
|
+
segmentEnd(
|
|
1026
|
+
basePaths.map((path6) => ({
|
|
1027
|
+
...path6,
|
|
1028
|
+
segments: path6.segments.slice()
|
|
1029
|
+
})),
|
|
1030
|
+
"",
|
|
1031
|
+
"_",
|
|
1032
|
+
pathMap
|
|
1033
|
+
);
|
|
1034
|
+
} else {
|
|
1035
|
+
segmentEnd(current, pattern.slice(segmentStart, i), type, pathMap);
|
|
1116
1036
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1037
|
+
current = void 0;
|
|
1038
|
+
type = void 0;
|
|
1039
|
+
segmentStart = ++i;
|
|
1040
|
+
} else if (charCode === 46) {
|
|
1041
|
+
if (current) {
|
|
1042
|
+
segmentEnd(current, pattern.slice(segmentStart, i), type);
|
|
1119
1043
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
if (dynamic == null ? void 0 : dynamic.route) {
|
|
1127
|
-
const segment = `s${next}`;
|
|
1128
|
-
writer.writeLines(`const ${segment} = decodeURIComponent(${value});`);
|
|
1129
|
-
value = segment;
|
|
1130
|
-
} else if (terminal == null ? void 0 : terminal.some(
|
|
1131
|
-
(terminal2) => decodeURIComponent(terminal2.key) !== terminal2.key
|
|
1132
|
-
)) {
|
|
1133
|
-
value = `decodeURIComponent(${value})`;
|
|
1134
|
-
}
|
|
1135
|
-
if (terminal) {
|
|
1136
|
-
const useSwitch = terminal.length > 1;
|
|
1137
|
-
if (useSwitch) {
|
|
1138
|
-
writer.writeBlockStart(`switch (${value}) {`);
|
|
1044
|
+
type = void 0;
|
|
1045
|
+
segmentStart = ++i;
|
|
1046
|
+
} else if (charCode === 40) {
|
|
1047
|
+
const groupPaths = parse2(current || basePaths, ++i);
|
|
1048
|
+
if (groupPaths.length) {
|
|
1049
|
+
current = groupPaths;
|
|
1139
1050
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1051
|
+
segmentStart = ++i;
|
|
1052
|
+
} else {
|
|
1053
|
+
if (charCode === 95) {
|
|
1054
|
+
type = "_";
|
|
1055
|
+
} else if (charCode === 36) {
|
|
1056
|
+
type = pattern.charCodeAt(i + 1) === 36 ? "$$" : "$";
|
|
1057
|
+
}
|
|
1058
|
+
current ?? (current = basePaths.map((path6) => ({
|
|
1059
|
+
...path6,
|
|
1060
|
+
segments: path6.segments.slice()
|
|
1061
|
+
})));
|
|
1062
|
+
i = len;
|
|
1063
|
+
for (const char of delimiters) {
|
|
1064
|
+
const index = pattern.indexOf(char, segmentStart);
|
|
1065
|
+
if (index >= 0 && index < i) {
|
|
1066
|
+
i = index;
|
|
1146
1067
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
} while (i < len);
|
|
1071
|
+
if (group && charCode !== 41) {
|
|
1072
|
+
throw new Error(
|
|
1073
|
+
`Invalid route pattern: group was not closed '${pattern.slice(
|
|
1074
|
+
group
|
|
1075
|
+
)}' in '${pattern}'`
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
if (!current) {
|
|
1079
|
+
segmentEnd(
|
|
1080
|
+
basePaths.map((path6) => ({
|
|
1081
|
+
...path6,
|
|
1082
|
+
segments: path6.segments.slice()
|
|
1083
|
+
})),
|
|
1084
|
+
"",
|
|
1085
|
+
"_",
|
|
1086
|
+
pathMap
|
|
1087
|
+
);
|
|
1088
|
+
} else {
|
|
1089
|
+
segmentEnd(current, pattern.slice(segmentStart, i), type, pathMap);
|
|
1090
|
+
}
|
|
1091
|
+
return [...pathMap.values()];
|
|
1092
|
+
}
|
|
1093
|
+
function segmentEnd(paths, raw, type, map) {
|
|
1094
|
+
let segment;
|
|
1095
|
+
if (raw) {
|
|
1096
|
+
segment = {
|
|
1097
|
+
raw,
|
|
1098
|
+
name: raw,
|
|
1099
|
+
type
|
|
1100
|
+
};
|
|
1101
|
+
if (type === "$" || type === "$$") {
|
|
1102
|
+
segment.name = type;
|
|
1103
|
+
segment.param = raw.slice(type.length);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
for (const path6 of paths) {
|
|
1107
|
+
if (segment) {
|
|
1108
|
+
if (path6.isCatchall) {
|
|
1109
|
+
throw new Error(
|
|
1110
|
+
`Invalid route pattern: nested segments are not allowed after a catch-all parameter. Found '.' following '${pattern.slice(
|
|
1111
|
+
0,
|
|
1112
|
+
i
|
|
1113
|
+
)}' in '${pattern}'.`
|
|
1150
1114
|
);
|
|
1151
1115
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1116
|
+
path6.segments.push(segment);
|
|
1117
|
+
path6.id += path6.id === "/" ? segment.name : `/${segment.name}`;
|
|
1118
|
+
if (type === "$$") {
|
|
1119
|
+
path6.isCatchall = true;
|
|
1154
1120
|
}
|
|
1155
1121
|
}
|
|
1156
|
-
if (
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1122
|
+
if (map) {
|
|
1123
|
+
if (map.has(path6.id)) {
|
|
1124
|
+
const existing = map.get(path6.id);
|
|
1125
|
+
const existingExpansion = existing.segments.map((s) => s.raw).join(".");
|
|
1126
|
+
const currentExpansion = path6.segments.map((s) => s.raw).join(".");
|
|
1127
|
+
throw new Error(
|
|
1128
|
+
`Invalid route pattern: route '${path6.id}' is ambiguous. Expansion '${currentExpansion}' collides with '${existingExpansion}' in '${pattern}'.`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
map.set(path6.id, path6);
|
|
1164
1132
|
}
|
|
1165
1133
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
// src/vite/routes/vdir.ts
|
|
1138
|
+
var _dirs, _pathlessDirs;
|
|
1139
|
+
var _VDir = class _VDir {
|
|
1140
|
+
constructor(parent, segment, source) {
|
|
1141
|
+
__privateAdd(this, _dirs);
|
|
1142
|
+
__privateAdd(this, _pathlessDirs);
|
|
1143
|
+
__publicField(this, "parent");
|
|
1144
|
+
__publicField(this, "source");
|
|
1145
|
+
__publicField(this, "path");
|
|
1146
|
+
__publicField(this, "fullPath");
|
|
1147
|
+
__publicField(this, "segment");
|
|
1148
|
+
__publicField(this, "files");
|
|
1149
|
+
if (!parent || !segment) {
|
|
1150
|
+
this.parent = null;
|
|
1151
|
+
this.source = null;
|
|
1152
|
+
this.path = "/";
|
|
1153
|
+
this.fullPath = "/";
|
|
1154
|
+
this.segment = {
|
|
1155
|
+
raw: "",
|
|
1156
|
+
name: ""
|
|
1157
|
+
};
|
|
1158
|
+
} else {
|
|
1159
|
+
this.parent = parent;
|
|
1160
|
+
this.source = source;
|
|
1161
|
+
this.path = parent.path + (parent.path === "/" ? segment.name : `/${segment.name}`);
|
|
1162
|
+
this.fullPath = parent.fullPath + (parent.fullPath === "/" ? segment.name : `/${segment.name}`);
|
|
1163
|
+
if (segment.param) {
|
|
1164
|
+
this.fullPath += segment.param;
|
|
1180
1165
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1166
|
+
this.segment = segment;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
get pathInfo() {
|
|
1170
|
+
const value = {
|
|
1171
|
+
id: "/",
|
|
1172
|
+
path: "/",
|
|
1173
|
+
segments: []
|
|
1174
|
+
};
|
|
1175
|
+
let sep = "";
|
|
1176
|
+
for (const { segment } of this) {
|
|
1177
|
+
const { type, name, param } = segment;
|
|
1178
|
+
if (name && type !== "_") {
|
|
1179
|
+
value.id += sep + (type || name);
|
|
1180
|
+
value.path += sep + name;
|
|
1181
|
+
value.isEnd = type === "$$";
|
|
1182
|
+
if (param) {
|
|
1183
|
+
value.path += param;
|
|
1184
|
+
const index = type === "$$" ? null : value.segments.length;
|
|
1185
|
+
if (!value.params) {
|
|
1186
|
+
value.params = { [param]: index };
|
|
1187
|
+
} else if (!(param in value.params)) {
|
|
1188
|
+
value.params[param] = index;
|
|
1199
1189
|
}
|
|
1200
1190
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
if ((dynamic == null ? void 0 : dynamic.static) || (dynamic == null ? void 0 : dynamic.dynamic) || (dynamic == null ? void 0 : dynamic.catchAll)) {
|
|
1206
|
-
writer.writeBlockStart(`if (${value}) {`);
|
|
1207
|
-
writeRouterVerb(writer, dynamic, verb, next, index);
|
|
1208
|
-
writer.writeBlockEnd(`}`);
|
|
1191
|
+
value.segments.push(name);
|
|
1192
|
+
sep = "/";
|
|
1209
1193
|
}
|
|
1210
1194
|
}
|
|
1195
|
+
Object.defineProperty(this, "pathInfo", {
|
|
1196
|
+
value,
|
|
1197
|
+
enumerable: true
|
|
1198
|
+
});
|
|
1199
|
+
return value;
|
|
1211
1200
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
verb,
|
|
1219
|
-
catchAll.route,
|
|
1220
|
-
catchAll.path,
|
|
1221
|
-
String(offset)
|
|
1222
|
-
)}; // ${catchAll.path.path}`
|
|
1223
|
-
);
|
|
1224
|
-
} else if (level === 0) {
|
|
1225
|
-
writer.writeLines("return null;");
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
function wrapPropertyName(name) {
|
|
1229
|
-
name = decodeURIComponent(name);
|
|
1230
|
-
return /^[^A-Za-z_$]|[^A-Za-z0-9$_]/.test(name) ? `'${name}'` : name;
|
|
1231
|
-
}
|
|
1232
|
-
function renderParams(params, pathIndex) {
|
|
1233
|
-
let result = "";
|
|
1234
|
-
let catchAll = "";
|
|
1235
|
-
let sep = "{";
|
|
1236
|
-
for (const [name, index] of Object.entries(params)) {
|
|
1237
|
-
if (typeof index === "number") {
|
|
1238
|
-
result += `${sep} ${wrapPropertyName(name)}: s${index + 1}`;
|
|
1239
|
-
sep = ",";
|
|
1240
|
-
} else if (pathIndex) {
|
|
1241
|
-
catchAll = name;
|
|
1201
|
+
addDir(path6, segment) {
|
|
1202
|
+
const map = segment.type === "_" ? __privateGet(this, _pathlessDirs) ?? __privateSet(this, _pathlessDirs, /* @__PURE__ */ new Map()) : __privateGet(this, _dirs) ?? __privateSet(this, _dirs, /* @__PURE__ */ new Map());
|
|
1203
|
+
if (!map.has(segment.name)) {
|
|
1204
|
+
const dir = new _VDir(this, segment, path6);
|
|
1205
|
+
map.set(segment.name, dir);
|
|
1206
|
+
return dir;
|
|
1242
1207
|
}
|
|
1208
|
+
return map.get(segment.name);
|
|
1243
1209
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
imports.writeLines(
|
|
1265
|
-
`import { normalize } from '${virtualFilePrefix}/runtime/internal';`
|
|
1266
|
-
);
|
|
1267
|
-
writer.writeLines("");
|
|
1268
|
-
for (const { id, importPath } of middleware) {
|
|
1269
|
-
const importName = `middleware${id}`;
|
|
1270
|
-
imports.writeLines(`import ${importName} from './${importPath}';`);
|
|
1271
|
-
writer.writeLines(`export const mware${id} = normalize(${importName});`);
|
|
1272
|
-
}
|
|
1273
|
-
imports.join();
|
|
1274
|
-
return writer.end();
|
|
1275
|
-
}
|
|
1276
|
-
function stripTsExtension(path6) {
|
|
1277
|
-
const index = path6.lastIndexOf(".");
|
|
1278
|
-
if (index !== -1) {
|
|
1279
|
-
const ext = path6.slice(index + 1);
|
|
1280
|
-
if (ext.toLowerCase() === "ts") {
|
|
1281
|
-
return path6.slice(0, index);
|
|
1210
|
+
addFile(file) {
|
|
1211
|
+
if (!this.files) {
|
|
1212
|
+
this.files = /* @__PURE__ */ new Map();
|
|
1213
|
+
this.files.set(file.type, file);
|
|
1214
|
+
} else if (!this.files.has(file.type)) {
|
|
1215
|
+
this.files.set(file.type, file);
|
|
1216
|
+
} else {
|
|
1217
|
+
const existing = this.files.get(file.type);
|
|
1218
|
+
if (existing !== file) {
|
|
1219
|
+
throw new Error(
|
|
1220
|
+
`Duplicate file type '${file.type}' added at path '${this.path}'. File '${file.importPath}' collides with '${existing.importPath}'.`
|
|
1221
|
+
);
|
|
1222
|
+
} else if (file.type === RoutableFileTypes.Page || file.type === RoutableFileTypes.Handler) {
|
|
1223
|
+
throw new Error(
|
|
1224
|
+
`Ambiguous path definition: route '${this.path}' is defined multiple times by ${file.importPath}`
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
throw new Error(
|
|
1228
|
+
`Ambiguous path definition: file '${this.path}' is included multiple times by ${file.importPath}`
|
|
1229
|
+
);
|
|
1282
1230
|
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
`/*
|
|
1291
|
-
WARNING: This file is automatically generated and any changes made to it will be overwritten without warning.
|
|
1292
|
-
Do NOT manually edit this file or your changes will be lost.
|
|
1293
|
-
*/
|
|
1294
|
-
`,
|
|
1295
|
-
`import { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform } from "@marko/run/namespace";`,
|
|
1296
|
-
`import type * as Run from "@marko/run";`
|
|
1297
|
-
);
|
|
1298
|
-
const headWriter = writer.branch("head");
|
|
1299
|
-
writer.writeLines("\n").writeBlockStart(`declare module "@marko/run" {`);
|
|
1300
|
-
if (adapter && adapter.typeInfo) {
|
|
1301
|
-
const platformType = await adapter.typeInfo(
|
|
1302
|
-
(data) => headWriter.write(data)
|
|
1303
|
-
);
|
|
1304
|
-
if (platformType) {
|
|
1305
|
-
writer.writeLines(`interface Platform extends ${platformType} {}
|
|
1306
|
-
`);
|
|
1231
|
+
}
|
|
1232
|
+
*dirs() {
|
|
1233
|
+
if (__privateGet(this, _pathlessDirs)) {
|
|
1234
|
+
yield* __privateGet(this, _pathlessDirs).values();
|
|
1235
|
+
}
|
|
1236
|
+
if (__privateGet(this, _dirs)) {
|
|
1237
|
+
yield* __privateGet(this, _dirs).values();
|
|
1307
1238
|
}
|
|
1308
1239
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
writer.writeBlockEnd("}").writeBlockEnd(`}> {}`).writeBlockEnd(`}`);
|
|
1313
|
-
const routeTypes = /* @__PURE__ */ new Map();
|
|
1314
|
-
for (const route of routes.list) {
|
|
1315
|
-
let routeType = "";
|
|
1316
|
-
for (const path6 of route.paths) {
|
|
1317
|
-
const pathType = `"${pathToURLPatternString(path6.path)}"`;
|
|
1318
|
-
routeType += routeType ? " | " + pathType : pathType;
|
|
1319
|
-
routesWriter.writeLines(`${pathType}: Routes["${route.key}"];`);
|
|
1240
|
+
*[Symbol.iterator]() {
|
|
1241
|
+
if (this.parent) {
|
|
1242
|
+
yield* this.parent;
|
|
1320
1243
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1244
|
+
yield this;
|
|
1245
|
+
}
|
|
1246
|
+
static addPaths(roots, paths) {
|
|
1247
|
+
const dirs = [];
|
|
1248
|
+
const unique = /* @__PURE__ */ new Set();
|
|
1249
|
+
for (const root of roots) {
|
|
1250
|
+
for (const path6 of paths) {
|
|
1251
|
+
let dir = root;
|
|
1252
|
+
for (const segment of path6.segments) {
|
|
1253
|
+
dir = dir.addDir(path6, segment);
|
|
1328
1254
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
} else {
|
|
1338
|
-
existing.push(routeType);
|
|
1255
|
+
if (unique.has(dir.path)) {
|
|
1256
|
+
const sources = /* @__PURE__ */ new Set();
|
|
1257
|
+
let sourcePath = "";
|
|
1258
|
+
for (const { source } of dir) {
|
|
1259
|
+
if (source && !sources.has(source.source)) {
|
|
1260
|
+
sources.add(source.source);
|
|
1261
|
+
sourcePath += source.source + "/";
|
|
1262
|
+
}
|
|
1339
1263
|
}
|
|
1264
|
+
throw new Error(
|
|
1265
|
+
`Ambiguous directory structure: '${sourcePath}${path6.source}' defines '${dir.path}' multiple times.`
|
|
1266
|
+
);
|
|
1267
|
+
} else {
|
|
1268
|
+
unique.add(dir.path);
|
|
1269
|
+
dirs.push(dir);
|
|
1340
1270
|
}
|
|
1341
1271
|
}
|
|
1342
1272
|
}
|
|
1273
|
+
return dirs;
|
|
1343
1274
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1275
|
+
};
|
|
1276
|
+
_dirs = new WeakMap();
|
|
1277
|
+
_pathlessDirs = new WeakMap();
|
|
1278
|
+
var VDir = _VDir;
|
|
1279
|
+
|
|
1280
|
+
// src/vite/routes/builder.ts
|
|
1281
|
+
var markoFiles = `(${RoutableFileTypes.Layout}|${RoutableFileTypes.Page}|${RoutableFileTypes.NotFound}|${RoutableFileTypes.Error})\\.(?:.*\\.)?(marko)`;
|
|
1282
|
+
var nonMarkoFiles = `(${RoutableFileTypes.Middleware}|${RoutableFileTypes.Handler}|${RoutableFileTypes.Meta})\\.(?:.*\\.)?(.+)`;
|
|
1283
|
+
var routeableFileRegex = new RegExp(
|
|
1284
|
+
`[+](?:${markoFiles}|${nonMarkoFiles})$`,
|
|
1285
|
+
"i"
|
|
1286
|
+
);
|
|
1287
|
+
function matchRoutableFile(filename) {
|
|
1288
|
+
const match = filename.match(routeableFileRegex);
|
|
1289
|
+
return match && (match[1] || match[3]).toLowerCase();
|
|
1290
|
+
}
|
|
1291
|
+
function isSpecialType(type) {
|
|
1292
|
+
return type === RoutableFileTypes.NotFound || type === RoutableFileTypes.Error;
|
|
1293
|
+
}
|
|
1294
|
+
async function buildRoutes(sources) {
|
|
1295
|
+
const uniqueRoutes = /* @__PURE__ */ new Map();
|
|
1296
|
+
const routes = [];
|
|
1297
|
+
const special = {};
|
|
1298
|
+
const middlewares = /* @__PURE__ */ new Set();
|
|
1299
|
+
const unusedFiles = /* @__PURE__ */ new Set();
|
|
1300
|
+
const currentLayouts = /* @__PURE__ */ new Set();
|
|
1301
|
+
const currentMiddleware = /* @__PURE__ */ new Set();
|
|
1302
|
+
const root = new VDir();
|
|
1303
|
+
const dirStack = [];
|
|
1304
|
+
let basePath;
|
|
1305
|
+
let importPrefix;
|
|
1306
|
+
let activeDirs;
|
|
1307
|
+
let isBaseDir;
|
|
1308
|
+
let nextFileId = 1;
|
|
1309
|
+
let nextRouteIndex = 1;
|
|
1310
|
+
const walkOptions = {
|
|
1311
|
+
onEnter({ name }) {
|
|
1312
|
+
const prevDirStackLength = dirStack.length;
|
|
1313
|
+
if (isBaseDir) {
|
|
1314
|
+
isBaseDir = false;
|
|
1315
|
+
if (!basePath) {
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
name = basePath;
|
|
1319
|
+
} else {
|
|
1320
|
+
dirStack.push(name);
|
|
1321
|
+
}
|
|
1322
|
+
const previousDirs = activeDirs;
|
|
1323
|
+
const paths = parseFlatRoute(name);
|
|
1324
|
+
activeDirs = VDir.addPaths(previousDirs, paths);
|
|
1325
|
+
return () => {
|
|
1326
|
+
activeDirs = previousDirs;
|
|
1327
|
+
dirStack.length = prevDirStackLength;
|
|
1328
|
+
};
|
|
1329
|
+
},
|
|
1330
|
+
onFile({ name, path: path6 }) {
|
|
1331
|
+
const match = name.match(routeableFileRegex);
|
|
1332
|
+
if (!match) {
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
const type = (match[1] || match[3]).toLowerCase();
|
|
1336
|
+
if (dirStack.length && isSpecialType(type)) {
|
|
1337
|
+
console.warn(
|
|
1338
|
+
`Special pages '${RoutableFileTypes.NotFound}' and '${RoutableFileTypes.Error}' are only considered in the root directory - ignoring ${path6}`
|
|
1385
1339
|
);
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
let dirs = activeDirs;
|
|
1343
|
+
if (match.index) {
|
|
1344
|
+
const paths = parseFlatRoute(name.slice(0, match.index));
|
|
1345
|
+
dirs = VDir.addPaths(activeDirs, paths);
|
|
1346
|
+
}
|
|
1347
|
+
const dirPath = dirStack.join("/");
|
|
1348
|
+
const relativePath = dirPath ? `${dirPath}/${name}` : name;
|
|
1349
|
+
const file = {
|
|
1350
|
+
id: String(nextFileId++),
|
|
1351
|
+
name,
|
|
1352
|
+
type,
|
|
1353
|
+
filePath: path6,
|
|
1354
|
+
relativePath,
|
|
1355
|
+
importPath: `${importPrefix}/${relativePath}`,
|
|
1356
|
+
verbs: type === RoutableFileTypes.Page ? ["get", "head"] : void 0
|
|
1357
|
+
};
|
|
1358
|
+
for (const dir of dirs) {
|
|
1359
|
+
dir.addFile(file);
|
|
1360
|
+
}
|
|
1390
1361
|
}
|
|
1362
|
+
};
|
|
1363
|
+
if (!Array.isArray(sources)) {
|
|
1364
|
+
sources = [sources];
|
|
1391
1365
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1366
|
+
for (const source of sources) {
|
|
1367
|
+
importPrefix = source.importPrefix ? source.importPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
1368
|
+
basePath = source.basePath || "";
|
|
1369
|
+
activeDirs = [root];
|
|
1370
|
+
isBaseDir = true;
|
|
1371
|
+
await source.walker(walkOptions);
|
|
1372
|
+
}
|
|
1373
|
+
traverse(root);
|
|
1374
|
+
return {
|
|
1375
|
+
list: routes,
|
|
1376
|
+
middleware: [...middlewares],
|
|
1377
|
+
special
|
|
1378
|
+
};
|
|
1379
|
+
function traverse(dir) {
|
|
1380
|
+
let middleware;
|
|
1381
|
+
let layout;
|
|
1382
|
+
if (dir.files) {
|
|
1383
|
+
middleware = dir.files.get(RoutableFileTypes.Middleware);
|
|
1384
|
+
layout = dir.files.get(RoutableFileTypes.Layout);
|
|
1385
|
+
const handler = dir.files.get(RoutableFileTypes.Handler);
|
|
1386
|
+
const page = dir.files.get(RoutableFileTypes.Page);
|
|
1387
|
+
let hasSpecial = false;
|
|
1388
|
+
if (middleware) {
|
|
1389
|
+
if (currentMiddleware.has(middleware)) {
|
|
1390
|
+
middleware = void 0;
|
|
1391
|
+
} else {
|
|
1392
|
+
currentMiddleware.add(middleware);
|
|
1393
|
+
unusedFiles.add(middleware);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
if (layout) {
|
|
1397
|
+
if (currentLayouts.has(layout)) {
|
|
1398
|
+
layout = void 0;
|
|
1399
|
+
} else {
|
|
1400
|
+
currentLayouts.add(layout);
|
|
1401
|
+
unusedFiles.add(layout);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
if (page || handler) {
|
|
1405
|
+
const path6 = dir.pathInfo;
|
|
1406
|
+
if (uniqueRoutes.has(path6.id)) {
|
|
1407
|
+
const existing = uniqueRoutes.get(path6.id);
|
|
1408
|
+
const route = routes[existing.index];
|
|
1409
|
+
const existingFiles = [route.handler, route.page].filter(Boolean).map((f) => f.filePath);
|
|
1410
|
+
const currentFiles = [handler, page].filter(Boolean).map((f) => f.filePath);
|
|
1411
|
+
throw new Error(`Duplicate routes for path '${path6.path}' were defined. A route established by:
|
|
1412
|
+
${existingFiles.join(" and ")} via '${existing.dir.path}'
|
|
1413
|
+
collides with
|
|
1414
|
+
${currentFiles.join(" and ")} via '${dir.path}'
|
|
1415
|
+
`);
|
|
1416
|
+
}
|
|
1417
|
+
uniqueRoutes.set(path6.id, { dir, index: routes.length });
|
|
1418
|
+
routes.push({
|
|
1419
|
+
index: nextRouteIndex++,
|
|
1420
|
+
key: dir.fullPath,
|
|
1421
|
+
paths: [path6],
|
|
1422
|
+
middleware: [...currentMiddleware],
|
|
1423
|
+
layouts: page ? [...currentLayouts] : [],
|
|
1424
|
+
meta: dir.files.get(RoutableFileTypes.Meta),
|
|
1425
|
+
page,
|
|
1426
|
+
handler,
|
|
1427
|
+
entryName: `${markoRunFilePrefix}route` + (dir.path !== "/" ? dir.fullPath.replace(/\//g, ".").replace(/(%[A-Fa-f0-9]{2})+/g, "_") : "")
|
|
1428
|
+
});
|
|
1404
1429
|
}
|
|
1405
|
-
if (
|
|
1406
|
-
|
|
1430
|
+
if (dir === root) {
|
|
1431
|
+
for (const [type, file] of dir.files) {
|
|
1432
|
+
if (isSpecialType(type)) {
|
|
1433
|
+
hasSpecial = true;
|
|
1434
|
+
special[type] = {
|
|
1435
|
+
index: 0,
|
|
1436
|
+
key: type,
|
|
1437
|
+
paths: [],
|
|
1438
|
+
middleware: [],
|
|
1439
|
+
layouts: [...currentLayouts],
|
|
1440
|
+
page: file,
|
|
1441
|
+
entryName: `${markoRunFilePrefix}special.${type}`
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1407
1445
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1446
|
+
if (handler || page) {
|
|
1447
|
+
for (const middleware2 of currentMiddleware) {
|
|
1448
|
+
middlewares.add(middleware2);
|
|
1449
|
+
unusedFiles.delete(middleware2);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (page || hasSpecial) {
|
|
1453
|
+
for (const layout2 of currentLayouts) {
|
|
1454
|
+
unusedFiles.delete(layout2);
|
|
1414
1455
|
}
|
|
1415
|
-
routeType += ` meta: ${metaType};`;
|
|
1416
1456
|
}
|
|
1417
|
-
|
|
1457
|
+
}
|
|
1458
|
+
if (dir.dirs) {
|
|
1459
|
+
for (const child of dir.dirs()) {
|
|
1460
|
+
traverse(child);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
if (middleware) {
|
|
1464
|
+
currentMiddleware.delete(middleware);
|
|
1465
|
+
}
|
|
1466
|
+
if (layout) {
|
|
1467
|
+
currentLayouts.delete(layout);
|
|
1418
1468
|
}
|
|
1419
1469
|
}
|
|
1420
|
-
writer.writeBlockEnd("}");
|
|
1421
|
-
return writer.end();
|
|
1422
|
-
}
|
|
1423
|
-
function writeModuleDeclaration(writer, path6, routeType, moduleTypes) {
|
|
1424
|
-
writer.writeLines("").write(`declare module "${stripTsExtension(path6)}" {`);
|
|
1425
|
-
if (moduleTypes) {
|
|
1426
|
-
writer.write(moduleTypes);
|
|
1427
|
-
}
|
|
1428
|
-
if (routeType) {
|
|
1429
|
-
const isMarko = path6.endsWith(".marko");
|
|
1430
|
-
writer.write(`
|
|
1431
|
-
namespace MarkoRun {
|
|
1432
|
-
export { NotHandled, NotMatched, GetPaths, PostPaths, GetablePath, GetableHref, PostablePath, PostableHref, Platform };
|
|
1433
|
-
export type Route = ${routeType};
|
|
1434
|
-
export type Context = Run.MultiRouteContext<Route>${isMarko ? " & Marko.Global" : ""};
|
|
1435
|
-
export type Handler = Run.HandlerLike<Route>;
|
|
1436
|
-
/** @deprecated use \`((context, next) => { ... }) satisfies MarkoRun.Handler\` instead */
|
|
1437
|
-
export const route: Run.HandlerTypeFn<Route>;
|
|
1438
|
-
}`);
|
|
1439
|
-
}
|
|
1440
|
-
writer.writeLines(`
|
|
1441
|
-
}`);
|
|
1442
|
-
}
|
|
1443
|
-
function pathToURLPatternString(path6) {
|
|
1444
|
-
return path6.replace(/\/\$(\$?)([^\/]*)/g, (_, catchAll, name) => {
|
|
1445
|
-
name = decodeURIComponent(name);
|
|
1446
|
-
return catchAll ? `/:${name || "rest"}*` : `/:${name}`;
|
|
1447
|
-
});
|
|
1448
1470
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1471
|
+
|
|
1472
|
+
// src/vite/routes/walk.ts
|
|
1473
|
+
import fs from "fs";
|
|
1474
|
+
import path2 from "path";
|
|
1475
|
+
function createFSWalker(dir) {
|
|
1476
|
+
return async function walkFS({
|
|
1477
|
+
onEnter,
|
|
1478
|
+
onFile,
|
|
1479
|
+
onDir,
|
|
1480
|
+
maxDepth = 50
|
|
1481
|
+
}) {
|
|
1482
|
+
async function walk(dir2, depth) {
|
|
1483
|
+
const onExit = onEnter == null ? void 0 : onEnter(dir2);
|
|
1484
|
+
if (onExit !== false) {
|
|
1485
|
+
const dirs = [];
|
|
1486
|
+
const entries = await fs.promises.readdir(dir2.path, {
|
|
1487
|
+
withFileTypes: true
|
|
1462
1488
|
});
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
key: segment
|
|
1489
|
+
const prefix = dir2.path + path2.sep;
|
|
1490
|
+
for (const entry of entries) {
|
|
1491
|
+
const walkEntry = {
|
|
1492
|
+
name: entry.name,
|
|
1493
|
+
path: prefix + entry.name
|
|
1469
1494
|
};
|
|
1470
|
-
|
|
1495
|
+
if (entry.isDirectory()) {
|
|
1496
|
+
dirs.push(walkEntry);
|
|
1497
|
+
} else {
|
|
1498
|
+
onFile == null ? void 0 : onFile(walkEntry);
|
|
1499
|
+
}
|
|
1471
1500
|
}
|
|
1472
|
-
|
|
1501
|
+
if ((onDir == null ? void 0 : onDir()) !== false && --depth > 0) {
|
|
1502
|
+
for (const entry of dirs) {
|
|
1503
|
+
await walk(entry, depth);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
onExit == null ? void 0 : onExit();
|
|
1473
1507
|
}
|
|
1474
1508
|
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
}
|
|
1483
|
-
return root;
|
|
1509
|
+
await walk(
|
|
1510
|
+
{
|
|
1511
|
+
path: dir,
|
|
1512
|
+
name: path2.basename(dir)
|
|
1513
|
+
},
|
|
1514
|
+
maxDepth
|
|
1515
|
+
);
|
|
1516
|
+
};
|
|
1484
1517
|
}
|
|
1485
1518
|
|
|
1486
1519
|
// src/vite/utils/ast.ts
|
|
@@ -1539,25 +1572,39 @@ function getViteSSRExportIdentifiers(astProgramNode, exportObjectName = "__vite_
|
|
|
1539
1572
|
return result;
|
|
1540
1573
|
}
|
|
1541
1574
|
|
|
1575
|
+
// src/vite/utils/config.ts
|
|
1576
|
+
var PluginConfigKey = "__MARKO_RUN_PLUGIN_CONFIG__";
|
|
1577
|
+
var AdapterConfigKey = "__MARKO_RUN_ADAPTER_CONFIG__";
|
|
1578
|
+
function getConfig(obj, key) {
|
|
1579
|
+
return obj[key];
|
|
1580
|
+
}
|
|
1581
|
+
function setConfig(obj, key, value) {
|
|
1582
|
+
obj[key] = value;
|
|
1583
|
+
return obj;
|
|
1584
|
+
}
|
|
1585
|
+
var getExternalPluginOptions = (viteConfig) => getConfig(viteConfig, PluginConfigKey);
|
|
1586
|
+
var setExternalPluginOptions = (viteConfig, value) => setConfig(viteConfig, PluginConfigKey, value);
|
|
1587
|
+
var getExternalAdapterOptions = (viteConfig) => getConfig(viteConfig, AdapterConfigKey);
|
|
1588
|
+
var setExternalAdapterOptions = (viteConfig, value) => setConfig(viteConfig, AdapterConfigKey, value);
|
|
1589
|
+
|
|
1542
1590
|
// src/vite/utils/log.ts
|
|
1543
1591
|
import zlib from "node:zlib";
|
|
1592
|
+
import { Blob } from "buffer";
|
|
1544
1593
|
import Table from "cli-table3";
|
|
1545
|
-
import kleur from "kleur";
|
|
1546
1594
|
import format from "human-format";
|
|
1547
|
-
import
|
|
1595
|
+
import kleur2 from "kleur";
|
|
1548
1596
|
var HttpVerbColors = {
|
|
1549
|
-
get:
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
get: 0,
|
|
1557
|
-
post: 1,
|
|
1558
|
-
put: 2,
|
|
1559
|
-
delete: 3
|
|
1597
|
+
get: kleur2.green,
|
|
1598
|
+
head: kleur2.dim().green,
|
|
1599
|
+
post: kleur2.magenta,
|
|
1600
|
+
put: kleur2.cyan,
|
|
1601
|
+
delete: kleur2.red,
|
|
1602
|
+
patch: kleur2.yellow,
|
|
1603
|
+
options: kleur2.grey
|
|
1560
1604
|
};
|
|
1605
|
+
function verbColor(verb) {
|
|
1606
|
+
return verb in HttpVerbColors ? HttpVerbColors[verb] : kleur2.gray;
|
|
1607
|
+
}
|
|
1561
1608
|
function logRoutesTable(routes, bundle, options) {
|
|
1562
1609
|
function getRouteChunkName(route) {
|
|
1563
1610
|
return options.sanitizeFileName(`${route.entryName}.marko`);
|
|
@@ -1577,30 +1624,34 @@ function logRoutesTable(routes, bundle, options) {
|
|
|
1577
1624
|
headings.push("Size/GZip");
|
|
1578
1625
|
colAligns.push("right");
|
|
1579
1626
|
const table = new Table({
|
|
1580
|
-
head: headings.map((title) =>
|
|
1627
|
+
head: headings.map((title) => kleur2.bold(kleur2.white(title.toUpperCase()))),
|
|
1581
1628
|
wordWrap: true,
|
|
1582
1629
|
colAligns,
|
|
1583
1630
|
style: { compact: true }
|
|
1584
1631
|
});
|
|
1585
1632
|
for (const route of routes.list) {
|
|
1586
1633
|
for (const path6 of route.paths) {
|
|
1587
|
-
const verbs = getVerbs(route)
|
|
1588
|
-
(a, b) => HttpVerbOrder[a] - HttpVerbOrder[b]
|
|
1589
|
-
);
|
|
1634
|
+
const verbs = getVerbs(route, true);
|
|
1590
1635
|
let firstRow = true;
|
|
1591
1636
|
for (const verb of verbs) {
|
|
1592
|
-
let size = "";
|
|
1593
1637
|
const entryType = [];
|
|
1638
|
+
let size = "";
|
|
1639
|
+
let verbCell = verbColor(verb)(verb.toUpperCase());
|
|
1640
|
+
if (verb === "get" && !verbs.includes("head")) {
|
|
1641
|
+
verbCell += kleur2.dim(`,${verbColor(verb)("HEAD")}`);
|
|
1642
|
+
}
|
|
1594
1643
|
if (route.handler) {
|
|
1595
|
-
entryType.push(
|
|
1644
|
+
entryType.push(kleur2.blue("handler"));
|
|
1596
1645
|
}
|
|
1597
|
-
if (verb === "get"
|
|
1598
|
-
entryType.push(
|
|
1599
|
-
|
|
1646
|
+
if (route.page && (verb === "get" || verb === "head")) {
|
|
1647
|
+
entryType.push(kleur2.yellow("page"));
|
|
1648
|
+
if (verb === "get") {
|
|
1649
|
+
size = prettySize(
|
|
1650
|
+
computeRouteSize(getRouteChunkName(route), bundle)
|
|
1651
|
+
);
|
|
1652
|
+
}
|
|
1600
1653
|
}
|
|
1601
|
-
const row = [
|
|
1602
|
-
kleur.bold(HttpVerbColors[verb](verb.toUpperCase()))
|
|
1603
|
-
];
|
|
1654
|
+
const row = [verbCell];
|
|
1604
1655
|
if (verbs.length === 1 || firstRow) {
|
|
1605
1656
|
row.push({ rowSpan: verbs.length, content: prettyPath(path6.path) });
|
|
1606
1657
|
firstRow = false;
|
|
@@ -1614,7 +1665,7 @@ function logRoutesTable(routes, bundle, options) {
|
|
|
1614
1665
|
}
|
|
1615
1666
|
}
|
|
1616
1667
|
for (const [key, route] of Object.entries(routes.special).sort()) {
|
|
1617
|
-
const row = [
|
|
1668
|
+
const row = [kleur2.bold(kleur2.white("*")), key, kleur2.yellow("page")];
|
|
1618
1669
|
hasMiddleware && row.push("");
|
|
1619
1670
|
hasMeta && row.push("");
|
|
1620
1671
|
row.push(prettySize(computeRouteSize(getRouteChunkName(route), bundle)));
|
|
@@ -1653,27 +1704,24 @@ function computeChunkSize(chunk, bundle, seen = /* @__PURE__ */ new Set()) {
|
|
|
1653
1704
|
}
|
|
1654
1705
|
function prettySize([bytes, compBytes]) {
|
|
1655
1706
|
if (bytes <= 0) {
|
|
1656
|
-
return
|
|
1707
|
+
return kleur2.gray("0.0 kB");
|
|
1657
1708
|
}
|
|
1658
1709
|
const [size, prefix] = format(bytes, { decimals: 1 }).split(/\s+/);
|
|
1659
1710
|
const compSize = format(compBytes, { decimals: 1, prefix, unit: "B" });
|
|
1660
|
-
let str =
|
|
1661
|
-
if (compBytes < 20 * 1e3) str +=
|
|
1662
|
-
else if (compBytes < 50 * 1e3) str +=
|
|
1663
|
-
else str +=
|
|
1711
|
+
let str = kleur2.white(size) + kleur2.gray("/");
|
|
1712
|
+
if (compBytes < 20 * 1e3) str += kleur2.green(compSize);
|
|
1713
|
+
else if (compBytes < 50 * 1e3) str += kleur2.yellow(compSize);
|
|
1714
|
+
else str += kleur2.bold(kleur2.red(compSize));
|
|
1664
1715
|
return str;
|
|
1665
1716
|
}
|
|
1666
1717
|
function prettyPath(path6) {
|
|
1667
|
-
return path6.replace(/\/\$\$(.*)$/, (_, p) => "/" +
|
|
1718
|
+
return path6.replace(/\/\$\$(.*)$/, (_, p) => "/" + kleur2.bold(kleur2.dim(`*${p}`))).replace(/\/\$([^/]+)/g, (_, p) => "/" + kleur2.bold(kleur2.dim(`:${p}`)));
|
|
1668
1719
|
}
|
|
1669
1720
|
|
|
1670
|
-
// src/vite/plugin.ts
|
|
1671
|
-
import createDebug from "debug";
|
|
1672
|
-
|
|
1673
1721
|
// src/vite/utils/read-once-persisted-store.ts
|
|
1722
|
+
import { promises as fs2 } from "fs";
|
|
1674
1723
|
import os from "os";
|
|
1675
1724
|
import path3 from "path";
|
|
1676
|
-
import { promises as fs3 } from "fs";
|
|
1677
1725
|
var noop = () => {
|
|
1678
1726
|
};
|
|
1679
1727
|
var tmpFile = path3.join(os.tmpdir(), "marko-run-storage.json");
|
|
@@ -1696,13 +1744,13 @@ var ReadOncePersistedStore = class {
|
|
|
1696
1744
|
if (loadedFromDisk === true) {
|
|
1697
1745
|
throw new Error(`Value for ${uid} could not be loaded.`);
|
|
1698
1746
|
}
|
|
1699
|
-
await (loadedFromDisk || (loadedFromDisk =
|
|
1747
|
+
await (loadedFromDisk || (loadedFromDisk = fs2.readFile(tmpFile, "utf-8").then(syncDataFromDisk).catch(finishLoadFromDisk)));
|
|
1700
1748
|
return this.read();
|
|
1701
1749
|
}
|
|
1702
1750
|
};
|
|
1703
1751
|
function syncDataFromDisk(data) {
|
|
1704
1752
|
finishLoadFromDisk();
|
|
1705
|
-
|
|
1753
|
+
fs2.unlink(tmpFile).catch(noop);
|
|
1706
1754
|
for (const [k, v] of JSON.parse(data)) {
|
|
1707
1755
|
values.set(k, v);
|
|
1708
1756
|
}
|
|
@@ -1712,37 +1760,11 @@ function finishLoadFromDisk() {
|
|
|
1712
1760
|
}
|
|
1713
1761
|
process.once("beforeExit", (code) => {
|
|
1714
1762
|
if (code === 0 && values.size) {
|
|
1715
|
-
|
|
1763
|
+
fs2.writeFile(tmpFile, JSON.stringify([...values])).catch(noop);
|
|
1716
1764
|
}
|
|
1717
1765
|
});
|
|
1718
1766
|
|
|
1719
|
-
// src/adapter/utils.ts
|
|
1720
|
-
import supporsColor from "supports-color";
|
|
1721
|
-
import kleur2 from "kleur";
|
|
1722
|
-
function stripAnsi(string) {
|
|
1723
|
-
return string.replace(
|
|
1724
|
-
/([\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><])/g,
|
|
1725
|
-
""
|
|
1726
|
-
);
|
|
1727
|
-
}
|
|
1728
|
-
function cleanStack(stack) {
|
|
1729
|
-
return stack.split(/\n/).filter((l) => /^\s*at/.test(l)).join("\n");
|
|
1730
|
-
}
|
|
1731
|
-
function prepareError(err) {
|
|
1732
|
-
var _a;
|
|
1733
|
-
return {
|
|
1734
|
-
message: stripAnsi(err.message),
|
|
1735
|
-
stack: stripAnsi(cleanStack(err.stack || "")),
|
|
1736
|
-
id: err.id,
|
|
1737
|
-
frame: stripAnsi(err.frame || ""),
|
|
1738
|
-
plugin: err.plugin,
|
|
1739
|
-
pluginCode: (_a = err.pluginCode) == null ? void 0 : _a.toString(),
|
|
1740
|
-
loc: err.loc
|
|
1741
|
-
};
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
1767
|
// src/vite/plugin.ts
|
|
1745
|
-
import { createHash } from "crypto";
|
|
1746
1768
|
var debug = createDebug("@marko/run");
|
|
1747
1769
|
var __dirname = path4.dirname(fileURLToPath(import.meta.url));
|
|
1748
1770
|
var PLUGIN_NAME_PREFIX = "marko-run-vite";
|
|
@@ -1774,7 +1796,7 @@ function markoRun(opts = {}) {
|
|
|
1774
1796
|
let getExportsFromFile;
|
|
1775
1797
|
let resolvedConfig;
|
|
1776
1798
|
let typesFile;
|
|
1777
|
-
|
|
1799
|
+
const seenErrors = /* @__PURE__ */ new Set();
|
|
1778
1800
|
const virtualFiles = /* @__PURE__ */ new Map();
|
|
1779
1801
|
let times = {
|
|
1780
1802
|
routesBuild: 0,
|
|
@@ -1791,73 +1813,77 @@ function markoRun(opts = {}) {
|
|
|
1791
1813
|
normalizePath(path4.relative(typesDir, resolvedRoutesDir)),
|
|
1792
1814
|
adapter
|
|
1793
1815
|
);
|
|
1794
|
-
if (data !== typesFile || !
|
|
1816
|
+
if (data !== typesFile || !fs3.existsSync(filepath)) {
|
|
1795
1817
|
await ensureDir(typesDir);
|
|
1796
|
-
await
|
|
1818
|
+
await fs3.promises.writeFile(filepath, typesFile = data);
|
|
1797
1819
|
}
|
|
1798
1820
|
}
|
|
1799
1821
|
}
|
|
1800
1822
|
let buildVirtualFilesResult;
|
|
1801
1823
|
function buildVirtualFiles() {
|
|
1802
|
-
return buildVirtualFilesResult ?? (buildVirtualFilesResult =
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
throw new Error("No routes generated");
|
|
1811
|
-
}
|
|
1812
|
-
for (const route of routes.list) {
|
|
1813
|
-
virtualFiles.set(path4.posix.join(root, `${route.entryName}.js`), "");
|
|
1814
|
-
}
|
|
1815
|
-
if (routes.middleware.length) {
|
|
1816
|
-
virtualFiles.set(path4.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1817
|
-
}
|
|
1818
|
-
virtualFiles.set(path4.posix.join(root, ROUTER_FILENAME), "");
|
|
1819
|
-
resolve(routes);
|
|
1820
|
-
} catch (err) {
|
|
1821
|
-
reject(err);
|
|
1824
|
+
return buildVirtualFilesResult ?? (buildVirtualFilesResult = (async () => {
|
|
1825
|
+
virtualFiles.clear();
|
|
1826
|
+
routes = await buildRoutes({
|
|
1827
|
+
walker: createFSWalker(resolvedRoutesDir),
|
|
1828
|
+
importPrefix: routesDir
|
|
1829
|
+
});
|
|
1830
|
+
if (!routes.list.length) {
|
|
1831
|
+
throw new Error("No routes generated");
|
|
1822
1832
|
}
|
|
1823
|
-
|
|
1833
|
+
for (const route of routes.list) {
|
|
1834
|
+
virtualFiles.set(path4.posix.join(root, `${route.entryName}.js`), "");
|
|
1835
|
+
}
|
|
1836
|
+
if (routes.middleware.length) {
|
|
1837
|
+
virtualFiles.set(path4.posix.join(root, MIDDLEWARE_FILENAME), "");
|
|
1838
|
+
}
|
|
1839
|
+
virtualFiles.set(path4.posix.join(root, ROUTER_FILENAME), "");
|
|
1840
|
+
return routes;
|
|
1841
|
+
})());
|
|
1824
1842
|
}
|
|
1825
1843
|
let renderVirtualFilesResult;
|
|
1826
1844
|
function renderVirtualFiles(context) {
|
|
1827
|
-
return renderVirtualFilesResult ?? (renderVirtualFilesResult =
|
|
1845
|
+
return renderVirtualFilesResult ?? (renderVirtualFilesResult = (async () => {
|
|
1828
1846
|
var _a;
|
|
1829
1847
|
try {
|
|
1830
1848
|
const routes2 = await buildVirtualFiles();
|
|
1831
|
-
if (
|
|
1832
|
-
|
|
1849
|
+
if (fs3.existsSync(entryFilesDir)) {
|
|
1850
|
+
fs3.rmSync(entryFilesDir, { recursive: true });
|
|
1833
1851
|
}
|
|
1834
1852
|
for (const route of routes2.list) {
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
);
|
|
1840
|
-
route.handler.verbs = [];
|
|
1853
|
+
const { handler, page, layouts } = route;
|
|
1854
|
+
if (handler) {
|
|
1855
|
+
const exports = await getExportsFromFile(context, handler.filePath);
|
|
1856
|
+
handler.verbs = [];
|
|
1841
1857
|
for (const name of exports) {
|
|
1842
1858
|
const verb = name.toLowerCase();
|
|
1843
1859
|
if (name === verb.toUpperCase() && httpVerbs.includes(verb)) {
|
|
1844
|
-
|
|
1860
|
+
handler.verbs.push(verb);
|
|
1845
1861
|
}
|
|
1846
1862
|
}
|
|
1847
|
-
if (!
|
|
1863
|
+
if (!handler.verbs.length) {
|
|
1848
1864
|
context.warn(
|
|
1849
|
-
`Did not find any http verb exports in handler '${path4.relative(root,
|
|
1865
|
+
`Did not find any http verb exports in handler '${path4.relative(root, handler.filePath)}' - expected ${httpVerbs.map((v) => v.toUpperCase()).join(", ")}`
|
|
1850
1866
|
);
|
|
1851
1867
|
}
|
|
1852
1868
|
}
|
|
1853
|
-
if (
|
|
1854
|
-
const relativePath = path4.relative(
|
|
1869
|
+
if (page && layouts.length) {
|
|
1870
|
+
const relativePath = path4.relative(
|
|
1871
|
+
resolvedRoutesDir,
|
|
1872
|
+
page.filePath
|
|
1873
|
+
);
|
|
1855
1874
|
const routeFileDir = path4.join(entryFilesDir, relativePath, "..");
|
|
1856
|
-
const routeFileRelativePathPosix = normalizePath(
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1875
|
+
const routeFileRelativePathPosix = normalizePath(
|
|
1876
|
+
path4.relative(routeFileDir, root)
|
|
1877
|
+
);
|
|
1878
|
+
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1879
|
+
const pageNameIndex = page.name.indexOf("+page");
|
|
1880
|
+
const pageNamePrefix = pageNameIndex > 0 ? `${page.name.slice(0, pageNameIndex)}.` : "";
|
|
1881
|
+
fs3.writeFileSync(
|
|
1882
|
+
path4.join(routeFileDir, pageNamePrefix + "route.marko"),
|
|
1883
|
+
renderRouteTemplate(
|
|
1884
|
+
route,
|
|
1885
|
+
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1886
|
+
)
|
|
1861
1887
|
);
|
|
1862
1888
|
}
|
|
1863
1889
|
virtualFiles.set(
|
|
@@ -1866,14 +1892,23 @@ function markoRun(opts = {}) {
|
|
|
1866
1892
|
);
|
|
1867
1893
|
}
|
|
1868
1894
|
for (const route of Object.values(routes2.special)) {
|
|
1869
|
-
|
|
1870
|
-
|
|
1895
|
+
const { page, layouts, key } = route;
|
|
1896
|
+
if (page && layouts.length) {
|
|
1897
|
+
const relativePath = path4.relative(
|
|
1898
|
+
resolvedRoutesDir,
|
|
1899
|
+
page.filePath
|
|
1900
|
+
);
|
|
1871
1901
|
const routeFileDir = path4.join(entryFilesDir, relativePath, "..");
|
|
1872
|
-
const routeFileRelativePathPosix = normalizePath(
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1902
|
+
const routeFileRelativePathPosix = normalizePath(
|
|
1903
|
+
path4.relative(routeFileDir, root)
|
|
1904
|
+
);
|
|
1905
|
+
fs3.mkdirSync(routeFileDir, { recursive: true });
|
|
1906
|
+
fs3.writeFileSync(
|
|
1907
|
+
path4.join(routeFileDir, `route.${key}.marko`),
|
|
1908
|
+
renderRouteTemplate(
|
|
1909
|
+
route,
|
|
1910
|
+
(to) => path4.posix.join(routeFileRelativePathPosix, to)
|
|
1911
|
+
)
|
|
1877
1912
|
);
|
|
1878
1913
|
}
|
|
1879
1914
|
}
|
|
@@ -1919,8 +1954,7 @@ function markoRun(opts = {}) {
|
|
|
1919
1954
|
`throw ${JSON.stringify(prepareError(err))}`
|
|
1920
1955
|
);
|
|
1921
1956
|
}
|
|
1922
|
-
|
|
1923
|
-
}));
|
|
1957
|
+
})());
|
|
1924
1958
|
}
|
|
1925
1959
|
return [
|
|
1926
1960
|
defaultConfigPlugin,
|
|
@@ -1965,7 +1999,9 @@ function markoRun(opts = {}) {
|
|
|
1965
1999
|
createHash("shake256", { outputLength: 4 }).update(root).digest("hex")
|
|
1966
2000
|
);
|
|
1967
2001
|
entryFilesDirPosix = normalizePath(entryFilesDir);
|
|
1968
|
-
relativeEntryFilesDirPosix = normalizePath(
|
|
2002
|
+
relativeEntryFilesDirPosix = normalizePath(
|
|
2003
|
+
path4.relative(root, entryFilesDir)
|
|
2004
|
+
);
|
|
1969
2005
|
typesDir = path4.join(root, ".marko-run");
|
|
1970
2006
|
devEntryFile = path4.join(root, "index.html");
|
|
1971
2007
|
devEntryFilePosix = normalizePath(devEntryFile);
|
|
@@ -1986,7 +2022,7 @@ function markoRun(opts = {}) {
|
|
|
1986
2022
|
entryFileNames(info) {
|
|
1987
2023
|
let name = getEntryFileName(info.facadeModuleId);
|
|
1988
2024
|
if (!name) {
|
|
1989
|
-
for (
|
|
2025
|
+
for (const id of info.moduleIds) {
|
|
1990
2026
|
name = getEntryFileName(id);
|
|
1991
2027
|
if (name) {
|
|
1992
2028
|
break;
|
|
@@ -2265,15 +2301,15 @@ async function globFileExists(root, pattern) {
|
|
|
2265
2301
|
return (await glob(pattern, { root })).length > 0;
|
|
2266
2302
|
}
|
|
2267
2303
|
async function ensureDir(dir) {
|
|
2268
|
-
if (!
|
|
2269
|
-
await
|
|
2304
|
+
if (!fs3.existsSync(dir)) {
|
|
2305
|
+
await fs3.promises.mkdir(dir, { recursive: true });
|
|
2270
2306
|
}
|
|
2271
2307
|
}
|
|
2272
2308
|
async function getPackageData(dir) {
|
|
2273
2309
|
do {
|
|
2274
2310
|
const pkgPath = path4.join(dir, "package.json");
|
|
2275
|
-
if (
|
|
2276
|
-
return JSON.parse(await
|
|
2311
|
+
if (fs3.existsSync(pkgPath)) {
|
|
2312
|
+
return JSON.parse(await fs3.promises.readFile(pkgPath, "utf-8"));
|
|
2277
2313
|
}
|
|
2278
2314
|
} while (dir !== (dir = path4.dirname(dir)));
|
|
2279
2315
|
return null;
|
|
@@ -2291,7 +2327,10 @@ async function resolveAdapter(root, options, log) {
|
|
|
2291
2327
|
for (const name of dependecies) {
|
|
2292
2328
|
if (name.startsWith("@marko/run-adapter") || name.indexOf("marko-run-adapter") !== -1) {
|
|
2293
2329
|
try {
|
|
2294
|
-
const module2 = await import(
|
|
2330
|
+
const module2 = await import(
|
|
2331
|
+
/* @vite-ignore */
|
|
2332
|
+
name
|
|
2333
|
+
);
|
|
2295
2334
|
log && debug(
|
|
2296
2335
|
`Using adapter ${name} listed in your package.json dependecies`
|
|
2297
2336
|
);
|
|
@@ -2303,7 +2342,10 @@ async function resolveAdapter(root, options, log) {
|
|
|
2303
2342
|
}
|
|
2304
2343
|
}
|
|
2305
2344
|
const defaultAdapter = "@marko/run/adapter";
|
|
2306
|
-
const module = await import(
|
|
2345
|
+
const module = await import(
|
|
2346
|
+
/* @vite-ignore */
|
|
2347
|
+
defaultAdapter
|
|
2348
|
+
);
|
|
2307
2349
|
log && debug("Using default adapter");
|
|
2308
2350
|
return module.default();
|
|
2309
2351
|
}
|
|
@@ -2351,6 +2393,37 @@ var defaultConfigPlugin = {
|
|
|
2351
2393
|
}
|
|
2352
2394
|
};
|
|
2353
2395
|
|
|
2396
|
+
// src/vite/utils/server.ts
|
|
2397
|
+
import cp from "child_process";
|
|
2398
|
+
import cluster from "cluster";
|
|
2399
|
+
import { config, parse } from "dotenv";
|
|
2400
|
+
import fs4 from "fs";
|
|
2401
|
+
import net from "net";
|
|
2402
|
+
async function getConnection(port) {
|
|
2403
|
+
return new Promise((resolve) => {
|
|
2404
|
+
const connection = net.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () => {
|
|
2405
|
+
connection.end();
|
|
2406
|
+
resolve(null);
|
|
2407
|
+
}).on("connect", () => {
|
|
2408
|
+
resolve(connection);
|
|
2409
|
+
});
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
async function isPortInUse(port) {
|
|
2413
|
+
return Boolean(await getConnection(port));
|
|
2414
|
+
}
|
|
2415
|
+
async function getAvailablePort(port) {
|
|
2416
|
+
if (port && !await isPortInUse(port)) {
|
|
2417
|
+
return port;
|
|
2418
|
+
}
|
|
2419
|
+
return new Promise((resolve) => {
|
|
2420
|
+
const server = net.createServer().listen(0, () => {
|
|
2421
|
+
const { port: port2 } = server.address();
|
|
2422
|
+
server.close(() => resolve(port2));
|
|
2423
|
+
});
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2354
2427
|
// src/cli/commands.ts
|
|
2355
2428
|
var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
|
|
2356
2429
|
var defaultConfigFileBases = ["serve.config", "vite.config"];
|