devframe 0.9.0-beta.8 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{_shared-QkI6ljJS.d.mts → _shared-BPmX9fqK.d.mts} +1 -1
- package/dist/_shared-CbZ_yhbz.mjs +68 -0
- package/dist/adapters/build.d.mts +2 -2
- package/dist/adapters/build.mjs +6 -6
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +3 -3
- package/dist/adapters/dev.d.mts +4 -4
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +3 -3
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/cli/main.mjs +3 -3
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +22 -4
- package/dist/constants.d.mts +10 -1
- package/dist/constants.mjs +10 -1
- package/dist/{context-CQkRTbAc.d.mts → context-B3YUu_95.d.mts} +1 -1
- package/dist/{context-D0HD0F7C.mjs → context-CEe4PBz1.mjs} +7 -300
- package/dist/{context-D0jErmlx.mjs → context-xdynGSLP.mjs} +1 -1
- package/dist/{dev-QEuT8SOF.mjs → dev--rAPzbvO.mjs} +6 -6
- package/dist/{devframe-Cfx6doi4.d.mts → devframe-DJMg0WLe.d.mts} +7 -16
- package/dist/{diagnostics-hwjXp_UV.mjs → diagnostics-CD8nlgll.mjs} +1 -3
- package/dist/{diagnostics-DEuH3P5O.mjs → diagnostics-DOQPnQmX.mjs} +1 -3
- package/dist/{_shared-CKZPvSrN.mjs → dist-eNI9qM_I.mjs} +1 -67
- package/dist/{host-agent-C5HjzfBz.mjs → host-agent-xLCSe65D.mjs} +1 -1
- package/dist/{http-CVwj7b4g.mjs → http-DYpK0cUi.mjs} +4 -4
- package/dist/{index-MYi1SZVL.d.mts → index-CB-fSUyn.d.mts} +2 -2
- package/dist/index.d.mts +4 -3
- package/dist/{instance-registry-M2p-z6xE.mjs → instance-registry-WvQkt42E.mjs} +1 -1
- package/dist/{instance-shell-DJ8s-MFw.mjs → instance-shell-CMFyszWJ.mjs} +5 -5
- package/dist/{instance-shell-D_UA0Idz.d.mts → instance-shell-CljiKq1c.d.mts} +2 -2
- package/dist/internal/index.d.mts +8 -16
- package/dist/internal/index.mjs +7 -7
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +1 -1
- package/dist/node/index.mjs +2 -2
- package/dist/nostics-CzECRXpE.mjs +59 -0
- package/dist/nostics-SPGDgHEP.d.mts +33 -0
- package/dist/recipes/common-rpc-functions.d.mts +1 -1
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +2 -2
- package/dist/{remote-assets-DclsYyoL.d.mts → remote-assets-Bg4gCUZ_.d.mts} +19 -2
- package/dist/remote-assets-nTTxY2MU.mjs +636 -0
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.mjs +3 -3
- package/dist/rpc/transports/sse-client.mjs +1 -1
- package/dist/rpc/transports/sse-server.mjs +2 -2
- package/dist/rpc/transports/ws-bun.d.mts +1 -1
- package/dist/rpc/transports/ws-bun.mjs +1 -1
- package/dist/rpc/transports/ws-client.mjs +1 -1
- package/dist/rpc/transports/ws-server.mjs +1 -1
- package/dist/{rpc-core-C8JQ3p7A.d.mts → rpc-core-Cc4lucI0.d.mts} +2 -2
- package/dist/{rpc-core-IhcWl_xn.mjs → rpc-core-DMTe-hLo.mjs} +1 -1
- package/dist/{serialization-BHY8M5NQ.mjs → serialization-BGzEwAdr.mjs} +1 -1
- package/dist/{static-CvjkO8QE.mjs → static-BPZ1_OPA.mjs} +2 -2
- package/dist/{storage-BVuipbGS.mjs → storage-CYye7P7L.mjs} +1 -1
- package/dist/types/index.d.mts +4 -3
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/get-port.d.mts +17 -0
- package/dist/utils/get-port.mjs +2 -0
- package/dist/utils/nostics.d.mts +2 -0
- package/dist/utils/nostics.mjs +2 -0
- package/dist/utils/remote-assets.d.mts +1 -1
- package/dist/utils/remote-assets.mjs +1 -308
- package/dist/utils/serve-static.d.mts +1 -1
- package/dist/utils/serve-static.mjs +16 -0
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{validation-BiuDXTKW.mjs → validation-CpXFB6Dz.mjs} +1 -1
- package/dist/{wire-codec-9VhIKnyp.mjs → wire-codec-0K-o5MYW.mjs} +1 -3
- package/dist/{ws-server-Bk1hOG3X.mjs → ws-server-BdSLrhxE.mjs} +1 -1
- package/package.json +3 -1
- package/dist/diagnostics-reporter-CsIG85Q5.mjs +0 -38
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
import { t as diagnostics } from "./diagnostics-DOQPnQmX.mjs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { isatty } from "node:tty";
|
|
4
|
+
import { formatWithOptions, inspect } from "node:util";
|
|
5
|
+
import { createReadStream, existsSync } from "node:fs";
|
|
6
|
+
import { Buffer } from "node:buffer";
|
|
7
|
+
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
8
|
+
import { Readable } from "node:stream";
|
|
9
|
+
import { lookup } from "mrmime";
|
|
10
|
+
import { dirname, extname, join, normalize, sep } from "pathe";
|
|
11
|
+
//#region ../../node_modules/.pnpm/obug@2.1.4/node_modules/obug/dist/core.js
|
|
12
|
+
/**
|
|
13
|
+
* Coerce `value`.
|
|
14
|
+
*/
|
|
15
|
+
function coerce(value) {
|
|
16
|
+
if (value instanceof Error) return value.stack || value.message;
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Selects a color for a debug namespace
|
|
21
|
+
* @return An ANSI color code for the given namespace
|
|
22
|
+
*/
|
|
23
|
+
function selectColor(colors, namespace) {
|
|
24
|
+
let hash = 0;
|
|
25
|
+
for (let i = 0; i < namespace.length; i++) {
|
|
26
|
+
hash = (hash << 5) - hash + namespace.charCodeAt(i);
|
|
27
|
+
hash |= 0;
|
|
28
|
+
}
|
|
29
|
+
return colors[Math.abs(hash) % colors.length];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks if the given string matches a namespace template, honoring
|
|
33
|
+
* asterisks as wildcards.
|
|
34
|
+
*/
|
|
35
|
+
function matchesTemplate(search, template) {
|
|
36
|
+
let searchIndex = 0;
|
|
37
|
+
let templateIndex = 0;
|
|
38
|
+
let starIndex = -1;
|
|
39
|
+
let matchIndex = 0;
|
|
40
|
+
while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) if (template[templateIndex] === "*") {
|
|
41
|
+
starIndex = templateIndex;
|
|
42
|
+
matchIndex = searchIndex;
|
|
43
|
+
templateIndex++;
|
|
44
|
+
} else {
|
|
45
|
+
searchIndex++;
|
|
46
|
+
templateIndex++;
|
|
47
|
+
}
|
|
48
|
+
else if (starIndex !== -1) {
|
|
49
|
+
templateIndex = starIndex + 1;
|
|
50
|
+
matchIndex++;
|
|
51
|
+
searchIndex = matchIndex;
|
|
52
|
+
} else return false;
|
|
53
|
+
while (templateIndex < template.length && template[templateIndex] === "*") templateIndex++;
|
|
54
|
+
return templateIndex === template.length;
|
|
55
|
+
}
|
|
56
|
+
function humanize(value) {
|
|
57
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}s`;
|
|
58
|
+
return `${value}ms`;
|
|
59
|
+
}
|
|
60
|
+
let globalNamespaces = "";
|
|
61
|
+
function createDebug$1(namespace, options) {
|
|
62
|
+
let prevTime;
|
|
63
|
+
let enableOverride;
|
|
64
|
+
let namespacesCache;
|
|
65
|
+
let enabledCache;
|
|
66
|
+
const debug = (...args) => {
|
|
67
|
+
if (!debug.enabled) return;
|
|
68
|
+
const curr = Date.now();
|
|
69
|
+
const diff = curr - (prevTime || curr);
|
|
70
|
+
prevTime = curr;
|
|
71
|
+
args[0] = coerce(args[0]);
|
|
72
|
+
if (typeof args[0] !== "string") args.unshift("%O");
|
|
73
|
+
let index = 0;
|
|
74
|
+
args[0] = args[0].replace(/%([a-z%])/gi, (match, format) => {
|
|
75
|
+
if (match === "%%") return "%";
|
|
76
|
+
index++;
|
|
77
|
+
const formatter = options.formatters[format];
|
|
78
|
+
if (typeof formatter === "function") {
|
|
79
|
+
const value = args[index];
|
|
80
|
+
match = formatter.call(debug, value);
|
|
81
|
+
args.splice(index, 1);
|
|
82
|
+
index--;
|
|
83
|
+
}
|
|
84
|
+
return match;
|
|
85
|
+
});
|
|
86
|
+
options.formatArgs.call(debug, diff, args);
|
|
87
|
+
debug.log(...args);
|
|
88
|
+
};
|
|
89
|
+
debug.extend = function(namespace, delimiter = ":") {
|
|
90
|
+
return createDebug$1(this.namespace + delimiter + namespace, {
|
|
91
|
+
useColors: this.useColors,
|
|
92
|
+
color: this.color,
|
|
93
|
+
formatArgs: this.formatArgs,
|
|
94
|
+
formatters: this.formatters,
|
|
95
|
+
inspectOpts: this.inspectOpts,
|
|
96
|
+
log: this.log,
|
|
97
|
+
humanize: this.humanize
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
Object.assign(debug, options);
|
|
101
|
+
debug.namespace = namespace;
|
|
102
|
+
Object.defineProperty(debug, "enabled", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: false,
|
|
105
|
+
get: () => {
|
|
106
|
+
if (enableOverride != null) return enableOverride;
|
|
107
|
+
if (namespacesCache !== globalNamespaces) {
|
|
108
|
+
namespacesCache = globalNamespaces;
|
|
109
|
+
enabledCache = enabled(namespace);
|
|
110
|
+
}
|
|
111
|
+
return enabledCache;
|
|
112
|
+
},
|
|
113
|
+
set: (v) => {
|
|
114
|
+
enableOverride = v;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return debug;
|
|
118
|
+
}
|
|
119
|
+
let names = [];
|
|
120
|
+
let skips = [];
|
|
121
|
+
function enable(namespaces) {
|
|
122
|
+
globalNamespaces = namespaces;
|
|
123
|
+
names = [];
|
|
124
|
+
skips = [];
|
|
125
|
+
const split = globalNamespaces.trim().replace(/\s+/g, ",").split(",").filter(Boolean);
|
|
126
|
+
for (const ns of split) if (ns[0] === "-") skips.push(ns.slice(1));
|
|
127
|
+
else names.push(ns);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns true if the given mode name is enabled, false otherwise.
|
|
131
|
+
*/
|
|
132
|
+
function enabled(name) {
|
|
133
|
+
for (const skip of skips) if (matchesTemplate(name, skip)) return false;
|
|
134
|
+
for (const ns of names) if (matchesTemplate(name, ns)) return true;
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region ../../node_modules/.pnpm/obug@2.1.4/node_modules/obug/dist/node.js
|
|
139
|
+
let env = {};
|
|
140
|
+
try {
|
|
141
|
+
process.env.DEBUG;
|
|
142
|
+
env = process.env;
|
|
143
|
+
} catch (_unused) {}
|
|
144
|
+
const colors = process.stderr.getColorDepth && process.stderr.getColorDepth(env) > 2 ? [
|
|
145
|
+
20,
|
|
146
|
+
21,
|
|
147
|
+
26,
|
|
148
|
+
27,
|
|
149
|
+
32,
|
|
150
|
+
33,
|
|
151
|
+
38,
|
|
152
|
+
39,
|
|
153
|
+
40,
|
|
154
|
+
41,
|
|
155
|
+
42,
|
|
156
|
+
43,
|
|
157
|
+
44,
|
|
158
|
+
45,
|
|
159
|
+
56,
|
|
160
|
+
57,
|
|
161
|
+
62,
|
|
162
|
+
63,
|
|
163
|
+
68,
|
|
164
|
+
69,
|
|
165
|
+
74,
|
|
166
|
+
75,
|
|
167
|
+
76,
|
|
168
|
+
77,
|
|
169
|
+
78,
|
|
170
|
+
79,
|
|
171
|
+
80,
|
|
172
|
+
81,
|
|
173
|
+
92,
|
|
174
|
+
93,
|
|
175
|
+
98,
|
|
176
|
+
99,
|
|
177
|
+
112,
|
|
178
|
+
113,
|
|
179
|
+
128,
|
|
180
|
+
129,
|
|
181
|
+
134,
|
|
182
|
+
135,
|
|
183
|
+
148,
|
|
184
|
+
149,
|
|
185
|
+
160,
|
|
186
|
+
161,
|
|
187
|
+
162,
|
|
188
|
+
163,
|
|
189
|
+
164,
|
|
190
|
+
165,
|
|
191
|
+
166,
|
|
192
|
+
167,
|
|
193
|
+
168,
|
|
194
|
+
169,
|
|
195
|
+
170,
|
|
196
|
+
171,
|
|
197
|
+
172,
|
|
198
|
+
173,
|
|
199
|
+
178,
|
|
200
|
+
179,
|
|
201
|
+
184,
|
|
202
|
+
185,
|
|
203
|
+
196,
|
|
204
|
+
197,
|
|
205
|
+
198,
|
|
206
|
+
199,
|
|
207
|
+
200,
|
|
208
|
+
201,
|
|
209
|
+
202,
|
|
210
|
+
203,
|
|
211
|
+
204,
|
|
212
|
+
205,
|
|
213
|
+
206,
|
|
214
|
+
207,
|
|
215
|
+
208,
|
|
216
|
+
209,
|
|
217
|
+
214,
|
|
218
|
+
215,
|
|
219
|
+
220,
|
|
220
|
+
221
|
|
221
|
+
] : [
|
|
222
|
+
6,
|
|
223
|
+
2,
|
|
224
|
+
3,
|
|
225
|
+
4,
|
|
226
|
+
5,
|
|
227
|
+
1
|
|
228
|
+
];
|
|
229
|
+
const inspectOpts = Object.keys(env).filter((key) => /^debug_/i.test(key)).reduce((obj, key) => {
|
|
230
|
+
const prop = key.slice(6).toLowerCase().replace(/_([a-z])/g, (_, k) => k.toUpperCase());
|
|
231
|
+
let value = env[key];
|
|
232
|
+
const lowerCase = typeof value === "string" && value.toLowerCase();
|
|
233
|
+
if (value === "null") value = null;
|
|
234
|
+
else if (lowerCase === "yes" || lowerCase === "on" || lowerCase === "true" || lowerCase === "enabled") value = true;
|
|
235
|
+
else if (lowerCase === "no" || lowerCase === "off" || lowerCase === "false" || lowerCase === "disabled") value = false;
|
|
236
|
+
else value = Number(value);
|
|
237
|
+
obj[prop] = value;
|
|
238
|
+
return obj;
|
|
239
|
+
}, Object.create(null));
|
|
240
|
+
/**
|
|
241
|
+
* Is stdout a TTY? Colored output is enabled when `true`.
|
|
242
|
+
*/
|
|
243
|
+
function useColors() {
|
|
244
|
+
return "colors" in inspectOpts ? Boolean(inspectOpts.colors) : isatty(process.stderr.fd);
|
|
245
|
+
}
|
|
246
|
+
function getDate() {
|
|
247
|
+
if (inspectOpts.hideDate) return "";
|
|
248
|
+
return `${(/* @__PURE__ */ new Date()).toISOString()} `;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Adds ANSI color escape codes if enabled.
|
|
252
|
+
*/
|
|
253
|
+
function formatArgs(diff, args) {
|
|
254
|
+
const { namespace: name, useColors } = this;
|
|
255
|
+
if (useColors) {
|
|
256
|
+
const c = this.color;
|
|
257
|
+
const colorCode = `\u001B[3${c < 8 ? c : `8;5;${c}`}`;
|
|
258
|
+
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
|
|
259
|
+
args[0] = prefix + args[0].split("\n").join(`\n${prefix}`);
|
|
260
|
+
args.push(`${colorCode}m+${this.humanize(diff)}\u001B[0m`);
|
|
261
|
+
} else args[0] = `${getDate()}${name} ${args[0]}`;
|
|
262
|
+
}
|
|
263
|
+
function log(...args) {
|
|
264
|
+
process.stderr.write(`${formatWithOptions(this.inspectOpts, ...args)}\n`);
|
|
265
|
+
}
|
|
266
|
+
const defaultOptions = {
|
|
267
|
+
useColors: useColors(),
|
|
268
|
+
formatArgs,
|
|
269
|
+
formatters: {
|
|
270
|
+
/**
|
|
271
|
+
* Map %o to `util.inspect()`, all on a single line.
|
|
272
|
+
*/
|
|
273
|
+
o(v) {
|
|
274
|
+
this.inspectOpts.colors = this.useColors;
|
|
275
|
+
return inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" ");
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* Map %O to `util.inspect()`, allowing multiple lines if needed.
|
|
279
|
+
*/
|
|
280
|
+
O(v) {
|
|
281
|
+
this.inspectOpts.colors = this.useColors;
|
|
282
|
+
return inspect(v, this.inspectOpts);
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
inspectOpts,
|
|
286
|
+
log,
|
|
287
|
+
humanize
|
|
288
|
+
};
|
|
289
|
+
function createDebug(namespace, options) {
|
|
290
|
+
var _ref;
|
|
291
|
+
const color = (_ref = options && options.color) !== null && _ref !== void 0 ? _ref : selectColor(colors, namespace);
|
|
292
|
+
return createDebug$1(namespace, Object.assign(defaultOptions, { color }, options));
|
|
293
|
+
}
|
|
294
|
+
enable(env.DEBUG || "");
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/utils/remote-assets.ts
|
|
297
|
+
const debugFetch = createDebug("devframe:remote-assets:fetch");
|
|
298
|
+
const debugCache = createDebug("devframe:remote-assets:cache");
|
|
299
|
+
const MANIFEST_FILENAME = ".manifest.json";
|
|
300
|
+
/**
|
|
301
|
+
* Upstream response headers replayed to the browser. Everything outside this
|
|
302
|
+
* list is dropped, because it describes the *provider's* transfer rather than
|
|
303
|
+
* the file: hop-by-hop and encoding headers no longer match the body `fetch`
|
|
304
|
+
* already decoded, and a CDN's policy headers (`set-cookie`, `cache-control`,
|
|
305
|
+
* framing/CSP) belong to its origin — replaying them under the dev server's
|
|
306
|
+
* origin could just as well break the iframe these assets render in.
|
|
307
|
+
*/
|
|
308
|
+
const PROXIED_HEADERS = [
|
|
309
|
+
"content-language",
|
|
310
|
+
"etag",
|
|
311
|
+
"last-modified"
|
|
312
|
+
];
|
|
313
|
+
const CACHE_CONTROL_HEADER = "no-store";
|
|
314
|
+
/** Flatten a jsDelivr (`name`/`files`) or unpkg (`path`/`files`) file tree. */
|
|
315
|
+
function flattenTree(nodes, style) {
|
|
316
|
+
const out = [];
|
|
317
|
+
const walk = (list, prefix) => {
|
|
318
|
+
for (const node of list) if (style === "path") if (node.type === "file") out.push((node.path ?? "").replace(/^\//, ""));
|
|
319
|
+
else walk(node.files ?? [], "");
|
|
320
|
+
else if (node.type === "file") out.push(prefix + (node.name ?? ""));
|
|
321
|
+
else if (node.files) walk(node.files, `${prefix}${node.name}/`);
|
|
322
|
+
};
|
|
323
|
+
walk(nodes, "");
|
|
324
|
+
return out;
|
|
325
|
+
}
|
|
326
|
+
const providers = {
|
|
327
|
+
jsdelivr: {
|
|
328
|
+
fileUrl: (pkg, version, filePath) => `https://cdn.jsdelivr.net/npm/${pkg}@${version}/${filePath}`,
|
|
329
|
+
listFiles: async (pkg, version, fetchImpl) => {
|
|
330
|
+
const url = `https://data.jsdelivr.com/v1/packages/npm/${pkg}@${version}`;
|
|
331
|
+
debugFetch("listing files for %s@%s from %s", pkg, version, url);
|
|
332
|
+
const res = await fetchImpl(url);
|
|
333
|
+
if (!res.ok) throw new Error(`HTTP ${res.status} from ${url}`);
|
|
334
|
+
return flattenTree((await res.json()).files ?? [], "name");
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
unpkg: {
|
|
338
|
+
fileUrl: (pkg, version, filePath) => `https://unpkg.com/${pkg}@${version}/${filePath}`,
|
|
339
|
+
listFiles: async (pkg, version, fetchImpl) => {
|
|
340
|
+
const url = `https://unpkg.com/${pkg}@${version}/?meta`;
|
|
341
|
+
debugFetch("listing files for %s@%s from %s", pkg, version, url);
|
|
342
|
+
const res = await fetchImpl(url);
|
|
343
|
+
if (!res.ok) throw new Error(`HTTP ${res.status} from ${url}`);
|
|
344
|
+
return flattenTree([await res.json()], "path");
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
function resolveProvider(assets) {
|
|
349
|
+
const p = assets.provider ?? "jsdelivr";
|
|
350
|
+
return typeof p === "string" ? {
|
|
351
|
+
provider: providers[p],
|
|
352
|
+
name: p
|
|
353
|
+
} : {
|
|
354
|
+
provider: p,
|
|
355
|
+
name: "custom"
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Resolve a locally installed copy of `assets.package` from
|
|
360
|
+
* `assets.resolveFrom`'s dependency graph and return its assets directory,
|
|
361
|
+
* or `undefined` when the package (or directory) is absent. A different
|
|
362
|
+
* installed version warns (`DF0062`); a different major throws (`DF0061`).
|
|
363
|
+
*/
|
|
364
|
+
function resolveInstalled(assets) {
|
|
365
|
+
if (assets.resolveFrom == null) return void 0;
|
|
366
|
+
let pkgJsonPath;
|
|
367
|
+
let installed;
|
|
368
|
+
try {
|
|
369
|
+
const requireFrom = createRequire(assets.resolveFrom);
|
|
370
|
+
pkgJsonPath = requireFrom.resolve(`${assets.package}/package.json`);
|
|
371
|
+
installed = requireFrom(`${assets.package}/package.json`).version;
|
|
372
|
+
} catch {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (typeof installed !== "string") return void 0;
|
|
376
|
+
if (installed !== assets.version) {
|
|
377
|
+
const major = (v) => v.trim().split(".")[0] ?? v;
|
|
378
|
+
if (major(installed) !== major(assets.version)) throw diagnostics.DF0061({
|
|
379
|
+
package: assets.package,
|
|
380
|
+
required: assets.version,
|
|
381
|
+
installed
|
|
382
|
+
});
|
|
383
|
+
diagnostics.DF0062({
|
|
384
|
+
package: assets.package,
|
|
385
|
+
required: assets.version,
|
|
386
|
+
installed
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
const dir = join(dirname(pkgJsonPath), assets.path ?? "dist");
|
|
390
|
+
return existsSync(dir) ? dir : void 0;
|
|
391
|
+
}
|
|
392
|
+
function contentTypeFor(filePath) {
|
|
393
|
+
const type = lookup(filePath);
|
|
394
|
+
if (!type) return "application/octet-stream";
|
|
395
|
+
return type === "text/html" ? "text/html; charset=utf-8" : type;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Headers for a file streamed through from the provider. `Content-Type` and
|
|
399
|
+
* `Cache-Control` are ours, so a file looks identical whether it came from the
|
|
400
|
+
* provider or from the cache ({@link createStore}'s `serveCached`).
|
|
401
|
+
*/
|
|
402
|
+
function proxyHeaders(filePath, upstream) {
|
|
403
|
+
const headers = new Headers({
|
|
404
|
+
"Content-Type": contentTypeFor(filePath),
|
|
405
|
+
"Cache-Control": CACHE_CONTROL_HEADER
|
|
406
|
+
});
|
|
407
|
+
const encoding = upstream.get("content-encoding");
|
|
408
|
+
const length = upstream.get("content-length");
|
|
409
|
+
if (length && (!encoding || encoding === "identity")) headers.set("Content-Length", length);
|
|
410
|
+
for (const name of PROXIED_HEADERS) {
|
|
411
|
+
const value = upstream.get(name);
|
|
412
|
+
if (value != null) headers.set(name, value);
|
|
413
|
+
}
|
|
414
|
+
return headers;
|
|
415
|
+
}
|
|
416
|
+
/** Clean a request path into a safe package-relative POSIX path, or `null` if it escapes root. */
|
|
417
|
+
function cleanRequestPath(urlPath) {
|
|
418
|
+
let cleaned;
|
|
419
|
+
try {
|
|
420
|
+
cleaned = decodeURIComponent(urlPath || "/");
|
|
421
|
+
} catch {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
cleaned = cleaned.replace(/[?#].*$/, "").replace(/^\/+|\/+$/g, "");
|
|
425
|
+
const normalized = normalize(cleaned);
|
|
426
|
+
if (normalized === ".." || normalized.startsWith(`..${sep}`) || normalized.startsWith("/")) return null;
|
|
427
|
+
return normalized === "." ? "" : normalized;
|
|
428
|
+
}
|
|
429
|
+
/** Candidate files for a request, in order: direct hit, index, `.html`, SPA fallback. */
|
|
430
|
+
function candidatePaths(prefix, cleaned) {
|
|
431
|
+
const candidates = [];
|
|
432
|
+
if (cleaned) candidates.push(prefix + cleaned);
|
|
433
|
+
candidates.push(`${prefix}${cleaned ? `${cleaned}/` : ""}index.html`);
|
|
434
|
+
if (cleaned && !extname(cleaned)) candidates.push(`${prefix + cleaned}.html`);
|
|
435
|
+
if (!/\.[a-z0-9]+$/i.test(cleaned) && !candidates.includes(`${prefix}index.html`)) candidates.push(`${prefix}index.html`);
|
|
436
|
+
return candidates;
|
|
437
|
+
}
|
|
438
|
+
function createStore(assets, cacheDir) {
|
|
439
|
+
const normalized = {
|
|
440
|
+
...assets,
|
|
441
|
+
path: assets.path ?? "dist"
|
|
442
|
+
};
|
|
443
|
+
const { provider, name: providerName } = resolveProvider(assets);
|
|
444
|
+
const fetchImpl = assets.fetch ?? globalThis.fetch;
|
|
445
|
+
const prefix = `${normalized.path}/`;
|
|
446
|
+
let manifestPromise;
|
|
447
|
+
let manifestReported = false;
|
|
448
|
+
async function loadManifest() {
|
|
449
|
+
const manifestFile = join(cacheDir, MANIFEST_FILENAME);
|
|
450
|
+
if (existsSync(manifestFile)) try {
|
|
451
|
+
return new Set(JSON.parse(await readFile(manifestFile, "utf8")));
|
|
452
|
+
} catch {}
|
|
453
|
+
if (assets.offline || !provider.listFiles) return null;
|
|
454
|
+
try {
|
|
455
|
+
const files = await provider.listFiles(normalized.package, normalized.version, fetchImpl);
|
|
456
|
+
await mkdir(cacheDir, { recursive: true });
|
|
457
|
+
await writeFile(manifestFile, JSON.stringify(files), "utf8").catch(() => {});
|
|
458
|
+
return new Set(files);
|
|
459
|
+
} catch (error) {
|
|
460
|
+
if (!manifestReported) {
|
|
461
|
+
manifestReported = true;
|
|
462
|
+
diagnostics.DF0059({
|
|
463
|
+
package: normalized.package,
|
|
464
|
+
version: normalized.version,
|
|
465
|
+
provider: providerName,
|
|
466
|
+
reason: errText(error),
|
|
467
|
+
cause: error
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
async function serveCached(filePath) {
|
|
474
|
+
const abs = join(cacheDir, filePath);
|
|
475
|
+
let size;
|
|
476
|
+
try {
|
|
477
|
+
const s = await stat(abs);
|
|
478
|
+
if (!s.isFile()) return null;
|
|
479
|
+
size = s.size;
|
|
480
|
+
} catch {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
debugCache("serving %s from cache (%d bytes)", filePath, size);
|
|
484
|
+
return new Response(Readable.toWeb(createReadStream(abs)), { headers: {
|
|
485
|
+
"Content-Type": contentTypeFor(filePath),
|
|
486
|
+
"Content-Length": String(size),
|
|
487
|
+
"Cache-Control": CACHE_CONTROL_HEADER
|
|
488
|
+
} });
|
|
489
|
+
}
|
|
490
|
+
/** Persist `body` to the cache at `filePath` (tmp + rename); failures warn (`DF0063`). */
|
|
491
|
+
async function persist(filePath, body) {
|
|
492
|
+
const target = join(cacheDir, filePath);
|
|
493
|
+
const tmp = `${target}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
494
|
+
try {
|
|
495
|
+
await mkdir(dirname(target), { recursive: true });
|
|
496
|
+
await writeFile(tmp, Buffer.from(await new Response(body).arrayBuffer()));
|
|
497
|
+
await rename(tmp, target);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
await rm(tmp, { force: true }).catch(() => {});
|
|
500
|
+
diagnostics.DF0063({
|
|
501
|
+
filepath: target,
|
|
502
|
+
reason: errText(error),
|
|
503
|
+
cause: error
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/** Fetch `filePath` through the provider: `null` on 404, a `Response` on 200, throws (`DF0060`) otherwise. */
|
|
508
|
+
async function serveRemote(filePath) {
|
|
509
|
+
const url = provider.fileUrl(normalized.package, normalized.version, filePath);
|
|
510
|
+
let res;
|
|
511
|
+
try {
|
|
512
|
+
debugFetch("fetching %s from %s", filePath, url);
|
|
513
|
+
res = await fetchImpl(url);
|
|
514
|
+
} catch (error) {
|
|
515
|
+
throw diagnostics.DF0060({
|
|
516
|
+
url,
|
|
517
|
+
package: normalized.package,
|
|
518
|
+
reason: errText(error),
|
|
519
|
+
cause: error
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
if (res.status === 404) {
|
|
523
|
+
await res.body?.cancel().catch(() => {});
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
if (!res.ok || !res.body) {
|
|
527
|
+
await res.body?.cancel().catch(() => {});
|
|
528
|
+
throw diagnostics.DF0060({
|
|
529
|
+
url,
|
|
530
|
+
package: normalized.package,
|
|
531
|
+
reason: `HTTP ${res.status}`
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
const [toClient, toCache] = res.body.tee();
|
|
535
|
+
persist(filePath, toCache);
|
|
536
|
+
return new Response(toClient, {
|
|
537
|
+
status: res.status,
|
|
538
|
+
statusText: res.statusText,
|
|
539
|
+
headers: proxyHeaders(filePath, res.headers)
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
async function serve(urlPath) {
|
|
543
|
+
const cleaned = cleanRequestPath(urlPath);
|
|
544
|
+
if (cleaned === null) return null;
|
|
545
|
+
const candidates = candidatePaths(prefix, cleaned);
|
|
546
|
+
manifestPromise ??= loadManifest();
|
|
547
|
+
const manifest = await manifestPromise;
|
|
548
|
+
if (manifest) {
|
|
549
|
+
const filePath = candidates.find((c) => manifest.has(c));
|
|
550
|
+
if (!filePath) return null;
|
|
551
|
+
return await serveCached(filePath) ?? (assets.offline ? Promise.reject(diagnostics.DF0060({
|
|
552
|
+
url: filePath,
|
|
553
|
+
package: normalized.package,
|
|
554
|
+
reason: "offline: true and the file is not in the cache"
|
|
555
|
+
})) : serveRemote(filePath));
|
|
556
|
+
}
|
|
557
|
+
for (const candidate of candidates) {
|
|
558
|
+
const cached = await serveCached(candidate);
|
|
559
|
+
if (cached) return cached;
|
|
560
|
+
}
|
|
561
|
+
if (assets.offline) return null;
|
|
562
|
+
for (const candidate of candidates) {
|
|
563
|
+
const remote = await serveRemote(candidate);
|
|
564
|
+
if (remote) return remote;
|
|
565
|
+
}
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
async function materialize(targetDir) {
|
|
569
|
+
const fail = (reason, cause) => {
|
|
570
|
+
throw diagnostics.DF0064({
|
|
571
|
+
package: normalized.package,
|
|
572
|
+
version: normalized.version,
|
|
573
|
+
reason,
|
|
574
|
+
cause
|
|
575
|
+
});
|
|
576
|
+
};
|
|
577
|
+
if (!provider.listFiles) fail("the configured provider has no file listing (`listFiles`)");
|
|
578
|
+
let files;
|
|
579
|
+
try {
|
|
580
|
+
files = await provider.listFiles(normalized.package, normalized.version, fetchImpl);
|
|
581
|
+
} catch (error) {
|
|
582
|
+
return fail(errText(error), error);
|
|
583
|
+
}
|
|
584
|
+
for (const filePath of files.filter((f) => f.startsWith(prefix))) {
|
|
585
|
+
const target = join(targetDir, filePath.slice(prefix.length));
|
|
586
|
+
const url = provider.fileUrl(normalized.package, normalized.version, filePath);
|
|
587
|
+
let res;
|
|
588
|
+
try {
|
|
589
|
+
res = await fetchImpl(url);
|
|
590
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
591
|
+
} catch (error) {
|
|
592
|
+
return fail(`failed to download ${filePath}: ${errText(error)}`, error);
|
|
593
|
+
}
|
|
594
|
+
await mkdir(dirname(target), { recursive: true });
|
|
595
|
+
await writeFile(target, Buffer.from(await res.arrayBuffer()));
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return {
|
|
599
|
+
assets: normalized,
|
|
600
|
+
serve,
|
|
601
|
+
materialize
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function errText(error) {
|
|
605
|
+
return error instanceof Error ? error.message : String(error);
|
|
606
|
+
}
|
|
607
|
+
const PACKAGE_NAME_RE = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
608
|
+
const VERSION_RE = /^\d+\.\d+\.\d+(?:-[a-z0-9-]+(?:\.[a-z0-9-]+)*)?(?:\+[a-z0-9-]+(?:\.[a-z0-9-]+)*)?$/i;
|
|
609
|
+
/** Reject a {@link RemoteAssets} with an unsafe package name or version (`DF0065`). */
|
|
610
|
+
function assertValidRemoteAssets(assets) {
|
|
611
|
+
if (assets.package.length > 214 || !PACKAGE_NAME_RE.test(assets.package)) throw diagnostics.DF0065({
|
|
612
|
+
field: "package",
|
|
613
|
+
value: assets.package
|
|
614
|
+
});
|
|
615
|
+
if (!VERSION_RE.test(assets.version)) throw diagnostics.DF0065({
|
|
616
|
+
field: "version",
|
|
617
|
+
value: assets.version
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Normalize a {@link StaticAssetsSource} into something servable: a local
|
|
622
|
+
* directory (strings pass through; a remote source short-circuits to a
|
|
623
|
+
* locally installed copy of its package when present) or a caching
|
|
624
|
+
* {@link RemoteAssetsStore} back-proxy. Remote caches live under
|
|
625
|
+
* `<projectStorageDir>/.remote-assets/<package>@<version>/`.
|
|
626
|
+
*
|
|
627
|
+
* A remote source's `package`/`version` are validated first (`DF0065`) — both
|
|
628
|
+
* are interpolated into CDN URLs and the cache path.
|
|
629
|
+
*/
|
|
630
|
+
function resolveStaticAssetsSource(source, projectStorageDir) {
|
|
631
|
+
if (typeof source === "string") return source;
|
|
632
|
+
assertValidRemoteAssets(source);
|
|
633
|
+
return resolveInstalled(source) ?? createStore(source, join(projectStorageDir, ".remote-assets", `${source.package.replace(/\//g, "+")}@${source.version}`));
|
|
634
|
+
}
|
|
635
|
+
//#endregion
|
|
636
|
+
export { createDebug as n, resolveStaticAssetsSource as t };
|
package/dist/rpc/dump.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as reviveDumpError, i as getDefinitionsWithDumps, n as createClientFromDump, o as serializeDumpError, r as dumpFunctions, t as collectStaticRpcDump } from "../static-
|
|
1
|
+
import { a as reviveDumpError, i as getDefinitionsWithDumps, n as createClientFromDump, o as serializeDumpError, r as dumpFunctions, t as collectStaticRpcDump } from "../static-BPZ1_OPA.mjs";
|
|
2
2
|
export { collectStaticRpcDump, createClientFromDump, dumpFunctions, getDefinitionsWithDumps, reviveDumpError, serializeDumpError };
|
package/dist/rpc/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as validateRpcArgs, i as getRpcResolvedSetupResult, n as validateDefinitions, o as validateRpcReturn, r as getRpcHandler, s as hash, t as validateDefinition } from "../validation-
|
|
2
|
-
import { t as diagnostics } from "../diagnostics-
|
|
1
|
+
import { a as validateRpcArgs, i as getRpcResolvedSetupResult, n as validateDefinitions, o as validateRpcReturn, r as getRpcHandler, s as hash, t as validateDefinition } from "../validation-CpXFB6Dz.mjs";
|
|
2
|
+
import { t as diagnostics } from "../diagnostics-CD8nlgll.mjs";
|
|
3
3
|
import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-BLWPsH6y.mjs";
|
|
4
|
-
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-
|
|
4
|
+
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-BGzEwAdr.mjs";
|
|
5
5
|
//#region src/rpc/cache.ts
|
|
6
6
|
/**
|
|
7
7
|
* @experimental API is expected to change.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_SSE_SESSION_HEADER } from "../../constants.mjs";
|
|
2
|
-
import { t as createRpcWireCodec } from "../../wire-codec-
|
|
2
|
+
import { t as createRpcWireCodec } from "../../wire-codec-0K-o5MYW.mjs";
|
|
3
3
|
//#region src/rpc/transports/sse-client.ts
|
|
4
4
|
function NOOP() {}
|
|
5
5
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEVFRAME_SSE_SESSION_HEADER } from "../../constants.mjs";
|
|
2
|
-
import { n as peekRpcWireFrame, t as createRpcWireCodec } from "../../wire-codec-
|
|
3
|
-
import { i as isAllowedOrigin, o as createRpcSessionMeta } from "../../ws-server-
|
|
2
|
+
import { n as peekRpcWireFrame, t as createRpcWireCodec } from "../../wire-codec-0K-o5MYW.mjs";
|
|
3
|
+
import { i as isAllowedOrigin, o as createRpcSessionMeta } from "../../ws-server-BdSLrhxE.mjs";
|
|
4
4
|
//#region src/rpc/transports/sse-server.ts
|
|
5
5
|
const SSE_STREAM_HEADERS = {
|
|
6
6
|
"content-type": "text/event-stream",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as WsOriginRegistry } from "../../ws-server-D1d3QM9f.mjs";
|
|
2
|
-
import { t as ContextRpcServer } from "../../rpc-core-
|
|
2
|
+
import { t as ContextRpcServer } from "../../rpc-core-Cc4lucI0.mjs";
|
|
3
3
|
//#region src/rpc/transports/ws-bun.d.ts
|
|
4
4
|
interface AttachBunWsTransportOptions {
|
|
5
5
|
/** Same contract as `WsRpcTransportOptions.allowedOrigins`. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as isAllowedOrigin, r as createWsRpcPeerHooks } from "../../ws-server-
|
|
1
|
+
import { i as isAllowedOrigin, r as createWsRpcPeerHooks } from "../../ws-server-BdSLrhxE.mjs";
|
|
2
2
|
//#region src/rpc/transports/ws-bun.ts
|
|
3
3
|
/**
|
|
4
4
|
* The Bun fetch-upgrade WebSocket tier for `initDevframe` / `initHub` — the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEVFRAME_AUTH_TOKEN_QUERY_PARAM } from "../../constants.mjs";
|
|
2
|
-
import { t as createRpcWireCodec } from "../../wire-codec-
|
|
2
|
+
import { t as createRpcWireCodec } from "../../wire-codec-0K-o5MYW.mjs";
|
|
3
3
|
//#region src/rpc/transports/ws-client.ts
|
|
4
4
|
function NOOP() {}
|
|
5
5
|
const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as isLoopbackHostname, i as isAllowedOrigin, n as createWsOriginRegistry, r as createWsRpcPeerHooks, t as attachWsRpcTransport } from "../../ws-server-
|
|
1
|
+
import { a as isLoopbackHostname, i as isAllowedOrigin, n as createWsOriginRegistry, r as createWsRpcPeerHooks, t as attachWsRpcTransport } from "../../ws-server-BdSLrhxE.mjs";
|
|
2
2
|
export { attachWsRpcTransport, createWsOriginRegistry, createWsRpcPeerHooks, isAllowedOrigin, isLoopbackHostname };
|