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