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