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