@kodycodes/cli 1.27.1 → 1.27.2
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/bin.js +1 -1
- package/dist/{chunk-5YQBD7PN.js → chunk-GMKTUBB5.js} +5 -3
- package/dist/chunk-GMKTUBB5.js.map +6 -0
- package/dist/cli.js +1 -1
- package/dist/{dev-command-TZ2EB4J3.js → dev-command-PCQDX5EH.js} +753 -109
- package/dist/dev-command-PCQDX5EH.js.map +6 -0
- package/dist/fetch-body-package-scan.d.ts +11 -0
- package/dist/fetch-body-secret-resolution.d.ts +21 -0
- package/package.json +1 -1
- package/dist/chunk-5YQBD7PN.js.map +0 -6
- package/dist/dev-command-TZ2EB4J3.js.map +0 -6
|
@@ -69,8 +69,8 @@ import {
|
|
|
69
69
|
import "./chunk-UW6AWLXX.js";
|
|
70
70
|
|
|
71
71
|
// src/dev-command.ts
|
|
72
|
-
import { access, mkdir as mkdir3, readFile as
|
|
73
|
-
import { dirname as
|
|
72
|
+
import { access, mkdir as mkdir3, readFile as readFile5, rm as rm4, writeFile as writeFile4 } from "node:fs/promises";
|
|
73
|
+
import { dirname as dirname4, join as join9, resolve as resolve8 } from "node:path";
|
|
74
74
|
|
|
75
75
|
// src/credentialed-fetch-scan.ts
|
|
76
76
|
var esModuleLexerReady = init();
|
|
@@ -142,6 +142,621 @@ function mocksSuggestionDetail(input) {
|
|
|
142
142
|
return `suggested \u2014 package uses credentialed fetch (${kinds}); add .kody/mocks.ts so --target mock can MSW-match outbound requests (unmocked credentialed hops fail closed)`;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
// src/fetch-body-secret-resolution.ts
|
|
146
|
+
var fetchBodySecretResolutionWarningLead = 'WARNING: a fetch sends a body without x-kody-secret-resolution. The gateway fills {{secret:name}} anywhere in that body, so text this package did not write can fail with Secret "name" was not found, or a saved secret can be sent to a host the credential allows. Set x-kody-secret-resolution: headers-only on that fetch (headers still resolve). This does not block publish.';
|
|
147
|
+
var secretResolutionHeaderName = "x-kody-secret-resolution";
|
|
148
|
+
var maxWarningSites = 8;
|
|
149
|
+
function findFetchBodiesMissingSecretResolution(source) {
|
|
150
|
+
const hits = [];
|
|
151
|
+
for (const call of findFetchLikeCalls(source)) {
|
|
152
|
+
if (callSendsUnresolvedDynamicBody(call.args)) {
|
|
153
|
+
hits.push({ line: lineAt(source, call.index) });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return hits;
|
|
157
|
+
}
|
|
158
|
+
function formatFetchBodySecretResolutionWarning(hits) {
|
|
159
|
+
if (hits.length === 0) return null;
|
|
160
|
+
const ordered = [...hits].sort((left, right) => {
|
|
161
|
+
const byPath = left.path.localeCompare(right.path);
|
|
162
|
+
return byPath === 0 ? left.line - right.line : byPath;
|
|
163
|
+
});
|
|
164
|
+
const shown = ordered.slice(0, maxWarningSites);
|
|
165
|
+
const extra = ordered.length - shown.length;
|
|
166
|
+
return [
|
|
167
|
+
fetchBodySecretResolutionWarningLead,
|
|
168
|
+
...shown.map((hit) => `- ${hit.path}:${hit.line}`),
|
|
169
|
+
...extra > 0 ? [`- ${extra} more`] : []
|
|
170
|
+
].join("\n");
|
|
171
|
+
}
|
|
172
|
+
function findFetchLikeCalls(source) {
|
|
173
|
+
const calls = [];
|
|
174
|
+
scanCode(source, 0, "eof", calls);
|
|
175
|
+
return calls;
|
|
176
|
+
}
|
|
177
|
+
function scanCode(source, start, stop, calls) {
|
|
178
|
+
let index = start;
|
|
179
|
+
let lastWord = "";
|
|
180
|
+
let braceDepth = 0;
|
|
181
|
+
while (index < source.length) {
|
|
182
|
+
const char = source[index];
|
|
183
|
+
if (isWhitespace(char)) {
|
|
184
|
+
index += 1;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
188
|
+
index = skipLineComment(source, index);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
192
|
+
index = skipBlockComment(source, index);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (char === "'" || char === '"') {
|
|
196
|
+
index = skipQuotedString(source, index);
|
|
197
|
+
lastWord = "";
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (char === "`") {
|
|
201
|
+
index = skipTemplate(source, index, calls);
|
|
202
|
+
lastWord = "";
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (isIdentStart(char)) {
|
|
206
|
+
const wordStart = index;
|
|
207
|
+
index += 1;
|
|
208
|
+
while (index < source.length && isIdentPart(source[index])) index += 1;
|
|
209
|
+
const word = source.slice(wordStart, index);
|
|
210
|
+
const openParen = skipWhitespaceAndComments(source, index);
|
|
211
|
+
const isFetch = word === "fetch" && lastWord !== "function" && lastWord !== "async";
|
|
212
|
+
const isRequest = word === "Request" && lastWord === "new";
|
|
213
|
+
if ((isFetch || isRequest) && source[openParen] === "(") {
|
|
214
|
+
const call = readCallArguments(source, openParen);
|
|
215
|
+
if (call) calls.push({ index: wordStart, args: call.args });
|
|
216
|
+
}
|
|
217
|
+
lastWord = word;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (char === "{") {
|
|
221
|
+
braceDepth += 1;
|
|
222
|
+
lastWord = "";
|
|
223
|
+
index += 1;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (char === "}") {
|
|
227
|
+
if (stop === "brace" && braceDepth === 0) return index + 1;
|
|
228
|
+
braceDepth -= 1;
|
|
229
|
+
lastWord = "";
|
|
230
|
+
index += 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
lastWord = "";
|
|
234
|
+
index += 1;
|
|
235
|
+
}
|
|
236
|
+
return index;
|
|
237
|
+
}
|
|
238
|
+
function callSendsUnresolvedDynamicBody(args) {
|
|
239
|
+
const init2 = args[1]?.trim();
|
|
240
|
+
if (init2 == null || !init2.startsWith("{")) return false;
|
|
241
|
+
const properties = readObjectProperties(init2);
|
|
242
|
+
if (properties == null) return false;
|
|
243
|
+
const body = lastProperty(properties, "body");
|
|
244
|
+
if (body == null || body.spread || body.method) return false;
|
|
245
|
+
if (isStaticExpression(body.value)) return false;
|
|
246
|
+
const headers = lastProperty(properties, "headers");
|
|
247
|
+
if (headers == null) return true;
|
|
248
|
+
if (headers.spread || headers.method) return false;
|
|
249
|
+
return headersLeaveBodyResolutionOn(headers.value);
|
|
250
|
+
}
|
|
251
|
+
function headersLeaveBodyResolutionOn(headersValue) {
|
|
252
|
+
const text = headersValue.trim();
|
|
253
|
+
if (!text.startsWith("{")) return false;
|
|
254
|
+
const properties = readObjectProperties(text);
|
|
255
|
+
if (properties == null) return false;
|
|
256
|
+
if (properties.some((property) => property.spread)) return false;
|
|
257
|
+
const resolution = lastProperty(properties, secretResolutionHeaderName, {
|
|
258
|
+
caseInsensitive: true
|
|
259
|
+
});
|
|
260
|
+
if (resolution == null || resolution.method) return true;
|
|
261
|
+
const mode = staticStringValue(resolution.value);
|
|
262
|
+
if (mode == null) return false;
|
|
263
|
+
return mode === "on";
|
|
264
|
+
}
|
|
265
|
+
function lastProperty(properties, key, options) {
|
|
266
|
+
const needle = options?.caseInsensitive ? key.toLowerCase() : key;
|
|
267
|
+
for (let index = properties.length - 1; index >= 0; index -= 1) {
|
|
268
|
+
const property = properties[index];
|
|
269
|
+
const name = property.key;
|
|
270
|
+
if (name == null) continue;
|
|
271
|
+
const match = options?.caseInsensitive ? name.toLowerCase() : name;
|
|
272
|
+
if (match === needle) return property;
|
|
273
|
+
}
|
|
274
|
+
return void 0;
|
|
275
|
+
}
|
|
276
|
+
function readObjectProperties(source) {
|
|
277
|
+
const text = source.trim();
|
|
278
|
+
if (!text.startsWith("{")) return null;
|
|
279
|
+
const properties = [];
|
|
280
|
+
let index = 1;
|
|
281
|
+
while (index < text.length) {
|
|
282
|
+
index = skipWhitespaceAndComments(text, index);
|
|
283
|
+
if (index >= text.length) return null;
|
|
284
|
+
if (text[index] === "}") return properties;
|
|
285
|
+
if (text[index] === ",") {
|
|
286
|
+
index += 1;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (text.startsWith("...", index)) {
|
|
290
|
+
const spread = readExpression(text, index + 3);
|
|
291
|
+
if (spread == null) return null;
|
|
292
|
+
properties.push({
|
|
293
|
+
key: null,
|
|
294
|
+
value: spread.text,
|
|
295
|
+
spread: true,
|
|
296
|
+
method: false
|
|
297
|
+
});
|
|
298
|
+
index = spread.end;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
const key = readPropertyKey(text, index);
|
|
302
|
+
if (key == null) return null;
|
|
303
|
+
index = skipWhitespaceAndComments(text, key.end);
|
|
304
|
+
if (text[index] === "(" || text.startsWith("async ", key.start)) {
|
|
305
|
+
const method = skipMethod(text, index);
|
|
306
|
+
if (method == null) return null;
|
|
307
|
+
properties.push({
|
|
308
|
+
key: key.name,
|
|
309
|
+
value: "",
|
|
310
|
+
spread: false,
|
|
311
|
+
method: true
|
|
312
|
+
});
|
|
313
|
+
index = method;
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (text[index] !== ":") {
|
|
317
|
+
properties.push({
|
|
318
|
+
key: key.name,
|
|
319
|
+
value: key.raw,
|
|
320
|
+
spread: false,
|
|
321
|
+
method: false
|
|
322
|
+
});
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const value = readExpression(text, index + 1);
|
|
326
|
+
if (value == null) return null;
|
|
327
|
+
properties.push({
|
|
328
|
+
key: key.name,
|
|
329
|
+
value: value.text,
|
|
330
|
+
spread: false,
|
|
331
|
+
method: false
|
|
332
|
+
});
|
|
333
|
+
index = value.end;
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
function readPropertyKey(source, start) {
|
|
338
|
+
const index = skipWhitespaceAndComments(source, start);
|
|
339
|
+
const char = source[index];
|
|
340
|
+
if (char === "'" || char === '"') {
|
|
341
|
+
const end = skipQuotedString(source, index);
|
|
342
|
+
const raw = source.slice(index, end);
|
|
343
|
+
return { name: staticStringValue(raw), raw, start: index, end };
|
|
344
|
+
}
|
|
345
|
+
if (char === "[") {
|
|
346
|
+
const computed = readBalanced(source, index, "[", "]");
|
|
347
|
+
if (computed == null) return null;
|
|
348
|
+
return { name: null, raw: computed.text, start: index, end: computed.end };
|
|
349
|
+
}
|
|
350
|
+
if (char != null && isIdentStart(char)) {
|
|
351
|
+
let end = index + 1;
|
|
352
|
+
while (end < source.length && isIdentPart(source[end])) end += 1;
|
|
353
|
+
const raw = source.slice(index, end);
|
|
354
|
+
return { name: raw, raw, start: index, end };
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
function readExpression(source, start) {
|
|
359
|
+
const index = skipWhitespaceAndComments(source, start);
|
|
360
|
+
const balanced = readUntilSeparator(source, index);
|
|
361
|
+
if (balanced == null) return null;
|
|
362
|
+
return { text: source.slice(index, balanced), end: balanced };
|
|
363
|
+
}
|
|
364
|
+
function readUntilSeparator(source, start) {
|
|
365
|
+
let index = start;
|
|
366
|
+
let paren = 0;
|
|
367
|
+
let brace = 0;
|
|
368
|
+
let bracket = 0;
|
|
369
|
+
while (index < source.length) {
|
|
370
|
+
const char = source[index];
|
|
371
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
372
|
+
index = skipLineComment(source, index);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
376
|
+
index = skipBlockComment(source, index);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (char === "'" || char === '"') {
|
|
380
|
+
index = skipQuotedString(source, index);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (char === "`") {
|
|
384
|
+
index = skipTemplate(source, index, []);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
if (char === "(") paren += 1;
|
|
388
|
+
else if (char === ")") {
|
|
389
|
+
if (paren === 0) return index;
|
|
390
|
+
paren -= 1;
|
|
391
|
+
} else if (char === "{") brace += 1;
|
|
392
|
+
else if (char === "}") {
|
|
393
|
+
if (brace === 0 && paren === 0 && bracket === 0) return index;
|
|
394
|
+
brace -= 1;
|
|
395
|
+
} else if (char === "[") bracket += 1;
|
|
396
|
+
else if (char === "]") {
|
|
397
|
+
if (bracket === 0) return index;
|
|
398
|
+
bracket -= 1;
|
|
399
|
+
} else if (char === "," && paren === 0 && brace === 0 && bracket === 0) {
|
|
400
|
+
return index;
|
|
401
|
+
}
|
|
402
|
+
index += 1;
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
function skipMethod(source, openParen) {
|
|
407
|
+
const params = readBalanced(source, openParen, "(", ")");
|
|
408
|
+
if (params == null) return null;
|
|
409
|
+
const bodyAt = skipWhitespaceAndComments(source, params.end);
|
|
410
|
+
if (source[bodyAt] !== "{") return null;
|
|
411
|
+
const body = readBalanced(source, bodyAt, "{", "}");
|
|
412
|
+
return body?.end ?? null;
|
|
413
|
+
}
|
|
414
|
+
function readCallArguments(source, openParen) {
|
|
415
|
+
const args = [];
|
|
416
|
+
let index = openParen + 1;
|
|
417
|
+
let argStart = index;
|
|
418
|
+
let paren = 1;
|
|
419
|
+
let brace = 0;
|
|
420
|
+
let bracket = 0;
|
|
421
|
+
while (index < source.length) {
|
|
422
|
+
const char = source[index];
|
|
423
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
424
|
+
index = skipLineComment(source, index);
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
428
|
+
index = skipBlockComment(source, index);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
if (char === "'" || char === '"') {
|
|
432
|
+
index = skipQuotedString(source, index);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (char === "`") {
|
|
436
|
+
index = skipTemplate(source, index, []);
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
if (char === "(") paren += 1;
|
|
440
|
+
else if (char === ")") {
|
|
441
|
+
paren -= 1;
|
|
442
|
+
if (paren === 0) {
|
|
443
|
+
args.push(source.slice(argStart, index));
|
|
444
|
+
return { args };
|
|
445
|
+
}
|
|
446
|
+
} else if (char === "{") brace += 1;
|
|
447
|
+
else if (char === "}") brace -= 1;
|
|
448
|
+
else if (char === "[") bracket += 1;
|
|
449
|
+
else if (char === "]") bracket -= 1;
|
|
450
|
+
else if (char === "," && paren === 1 && brace === 0 && bracket === 0) {
|
|
451
|
+
args.push(source.slice(argStart, index));
|
|
452
|
+
argStart = index + 1;
|
|
453
|
+
}
|
|
454
|
+
index += 1;
|
|
455
|
+
}
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
function readBalanced(source, openIndex, open2, close) {
|
|
459
|
+
let depth = 0;
|
|
460
|
+
let index = openIndex;
|
|
461
|
+
while (index < source.length) {
|
|
462
|
+
const char = source[index];
|
|
463
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
464
|
+
index = skipLineComment(source, index);
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
468
|
+
index = skipBlockComment(source, index);
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
if (char === "'" || char === '"') {
|
|
472
|
+
index = skipQuotedString(source, index);
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (char === "`") {
|
|
476
|
+
index = skipTemplate(source, index, []);
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (char === open2) depth += 1;
|
|
480
|
+
else if (char === close) {
|
|
481
|
+
depth -= 1;
|
|
482
|
+
if (depth === 0) {
|
|
483
|
+
return { text: source.slice(openIndex, index + 1), end: index + 1 };
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
index += 1;
|
|
487
|
+
}
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
function isStaticExpression(expression) {
|
|
491
|
+
const text = expression.trim();
|
|
492
|
+
if (isLiteral(text)) return true;
|
|
493
|
+
const stringify = matchCallee(text, "JSON.stringify");
|
|
494
|
+
if (stringify != null) {
|
|
495
|
+
const data = stringify.args[0];
|
|
496
|
+
return data != null && stringify.args.slice(1).every((arg) => isLiteral(arg.trim())) && isStaticData(data);
|
|
497
|
+
}
|
|
498
|
+
const params = matchNewCallee(text, "URLSearchParams");
|
|
499
|
+
if (params != null) {
|
|
500
|
+
if (params.args.length === 0) return true;
|
|
501
|
+
const data = params.args[0];
|
|
502
|
+
return data != null && params.args.length === 1 && isStaticData(data);
|
|
503
|
+
}
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
function isStaticData(expression) {
|
|
507
|
+
const text = expression.trim();
|
|
508
|
+
if (isLiteral(text)) return true;
|
|
509
|
+
if (text.startsWith("{")) {
|
|
510
|
+
const closed = readBalanced(text, 0, "{", "}");
|
|
511
|
+
if (closed == null || closed.end !== text.length) return false;
|
|
512
|
+
const properties = readObjectProperties(text);
|
|
513
|
+
if (properties == null) return false;
|
|
514
|
+
return properties.every(
|
|
515
|
+
(property) => !property.spread && !property.method && property.key != null && isStaticData(property.value)
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
if (text.startsWith("[")) {
|
|
519
|
+
const closed = readBalanced(text, 0, "[", "]");
|
|
520
|
+
if (closed == null || closed.end !== text.length) return false;
|
|
521
|
+
const elements = readArrayElements(text);
|
|
522
|
+
if (elements == null) return false;
|
|
523
|
+
return elements.every((element) => isStaticData(element));
|
|
524
|
+
}
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
function readArrayElements(source) {
|
|
528
|
+
const text = source.trim();
|
|
529
|
+
if (!text.startsWith("[")) return null;
|
|
530
|
+
const elements = [];
|
|
531
|
+
let index = 1;
|
|
532
|
+
while (index < text.length) {
|
|
533
|
+
index = skipWhitespaceAndComments(text, index);
|
|
534
|
+
if (text[index] === "]") return elements;
|
|
535
|
+
if (text[index] === ",") {
|
|
536
|
+
index += 1;
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (text.startsWith("...", index)) return null;
|
|
540
|
+
const value = readExpression(text, index);
|
|
541
|
+
if (value == null) return null;
|
|
542
|
+
elements.push(value.text);
|
|
543
|
+
index = value.end;
|
|
544
|
+
}
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
function isLiteral(expression) {
|
|
548
|
+
const text = expression.trim();
|
|
549
|
+
if (/^(?:null|undefined|true|false|-?\d+(?:\.\d+)?)$/.test(text)) return true;
|
|
550
|
+
if (isPlainTemplate(text)) return true;
|
|
551
|
+
return staticStringValue(text) != null && (text.startsWith("'") || text.startsWith('"'));
|
|
552
|
+
}
|
|
553
|
+
function staticStringValue(expression) {
|
|
554
|
+
const text = expression.trim();
|
|
555
|
+
if (isPlainTemplate(text)) return text.slice(1, -1);
|
|
556
|
+
if (text.startsWith("'") && text.endsWith("'") || text.startsWith('"') && text.endsWith('"')) {
|
|
557
|
+
if (text.length < 2) return null;
|
|
558
|
+
const body = text.slice(1, -1);
|
|
559
|
+
if (body.includes(text[0]) || body.includes("\n")) return null;
|
|
560
|
+
return body.replace(/\\(.)/g, "$1");
|
|
561
|
+
}
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
function isPlainTemplate(expression) {
|
|
565
|
+
const text = expression.trim();
|
|
566
|
+
return text.startsWith("`") && text.endsWith("`") && !text.slice(1, -1).includes("${");
|
|
567
|
+
}
|
|
568
|
+
function matchCallee(expression, callee) {
|
|
569
|
+
const text = expression.trim();
|
|
570
|
+
if (!text.startsWith(callee)) return null;
|
|
571
|
+
const open2 = skipWhitespaceAndComments(text, callee.length);
|
|
572
|
+
if (text[open2] !== "(") return null;
|
|
573
|
+
const call = readCallArguments(text, open2);
|
|
574
|
+
if (call == null) return null;
|
|
575
|
+
const end = skipWhitespaceAndComments(text, endOfCall(text, open2));
|
|
576
|
+
if (end !== text.length) return null;
|
|
577
|
+
return call;
|
|
578
|
+
}
|
|
579
|
+
function matchNewCallee(expression, name) {
|
|
580
|
+
const text = expression.trim();
|
|
581
|
+
if (!text.startsWith("new")) return null;
|
|
582
|
+
const nameAt = skipWhitespaceAndComments(text, "new".length);
|
|
583
|
+
if (!text.startsWith(name, nameAt)) return null;
|
|
584
|
+
return matchCallee(text.slice(nameAt), name);
|
|
585
|
+
}
|
|
586
|
+
function endOfCall(source, openParen) {
|
|
587
|
+
const args = readCallArguments(source, openParen);
|
|
588
|
+
if (args == null) return openParen;
|
|
589
|
+
let index = openParen;
|
|
590
|
+
let paren = 0;
|
|
591
|
+
while (index < source.length) {
|
|
592
|
+
const char = source[index];
|
|
593
|
+
if (char === "'" || char === '"') {
|
|
594
|
+
index = skipQuotedString(source, index);
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
if (char === "`") {
|
|
598
|
+
index = skipTemplate(source, index, []);
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
if (char === "(") paren += 1;
|
|
602
|
+
else if (char === ")") {
|
|
603
|
+
paren -= 1;
|
|
604
|
+
if (paren === 0) return index + 1;
|
|
605
|
+
}
|
|
606
|
+
index += 1;
|
|
607
|
+
}
|
|
608
|
+
return source.length;
|
|
609
|
+
}
|
|
610
|
+
function skipTemplate(source, start, calls) {
|
|
611
|
+
let index = start + 1;
|
|
612
|
+
while (index < source.length) {
|
|
613
|
+
const char = source[index];
|
|
614
|
+
if (char === "\\") {
|
|
615
|
+
index += 2;
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (char === "`") return index + 1;
|
|
619
|
+
if (char === "$" && source[index + 1] === "{") {
|
|
620
|
+
index = scanCode(source, index + 2, "brace", calls);
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
index += 1;
|
|
624
|
+
}
|
|
625
|
+
return index;
|
|
626
|
+
}
|
|
627
|
+
function skipQuotedString(source, start) {
|
|
628
|
+
const quote = source[start];
|
|
629
|
+
let index = start + 1;
|
|
630
|
+
while (index < source.length) {
|
|
631
|
+
const char = source[index];
|
|
632
|
+
if (char === "\\") {
|
|
633
|
+
index += 2;
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (char === quote) return index + 1;
|
|
637
|
+
if (char === "\n") return index;
|
|
638
|
+
index += 1;
|
|
639
|
+
}
|
|
640
|
+
return index;
|
|
641
|
+
}
|
|
642
|
+
function skipLineComment(source, start) {
|
|
643
|
+
const newline = source.indexOf("\n", start);
|
|
644
|
+
return newline === -1 ? source.length : newline + 1;
|
|
645
|
+
}
|
|
646
|
+
function skipBlockComment(source, start) {
|
|
647
|
+
const end = source.indexOf("*/", start + 2);
|
|
648
|
+
return end === -1 ? source.length : end + 2;
|
|
649
|
+
}
|
|
650
|
+
function skipWhitespaceAndComments(source, start) {
|
|
651
|
+
let index = start;
|
|
652
|
+
while (index < source.length) {
|
|
653
|
+
const char = source[index];
|
|
654
|
+
if (isWhitespace(char)) {
|
|
655
|
+
index += 1;
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
659
|
+
index = skipLineComment(source, index);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
663
|
+
index = skipBlockComment(source, index);
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
return index;
|
|
669
|
+
}
|
|
670
|
+
function lineAt(source, index) {
|
|
671
|
+
let line = 1;
|
|
672
|
+
for (let cursor = 0; cursor < index && cursor < source.length; cursor += 1) {
|
|
673
|
+
if (source[cursor] === "\n") line += 1;
|
|
674
|
+
}
|
|
675
|
+
return line;
|
|
676
|
+
}
|
|
677
|
+
function isWhitespace(char) {
|
|
678
|
+
return char === " " || char === " " || char === "\n" || char === "\r";
|
|
679
|
+
}
|
|
680
|
+
function isIdentStart(char) {
|
|
681
|
+
return /[A-Za-z_$]/.test(char);
|
|
682
|
+
}
|
|
683
|
+
function isIdentPart(char) {
|
|
684
|
+
return /[A-Za-z0-9_$]/.test(char);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// src/fetch-body-package-scan.ts
|
|
688
|
+
import { readFile, stat } from "node:fs/promises";
|
|
689
|
+
import { dirname, extname, join, relative, resolve } from "node:path";
|
|
690
|
+
var esModuleLexerReady2 = init();
|
|
691
|
+
var sourceExtensions = [
|
|
692
|
+
".ts",
|
|
693
|
+
".tsx",
|
|
694
|
+
".mts",
|
|
695
|
+
".cts",
|
|
696
|
+
".js",
|
|
697
|
+
".mjs",
|
|
698
|
+
".cjs",
|
|
699
|
+
".jsx"
|
|
700
|
+
];
|
|
701
|
+
var maxModules = 200;
|
|
702
|
+
async function findPackageFetchBodyWarnings(input) {
|
|
703
|
+
await esModuleLexerReady2;
|
|
704
|
+
const hits = [];
|
|
705
|
+
const seen = /* @__PURE__ */ new Set();
|
|
706
|
+
const queue = [input.entryPath];
|
|
707
|
+
while (queue.length > 0 && seen.size < maxModules) {
|
|
708
|
+
const resolved = await resolveSourceFile(queue.pop());
|
|
709
|
+
if (resolved == null || seen.has(resolved)) continue;
|
|
710
|
+
const rel = relative(input.packageRoot, resolved).split("\\").join("/");
|
|
711
|
+
if (rel.startsWith("..") || rel.split("/").includes("node_modules") || isTestModule(rel)) {
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
seen.add(resolved);
|
|
715
|
+
let source;
|
|
716
|
+
try {
|
|
717
|
+
source = await readFile(resolved, "utf8");
|
|
718
|
+
} catch {
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
for (const hit of findFetchBodiesMissingSecretResolution(source)) {
|
|
722
|
+
hits.push({ path: rel, line: hit.line });
|
|
723
|
+
}
|
|
724
|
+
let imports;
|
|
725
|
+
try {
|
|
726
|
+
imports = parse(source)[0];
|
|
727
|
+
} catch {
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
for (const im of imports) {
|
|
731
|
+
if (im.type === "dynamic" || im.typeOnly === true) continue;
|
|
732
|
+
const specifier = im.specifier;
|
|
733
|
+
if (typeof specifier !== "string" || !specifier.startsWith(".")) continue;
|
|
734
|
+
queue.push(resolve(dirname(resolved), specifier));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return hits;
|
|
738
|
+
}
|
|
739
|
+
function isTestModule(path) {
|
|
740
|
+
return /\.(?:test|spec)\.[cm]?[jt]sx?$/.test(path);
|
|
741
|
+
}
|
|
742
|
+
async function resolveSourceFile(absPath) {
|
|
743
|
+
const candidates = [absPath];
|
|
744
|
+
if (extname(absPath) === "") {
|
|
745
|
+
for (const ext of sourceExtensions) {
|
|
746
|
+
candidates.push(`${absPath}${ext}`);
|
|
747
|
+
candidates.push(join(absPath, `index${ext}`));
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
for (const candidate of candidates) {
|
|
751
|
+
try {
|
|
752
|
+
const info = await stat(candidate);
|
|
753
|
+
if (info.isFile()) return candidate;
|
|
754
|
+
} catch {
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
|
|
145
760
|
// src/package-app-dev.ts
|
|
146
761
|
import { randomBytes } from "node:crypto";
|
|
147
762
|
import { rmSync } from "node:fs";
|
|
@@ -151,19 +766,19 @@ import {
|
|
|
151
766
|
request as httpRequest
|
|
152
767
|
} from "node:http";
|
|
153
768
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
154
|
-
import { join as
|
|
769
|
+
import { join as join8, relative as relative5, resolve as resolve7, sep as sep3 } from "node:path";
|
|
155
770
|
|
|
156
771
|
// src/dev/dev-assets.ts
|
|
157
772
|
import * as esbuild2 from "esbuild";
|
|
158
773
|
import { createHash } from "node:crypto";
|
|
159
|
-
import { readFile, stat } from "node:fs/promises";
|
|
160
|
-
import { join as
|
|
774
|
+
import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
775
|
+
import { join as join3, resolve as resolve3, sep } from "node:path";
|
|
161
776
|
|
|
162
777
|
// src/dev/dev-bundler.ts
|
|
163
778
|
import * as esbuild from "esbuild";
|
|
164
|
-
import { join, resolve } from "node:path";
|
|
779
|
+
import { join as join2, resolve as resolve2 } from "node:path";
|
|
165
780
|
function createDevBundler(input) {
|
|
166
|
-
const entry =
|
|
781
|
+
const entry = resolve2(input.entryPath);
|
|
167
782
|
const base = localBundleOptions(entry);
|
|
168
783
|
const options = {
|
|
169
784
|
...base,
|
|
@@ -171,7 +786,7 @@ function createDevBundler(input) {
|
|
|
171
786
|
sourcesContent: false,
|
|
172
787
|
metafile: true,
|
|
173
788
|
// Never written (write: false); only anchors source map paths at the root.
|
|
174
|
-
outfile:
|
|
789
|
+
outfile: join2(input.root, "__kody_dev_bundle.js")
|
|
175
790
|
};
|
|
176
791
|
const paths = { workingDir: base.absWorkingDir, displayRoot: input.root };
|
|
177
792
|
let disposed = false;
|
|
@@ -197,7 +812,7 @@ function createDevBundler(input) {
|
|
|
197
812
|
};
|
|
198
813
|
}
|
|
199
814
|
function bundleInputs(metafile, workingDir) {
|
|
200
|
-
return Object.keys(metafile?.inputs ?? {}).filter((path) => !path.includes("node_modules") && !path.includes(":")).map((path) =>
|
|
815
|
+
return Object.keys(metafile?.inputs ?? {}).filter((path) => !path.includes("node_modules") && !path.includes(":")).map((path) => resolve2(workingDir, path));
|
|
201
816
|
}
|
|
202
817
|
function readBundle(result, workingDir, entryPath) {
|
|
203
818
|
const outputs = result.outputFiles ?? [];
|
|
@@ -227,7 +842,7 @@ function createDevClientBundler(input) {
|
|
|
227
842
|
let context3 = null;
|
|
228
843
|
const createContext = () => esbuild2.context({
|
|
229
844
|
absWorkingDir: workingDir,
|
|
230
|
-
entryPoints: [
|
|
845
|
+
entryPoints: [resolve3(input.entryPath)],
|
|
231
846
|
bundle: true,
|
|
232
847
|
write: false,
|
|
233
848
|
metafile: true,
|
|
@@ -236,7 +851,7 @@ function createDevClientBundler(input) {
|
|
|
236
851
|
target: "es2022",
|
|
237
852
|
sourcemap: "inline",
|
|
238
853
|
logLevel: "silent",
|
|
239
|
-
outfile:
|
|
854
|
+
outfile: join3(input.root, "_assets", "client.js"),
|
|
240
855
|
plugins: externals.length > 0 ? [clientExternalsPlugin(externals)] : []
|
|
241
856
|
});
|
|
242
857
|
return {
|
|
@@ -292,8 +907,8 @@ function parseDevAssetPath(pathname) {
|
|
|
292
907
|
}
|
|
293
908
|
function resolveDevAssetFile(assetsDir, relativePath) {
|
|
294
909
|
if (relativePath.includes("\0") || relativePath.startsWith("/")) return null;
|
|
295
|
-
const root =
|
|
296
|
-
const file =
|
|
910
|
+
const root = resolve3(assetsDir);
|
|
911
|
+
const file = resolve3(root, relativePath);
|
|
297
912
|
return file.startsWith(`${root}${sep}`) ? file : null;
|
|
298
913
|
}
|
|
299
914
|
async function serveDevAsset(input) {
|
|
@@ -341,8 +956,8 @@ async function serveDevAsset(input) {
|
|
|
341
956
|
}
|
|
342
957
|
async function readAssetFile(file) {
|
|
343
958
|
try {
|
|
344
|
-
if (!(await
|
|
345
|
-
return await
|
|
959
|
+
if (!(await stat2(file)).isFile()) return null;
|
|
960
|
+
return await readFile2(file);
|
|
346
961
|
} catch {
|
|
347
962
|
return null;
|
|
348
963
|
}
|
|
@@ -540,14 +1155,14 @@ function wrapPort(port) {
|
|
|
540
1155
|
return port > 65535 ? devPortRange.min + (port - 65536) : port;
|
|
541
1156
|
}
|
|
542
1157
|
function listenOnce(server, host, port) {
|
|
543
|
-
return new Promise((
|
|
1158
|
+
return new Promise((resolve9, reject) => {
|
|
544
1159
|
const onError = (error) => {
|
|
545
1160
|
server.off("listening", onListening);
|
|
546
1161
|
reject(error);
|
|
547
1162
|
};
|
|
548
1163
|
const onListening = () => {
|
|
549
1164
|
server.off("error", onError);
|
|
550
|
-
|
|
1165
|
+
resolve9();
|
|
551
1166
|
};
|
|
552
1167
|
server.once("error", onError);
|
|
553
1168
|
server.once("listening", onListening);
|
|
@@ -560,14 +1175,14 @@ function isAddressInUse(error) {
|
|
|
560
1175
|
|
|
561
1176
|
// src/dev/dev-registry.ts
|
|
562
1177
|
import { createHash as createHash3 } from "node:crypto";
|
|
563
|
-
import { mkdir, readFile as
|
|
564
|
-
import { join as
|
|
1178
|
+
import { mkdir, readFile as readFile4, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
1179
|
+
import { join as join5 } from "node:path";
|
|
565
1180
|
|
|
566
1181
|
// src/dev/process-reaper.ts
|
|
567
1182
|
import { spawn } from "node:child_process";
|
|
568
|
-
import { readdir, readFile as
|
|
1183
|
+
import { readdir, readFile as readFile3, rm, stat as stat3, writeFile } from "node:fs/promises";
|
|
569
1184
|
import { tmpdir } from "node:os";
|
|
570
|
-
import { join as
|
|
1185
|
+
import { join as join4 } from "node:path";
|
|
571
1186
|
import psList from "ps-list";
|
|
572
1187
|
var devWorkDirPrefix = "kody-dev-";
|
|
573
1188
|
var ownerFileName = "owner.json";
|
|
@@ -590,7 +1205,7 @@ rm -rf "$1"
|
|
|
590
1205
|
`;
|
|
591
1206
|
async function startProcessReaper(input) {
|
|
592
1207
|
await writeFile(
|
|
593
|
-
|
|
1208
|
+
join4(input.workDir, ownerFileName),
|
|
594
1209
|
JSON.stringify({ pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
595
1210
|
);
|
|
596
1211
|
let reaper;
|
|
@@ -652,7 +1267,7 @@ async function sweepStaleDevDirs(input = {}) {
|
|
|
652
1267
|
}
|
|
653
1268
|
const byPid = new Map(processes.map((item) => [item.pid, item]));
|
|
654
1269
|
for (const name of entries) {
|
|
655
|
-
const dir =
|
|
1270
|
+
const dir = join4(tmp, name);
|
|
656
1271
|
try {
|
|
657
1272
|
const owner = await readOwnerPid(dir);
|
|
658
1273
|
if (owner !== null && isAlive(owner)) continue;
|
|
@@ -660,7 +1275,7 @@ async function sweepStaleDevDirs(input = {}) {
|
|
|
660
1275
|
(item) => /workerd/.test(item.name) && (item.cmd ?? "").includes(`${dir}/`)
|
|
661
1276
|
);
|
|
662
1277
|
if (owner === null) {
|
|
663
|
-
const info = await
|
|
1278
|
+
const info = await stat3(dir);
|
|
664
1279
|
if (now - info.mtimeMs < legacyDirMinAgeMs) continue;
|
|
665
1280
|
if (workerds.some((item) => !isOrphaned(item, byPid, isAlive))) continue;
|
|
666
1281
|
}
|
|
@@ -687,7 +1302,7 @@ function isOrphaned(item, byPid, isAlive) {
|
|
|
687
1302
|
async function readOwnerPid(dir) {
|
|
688
1303
|
try {
|
|
689
1304
|
const parsed = JSON.parse(
|
|
690
|
-
await
|
|
1305
|
+
await readFile3(join4(dir, ownerFileName), "utf8")
|
|
691
1306
|
);
|
|
692
1307
|
return typeof parsed.pid === "number" ? parsed.pid : null;
|
|
693
1308
|
} catch {
|
|
@@ -707,11 +1322,11 @@ function isProcessAlive(pid) {
|
|
|
707
1322
|
var devStatusPath = "/__kody/dev/status";
|
|
708
1323
|
function devRegistryPath(root, target, cacheDir = userCacheDir()) {
|
|
709
1324
|
const key = createHash3("sha256").update(`${root}\0${target}`).digest("hex").slice(0, 16);
|
|
710
|
-
return
|
|
1325
|
+
return join5(cacheDir, "dev-servers", `${key}.json`);
|
|
711
1326
|
}
|
|
712
1327
|
async function writeDevRegistration(registration, cacheDir) {
|
|
713
1328
|
const path = devRegistryPath(registration.root, registration.target, cacheDir);
|
|
714
|
-
await mkdir(
|
|
1329
|
+
await mkdir(join5(path, ".."), { recursive: true });
|
|
715
1330
|
await writeFile2(path, `${JSON.stringify(registration, null, 2)}
|
|
716
1331
|
`);
|
|
717
1332
|
return path;
|
|
@@ -754,7 +1369,7 @@ async function findRunningDevServer(input) {
|
|
|
754
1369
|
async function readRegistration(path) {
|
|
755
1370
|
try {
|
|
756
1371
|
const parsed = JSON.parse(
|
|
757
|
-
await
|
|
1372
|
+
await readFile4(path, "utf8")
|
|
758
1373
|
);
|
|
759
1374
|
if (typeof parsed.pid !== "number" || typeof parsed.origin !== "string" || typeof parsed.root !== "string" || parsed.target !== "mock" && parsed.target !== "prod") {
|
|
760
1375
|
return null;
|
|
@@ -774,12 +1389,12 @@ async function readRegistration(path) {
|
|
|
774
1389
|
|
|
775
1390
|
// node_modules/chokidar/esm/index.js
|
|
776
1391
|
import { stat as statcb } from "fs";
|
|
777
|
-
import { stat as
|
|
1392
|
+
import { stat as stat6, readdir as readdir3 } from "fs/promises";
|
|
778
1393
|
import { EventEmitter } from "events";
|
|
779
1394
|
import * as sysPath2 from "path";
|
|
780
1395
|
|
|
781
1396
|
// node_modules/readdirp/esm/index.js
|
|
782
|
-
import { stat as
|
|
1397
|
+
import { stat as stat4, lstat, readdir as readdir2, realpath } from "node:fs/promises";
|
|
783
1398
|
import { Readable } from "node:stream";
|
|
784
1399
|
import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
|
|
785
1400
|
var EntryTypes = {
|
|
@@ -846,7 +1461,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
846
1461
|
const { root, type } = opts;
|
|
847
1462
|
this._fileFilter = normalizeFilter(opts.fileFilter);
|
|
848
1463
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
849
|
-
const statMethod = opts.lstat ? lstat :
|
|
1464
|
+
const statMethod = opts.lstat ? lstat : stat4;
|
|
850
1465
|
if (wantBigintFsStats) {
|
|
851
1466
|
this._stat = (path) => statMethod(path, { bigint: true });
|
|
852
1467
|
} else {
|
|
@@ -999,7 +1614,7 @@ function readdirp(root, options = {}) {
|
|
|
999
1614
|
|
|
1000
1615
|
// node_modules/chokidar/esm/handler.js
|
|
1001
1616
|
import { watchFile, unwatchFile, watch as fs_watch } from "fs";
|
|
1002
|
-
import { open, stat as
|
|
1617
|
+
import { open, stat as stat5, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
|
|
1003
1618
|
import * as sysPath from "path";
|
|
1004
1619
|
import { type as osType } from "os";
|
|
1005
1620
|
var STR_DATA = "data";
|
|
@@ -1026,7 +1641,7 @@ var EVENTS = {
|
|
|
1026
1641
|
};
|
|
1027
1642
|
var EV = EVENTS;
|
|
1028
1643
|
var THROTTLE_MODE_WATCH = "watch";
|
|
1029
|
-
var statMethods = { lstat: lstat2, stat:
|
|
1644
|
+
var statMethods = { lstat: lstat2, stat: stat5 };
|
|
1030
1645
|
var KEY_LISTENERS = "listeners";
|
|
1031
1646
|
var KEY_ERR = "errHandlers";
|
|
1032
1647
|
var KEY_RAW = "rawEmitters";
|
|
@@ -1501,9 +2116,9 @@ var NodeFsHandler = class {
|
|
|
1501
2116
|
if (this.fsw.closed) {
|
|
1502
2117
|
return;
|
|
1503
2118
|
}
|
|
1504
|
-
const
|
|
2119
|
+
const dirname5 = sysPath.dirname(file);
|
|
1505
2120
|
const basename3 = sysPath.basename(file);
|
|
1506
|
-
const parent = this.fsw._getWatchedDir(
|
|
2121
|
+
const parent = this.fsw._getWatchedDir(dirname5);
|
|
1507
2122
|
let prevStats = stats;
|
|
1508
2123
|
if (parent.has(basename3))
|
|
1509
2124
|
return;
|
|
@@ -1512,7 +2127,7 @@ var NodeFsHandler = class {
|
|
|
1512
2127
|
return;
|
|
1513
2128
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
1514
2129
|
try {
|
|
1515
|
-
const newStats2 = await
|
|
2130
|
+
const newStats2 = await stat5(file);
|
|
1516
2131
|
if (this.fsw.closed)
|
|
1517
2132
|
return;
|
|
1518
2133
|
const at = newStats2.atimeMs;
|
|
@@ -1530,7 +2145,7 @@ var NodeFsHandler = class {
|
|
|
1530
2145
|
prevStats = newStats2;
|
|
1531
2146
|
}
|
|
1532
2147
|
} catch (error) {
|
|
1533
|
-
this.fsw._remove(
|
|
2148
|
+
this.fsw._remove(dirname5, basename3);
|
|
1534
2149
|
}
|
|
1535
2150
|
} else if (parent.has(basename3)) {
|
|
1536
2151
|
const at = newStats.atimeMs;
|
|
@@ -1626,7 +2241,7 @@ var NodeFsHandler = class {
|
|
|
1626
2241
|
this._addToNodeFs(path, initialAdd, wh, depth + 1);
|
|
1627
2242
|
}
|
|
1628
2243
|
}).on(EV.ERROR, this._boundHandleError);
|
|
1629
|
-
return new Promise((
|
|
2244
|
+
return new Promise((resolve9, reject) => {
|
|
1630
2245
|
if (!stream)
|
|
1631
2246
|
return reject();
|
|
1632
2247
|
stream.once(STR_END, () => {
|
|
@@ -1635,7 +2250,7 @@ var NodeFsHandler = class {
|
|
|
1635
2250
|
return;
|
|
1636
2251
|
}
|
|
1637
2252
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
1638
|
-
|
|
2253
|
+
resolve9(void 0);
|
|
1639
2254
|
previous.getChildren().filter((item) => {
|
|
1640
2255
|
return item !== directory && !current.has(item);
|
|
1641
2256
|
}).forEach((item) => {
|
|
@@ -1779,11 +2394,11 @@ function createPattern(matcher) {
|
|
|
1779
2394
|
if (matcher.path === string)
|
|
1780
2395
|
return true;
|
|
1781
2396
|
if (matcher.recursive) {
|
|
1782
|
-
const
|
|
1783
|
-
if (!
|
|
2397
|
+
const relative6 = sysPath2.relative(matcher.path, string);
|
|
2398
|
+
if (!relative6) {
|
|
1784
2399
|
return false;
|
|
1785
2400
|
}
|
|
1786
|
-
return !
|
|
2401
|
+
return !relative6.startsWith("..") && !sysPath2.isAbsolute(relative6);
|
|
1787
2402
|
}
|
|
1788
2403
|
return false;
|
|
1789
2404
|
};
|
|
@@ -2211,7 +2826,7 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2211
2826
|
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path) : path;
|
|
2212
2827
|
let stats2;
|
|
2213
2828
|
try {
|
|
2214
|
-
stats2 = await
|
|
2829
|
+
stats2 = await stat6(fullPath);
|
|
2215
2830
|
} catch (err) {
|
|
2216
2831
|
}
|
|
2217
2832
|
if (!stats2 || this.closed)
|
|
@@ -2338,8 +2953,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2338
2953
|
}
|
|
2339
2954
|
return this._userIgnored(path, stats);
|
|
2340
2955
|
}
|
|
2341
|
-
_isntIgnored(path,
|
|
2342
|
-
return !this._isIgnored(path,
|
|
2956
|
+
_isntIgnored(path, stat8) {
|
|
2957
|
+
return !this._isIgnored(path, stat8);
|
|
2343
2958
|
}
|
|
2344
2959
|
/**
|
|
2345
2960
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
@@ -2463,12 +3078,12 @@ function watch(paths, options = {}) {
|
|
|
2463
3078
|
}
|
|
2464
3079
|
|
|
2465
3080
|
// src/dev/dev-watcher.ts
|
|
2466
|
-
import { stat as
|
|
2467
|
-
import { relative as
|
|
3081
|
+
import { stat as stat7 } from "node:fs/promises";
|
|
3082
|
+
import { relative as relative4, sep as sep2 } from "node:path";
|
|
2468
3083
|
var defaultPollIntervalMs = 1e3;
|
|
2469
3084
|
function createDevWatcher(input) {
|
|
2470
3085
|
const ignorePrefixes = (input.ignore ?? []).map(normalizePrefix).filter(Boolean);
|
|
2471
|
-
const ignored = (path) => shouldIgnoreWatchPath(
|
|
3086
|
+
const ignored = (path) => shouldIgnoreWatchPath(relative4(input.root, path), ignorePrefixes);
|
|
2472
3087
|
const watcher = watch(input.root, {
|
|
2473
3088
|
ignoreInitial: true,
|
|
2474
3089
|
ignored,
|
|
@@ -2478,10 +3093,10 @@ function createDevWatcher(input) {
|
|
|
2478
3093
|
if (!ignored(path)) input.onChange(path);
|
|
2479
3094
|
});
|
|
2480
3095
|
let readySettled = false;
|
|
2481
|
-
const ready = new Promise((
|
|
3096
|
+
const ready = new Promise((resolve9, reject) => {
|
|
2482
3097
|
watcher.once("ready", () => {
|
|
2483
3098
|
readySettled = true;
|
|
2484
|
-
|
|
3099
|
+
resolve9();
|
|
2485
3100
|
});
|
|
2486
3101
|
watcher.on("error", (error) => {
|
|
2487
3102
|
if (readySettled) return;
|
|
@@ -2568,7 +3183,7 @@ function createDevWatcher(input) {
|
|
|
2568
3183
|
}
|
|
2569
3184
|
async function fingerprint(path) {
|
|
2570
3185
|
try {
|
|
2571
|
-
const info = await
|
|
3186
|
+
const info = await stat7(path);
|
|
2572
3187
|
return `${info.ino}:${info.size}:${info.mtimeMs}`;
|
|
2573
3188
|
} catch {
|
|
2574
3189
|
return "missing";
|
|
@@ -2843,9 +3458,9 @@ async function runPrebuild(input) {
|
|
|
2843
3458
|
else input.signal.addEventListener("abort", killChild, { once: true });
|
|
2844
3459
|
}
|
|
2845
3460
|
try {
|
|
2846
|
-
const result = await new Promise((
|
|
3461
|
+
const result = await new Promise((resolve9, reject) => {
|
|
2847
3462
|
child.once("error", reject);
|
|
2848
|
-
child.once("close", (code, signal) =>
|
|
3463
|
+
child.once("close", (code, signal) => resolve9({ code, signal }));
|
|
2849
3464
|
});
|
|
2850
3465
|
if (input.signal?.aborted) {
|
|
2851
3466
|
throw new PrebuildError("kody.dev.prebuild aborted");
|
|
@@ -2891,7 +3506,7 @@ for (let i = 0; i < chars.length; i++) {
|
|
|
2891
3506
|
intToChar[i] = c;
|
|
2892
3507
|
charToInt[c] = i;
|
|
2893
3508
|
}
|
|
2894
|
-
function decodeInteger(reader,
|
|
3509
|
+
function decodeInteger(reader, relative6) {
|
|
2895
3510
|
let value = 0;
|
|
2896
3511
|
let shift = 0;
|
|
2897
3512
|
let integer = 0;
|
|
@@ -2906,7 +3521,7 @@ function decodeInteger(reader, relative5) {
|
|
|
2906
3521
|
if (shouldNegate) {
|
|
2907
3522
|
value = -2147483648 | -value;
|
|
2908
3523
|
}
|
|
2909
|
-
return
|
|
3524
|
+
return relative6 + value;
|
|
2910
3525
|
}
|
|
2911
3526
|
function hasMoreVlq(reader, max) {
|
|
2912
3527
|
if (reader.pos >= max) return false;
|
|
@@ -3094,7 +3709,7 @@ function normalizePath2(url, type) {
|
|
|
3094
3709
|
}
|
|
3095
3710
|
url.path = path;
|
|
3096
3711
|
}
|
|
3097
|
-
function
|
|
3712
|
+
function resolve6(input, base) {
|
|
3098
3713
|
if (!input && !base)
|
|
3099
3714
|
return "";
|
|
3100
3715
|
const url = parseUrl(input);
|
|
@@ -3157,7 +3772,7 @@ function stripFilename(path) {
|
|
|
3157
3772
|
function resolver(mapUrl, sourceRoot) {
|
|
3158
3773
|
const from = stripFilename(mapUrl);
|
|
3159
3774
|
const prefix = sourceRoot ? sourceRoot + "/" : "";
|
|
3160
|
-
return (source) =>
|
|
3775
|
+
return (source) => resolve6(prefix + (source || ""), from);
|
|
3161
3776
|
}
|
|
3162
3777
|
var COLUMN = 0;
|
|
3163
3778
|
var SOURCES_INDEX = 1;
|
|
@@ -3270,8 +3885,8 @@ var TraceMap = class {
|
|
|
3270
3885
|
this.sources = sources;
|
|
3271
3886
|
this.sourcesContent = sourcesContent;
|
|
3272
3887
|
this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
|
|
3273
|
-
const
|
|
3274
|
-
this.resolvedSources = sources.map(
|
|
3888
|
+
const resolve9 = resolver(mapUrl, sourceRoot);
|
|
3889
|
+
this.resolvedSources = sources.map(resolve9);
|
|
3275
3890
|
const { mappings } = parsed;
|
|
3276
3891
|
if (typeof mappings === "string") {
|
|
3277
3892
|
this._encoded = mappings;
|
|
@@ -3408,12 +4023,12 @@ async function startWorkerd(input) {
|
|
|
3408
4023
|
`;
|
|
3409
4024
|
input.onStderrLine(line);
|
|
3410
4025
|
});
|
|
3411
|
-
const exited = new Promise((
|
|
4026
|
+
const exited = new Promise((resolve9) => {
|
|
3412
4027
|
child.once(
|
|
3413
4028
|
"exit",
|
|
3414
|
-
(code, signal) =>
|
|
4029
|
+
(code, signal) => resolve9(`workerd exit ${signal ?? code}`)
|
|
3415
4030
|
);
|
|
3416
|
-
child.once("error", (error) =>
|
|
4031
|
+
child.once("error", (error) => resolve9(`workerd error: ${error.message}`));
|
|
3417
4032
|
});
|
|
3418
4033
|
const port = await waitForListen(child, exited, () => {
|
|
3419
4034
|
const trimmed = redact(startupStderr.trim());
|
|
@@ -3430,7 +4045,7 @@ ${trimmed}` : "";
|
|
|
3430
4045
|
child.kill("SIGKILL");
|
|
3431
4046
|
await Promise.race([
|
|
3432
4047
|
exited,
|
|
3433
|
-
new Promise((
|
|
4048
|
+
new Promise((resolve9) => setTimeout(resolve9, 1e3))
|
|
3434
4049
|
]);
|
|
3435
4050
|
}
|
|
3436
4051
|
};
|
|
@@ -3443,7 +4058,7 @@ function forEachLine2(stream, onLine) {
|
|
|
3443
4058
|
});
|
|
3444
4059
|
}
|
|
3445
4060
|
function waitForListen(child, exited, stderr) {
|
|
3446
|
-
return new Promise((
|
|
4061
|
+
return new Promise((resolve9, reject) => {
|
|
3447
4062
|
const control = child.stdio[3];
|
|
3448
4063
|
let buffered = "";
|
|
3449
4064
|
let settled = false;
|
|
@@ -3469,7 +4084,7 @@ function waitForListen(child, exited, stderr) {
|
|
|
3469
4084
|
buffered = lines.pop() ?? "";
|
|
3470
4085
|
for (const line of lines) {
|
|
3471
4086
|
const port = parseListenPort(line);
|
|
3472
|
-
if (port !== null) settle(() =>
|
|
4087
|
+
if (port !== null) settle(() => resolve9(port));
|
|
3473
4088
|
}
|
|
3474
4089
|
});
|
|
3475
4090
|
void exited.then((detail) => {
|
|
@@ -3519,7 +4134,7 @@ async function startPackageAppDev(options) {
|
|
|
3519
4134
|
const errorPageTail = liveReload ? `<script>globalThis.__kodyDevErrorPage = true</script>${liveReloadScriptTag}` : "";
|
|
3520
4135
|
void sweepStaleDevDirs().catch(() => {
|
|
3521
4136
|
});
|
|
3522
|
-
const workDir = await mkdtemp(
|
|
4137
|
+
const workDir = await mkdtemp(join8(tmpdir2(), devWorkDirPrefix));
|
|
3523
4138
|
const reaper = await startProcessReaper({ workDir });
|
|
3524
4139
|
const workerdPath = options.workerdPath ?? await ensureWorkerdBinary({
|
|
3525
4140
|
onDownload: (url) => options.onStatus?.(`Downloading workerd from ${url}\u2026`)
|
|
@@ -3555,8 +4170,8 @@ async function startPackageAppDev(options) {
|
|
|
3555
4170
|
let buildFailureAt = startedAt;
|
|
3556
4171
|
let markStarted = () => {
|
|
3557
4172
|
};
|
|
3558
|
-
const started = new Promise((
|
|
3559
|
-
markStarted =
|
|
4173
|
+
const started = new Promise((resolve9) => {
|
|
4174
|
+
markStarted = resolve9;
|
|
3560
4175
|
});
|
|
3561
4176
|
const killAllSync = () => {
|
|
3562
4177
|
for (const generation of generations) {
|
|
@@ -3598,8 +4213,8 @@ async function startPackageAppDev(options) {
|
|
|
3598
4213
|
process.off("exit", killAllSync);
|
|
3599
4214
|
reaper.close();
|
|
3600
4215
|
proxy.closeAllConnections();
|
|
3601
|
-
await new Promise((
|
|
3602
|
-
proxy.close(() =>
|
|
4216
|
+
await new Promise((resolve9) => {
|
|
4217
|
+
proxy.close(() => resolve9());
|
|
3603
4218
|
});
|
|
3604
4219
|
await rm3(workDir, { recursive: true, force: true });
|
|
3605
4220
|
throw error;
|
|
@@ -3653,7 +4268,7 @@ async function startPackageAppDev(options) {
|
|
|
3653
4268
|
root,
|
|
3654
4269
|
externals: app.clientExternals
|
|
3655
4270
|
}) : null;
|
|
3656
|
-
const assetsDir = app.assets ?
|
|
4271
|
+
const assetsDir = app.assets ? resolve7(root, app.assets) : null;
|
|
3657
4272
|
const prebuild = options.manifest.dev?.prebuild;
|
|
3658
4273
|
let prebuildRunning = false;
|
|
3659
4274
|
let prebuildSettledAt = 0;
|
|
@@ -3687,7 +4302,7 @@ async function startPackageAppDev(options) {
|
|
|
3687
4302
|
const started2 = performance.now();
|
|
3688
4303
|
emit({
|
|
3689
4304
|
type: "rebuild_start",
|
|
3690
|
-
files: files.map((file) =>
|
|
4305
|
+
files: files.map((file) => relative5(root, file) || file)
|
|
3691
4306
|
});
|
|
3692
4307
|
const assetsChanged = assetsDir !== null && files.some(
|
|
3693
4308
|
(file) => file === assetsDir || file.startsWith(`${assetsDir}${sep3}`)
|
|
@@ -3806,7 +4421,7 @@ async function startPackageAppDev(options) {
|
|
|
3806
4421
|
}
|
|
3807
4422
|
async function startGeneration(bundle, client2) {
|
|
3808
4423
|
const id = ++generationCounter;
|
|
3809
|
-
const dir =
|
|
4424
|
+
const dir = join8(workDir, `g${id}`);
|
|
3810
4425
|
await writeWorkerFiles({
|
|
3811
4426
|
workDir: dir,
|
|
3812
4427
|
code: bundle.code,
|
|
@@ -3828,7 +4443,7 @@ async function startPackageAppDev(options) {
|
|
|
3828
4443
|
try {
|
|
3829
4444
|
workerd = await startWorkerd({
|
|
3830
4445
|
workerdPath,
|
|
3831
|
-
configPath:
|
|
4446
|
+
configPath: join8(dir, "config.capnp"),
|
|
3832
4447
|
cwd: dir,
|
|
3833
4448
|
env: workerdEnv,
|
|
3834
4449
|
onSpawn: (pid) => {
|
|
@@ -3907,7 +4522,7 @@ async function startPackageAppDev(options) {
|
|
|
3907
4522
|
pending.catch(() => {
|
|
3908
4523
|
}),
|
|
3909
4524
|
new Promise(
|
|
3910
|
-
(
|
|
4525
|
+
(resolve9) => setTimeout(resolve9, rebuildGateMs).unref()
|
|
3911
4526
|
)
|
|
3912
4527
|
]);
|
|
3913
4528
|
}
|
|
@@ -4041,7 +4656,7 @@ async function startPackageAppDev(options) {
|
|
|
4041
4656
|
[runSecretHeader]: runSecret,
|
|
4042
4657
|
[devRequestIdHeader]: tag.id
|
|
4043
4658
|
};
|
|
4044
|
-
return new Promise((
|
|
4659
|
+
return new Promise((resolve9, reject) => {
|
|
4045
4660
|
const upstream = httpRequest(
|
|
4046
4661
|
forwardUrl,
|
|
4047
4662
|
{ method: req.method, headers },
|
|
@@ -4049,7 +4664,7 @@ async function startPackageAppDev(options) {
|
|
|
4049
4664
|
if (upstreamRes.headers[devErrorHeader]) {
|
|
4050
4665
|
void readStream(upstreamRes).then((raw) => {
|
|
4051
4666
|
respondWithRuntimeError(generation, req, res, tag, raw);
|
|
4052
|
-
|
|
4667
|
+
resolve9();
|
|
4053
4668
|
}).catch(reject);
|
|
4054
4669
|
return;
|
|
4055
4670
|
}
|
|
@@ -4076,20 +4691,20 @@ async function startPackageAppDev(options) {
|
|
|
4076
4691
|
headers2["content-length"] = String(body.length);
|
|
4077
4692
|
res.writeHead(status2, headers2);
|
|
4078
4693
|
res.end(body);
|
|
4079
|
-
|
|
4694
|
+
resolve9();
|
|
4080
4695
|
}).catch(reject);
|
|
4081
4696
|
return;
|
|
4082
4697
|
}
|
|
4083
4698
|
res.writeHead(status2, upstreamRes.headers);
|
|
4084
4699
|
upstreamRes.pipe(res);
|
|
4085
|
-
upstreamRes.on("end", () =>
|
|
4700
|
+
upstreamRes.on("end", () => resolve9());
|
|
4086
4701
|
upstreamRes.on("error", reject);
|
|
4087
4702
|
}
|
|
4088
4703
|
);
|
|
4089
4704
|
upstream.on("error", reject);
|
|
4090
4705
|
res.on("close", () => {
|
|
4091
4706
|
if (!res.writableFinished) upstream.destroy();
|
|
4092
|
-
|
|
4707
|
+
resolve9();
|
|
4093
4708
|
});
|
|
4094
4709
|
req.pipe(upstream);
|
|
4095
4710
|
});
|
|
@@ -4138,10 +4753,10 @@ fix: ${fix}` : mapped,
|
|
|
4138
4753
|
pending.clear();
|
|
4139
4754
|
clearTimeout(debounceTimer);
|
|
4140
4755
|
debouncePending = false;
|
|
4141
|
-
const
|
|
4756
|
+
const resolve9 = resolveDebounceFlush;
|
|
4142
4757
|
resolveDebounceFlush = null;
|
|
4143
4758
|
debounceFlush = null;
|
|
4144
|
-
|
|
4759
|
+
resolve9?.();
|
|
4145
4760
|
};
|
|
4146
4761
|
return createDevWatcher({
|
|
4147
4762
|
root,
|
|
@@ -4163,8 +4778,8 @@ fix: ${fix}` : mapped,
|
|
|
4163
4778
|
pending.add(path);
|
|
4164
4779
|
debouncePending = true;
|
|
4165
4780
|
if (!debounceFlush) {
|
|
4166
|
-
debounceFlush = new Promise((
|
|
4167
|
-
resolveDebounceFlush =
|
|
4781
|
+
debounceFlush = new Promise((resolve9) => {
|
|
4782
|
+
resolveDebounceFlush = resolve9;
|
|
4168
4783
|
});
|
|
4169
4784
|
}
|
|
4170
4785
|
clearTimeout(debounceTimer);
|
|
@@ -4173,10 +4788,10 @@ fix: ${fix}` : mapped,
|
|
|
4173
4788
|
pending.clear();
|
|
4174
4789
|
debouncePending = false;
|
|
4175
4790
|
const build = requestBuild(paths);
|
|
4176
|
-
const
|
|
4791
|
+
const resolve9 = resolveDebounceFlush;
|
|
4177
4792
|
resolveDebounceFlush = null;
|
|
4178
4793
|
debounceFlush = null;
|
|
4179
|
-
|
|
4794
|
+
resolve9?.();
|
|
4180
4795
|
void build;
|
|
4181
4796
|
}, options.debounceMs ?? defaultDebounceMs);
|
|
4182
4797
|
}
|
|
@@ -4188,10 +4803,10 @@ fix: ${fix}` : mapped,
|
|
|
4188
4803
|
process.off("exit", killAllSync);
|
|
4189
4804
|
clearTimeout(debounceTimer);
|
|
4190
4805
|
debouncePending = false;
|
|
4191
|
-
const
|
|
4806
|
+
const resolve9 = resolveDebounceFlush;
|
|
4192
4807
|
resolveDebounceFlush = null;
|
|
4193
4808
|
debounceFlush = null;
|
|
4194
|
-
|
|
4809
|
+
resolve9?.();
|
|
4195
4810
|
prebuildAbort?.abort();
|
|
4196
4811
|
await watcher?.close();
|
|
4197
4812
|
await buildLoop?.catch(() => {
|
|
@@ -4205,8 +4820,8 @@ fix: ${fix}` : mapped,
|
|
|
4205
4820
|
await bridge.close();
|
|
4206
4821
|
liveReloadHub.close();
|
|
4207
4822
|
proxy.closeAllConnections();
|
|
4208
|
-
await new Promise((
|
|
4209
|
-
proxy.close(() =>
|
|
4823
|
+
await new Promise((resolve10) => {
|
|
4824
|
+
proxy.close(() => resolve10());
|
|
4210
4825
|
});
|
|
4211
4826
|
await rm3(workDir, { recursive: true, force: true });
|
|
4212
4827
|
};
|
|
@@ -4296,7 +4911,7 @@ async function writeWorkerFiles(input) {
|
|
|
4296
4911
|
input.workDir,
|
|
4297
4912
|
packageGraph,
|
|
4298
4913
|
writeFile3,
|
|
4299
|
-
|
|
4914
|
+
join8
|
|
4300
4915
|
);
|
|
4301
4916
|
let gatewayFetchShimModules = packageGraph.modules.map((module) => module.name).filter((name) => name === localExecuteGatewayFetchShimModuleName);
|
|
4302
4917
|
if (input.mockFetchGateway) {
|
|
@@ -4308,23 +4923,23 @@ async function writeWorkerFiles(input) {
|
|
|
4308
4923
|
gatewayFetchShimModules = installed.sideEffectModules;
|
|
4309
4924
|
}
|
|
4310
4925
|
await writeFile3(
|
|
4311
|
-
|
|
4926
|
+
join8(input.workDir, files.entry),
|
|
4312
4927
|
createPackageAppEntrySource({ sideEffectModules: gatewayFetchShimModules })
|
|
4313
4928
|
);
|
|
4314
|
-
await writeFile3(
|
|
4929
|
+
await writeFile3(join8(input.workDir, files.user), input.code);
|
|
4315
4930
|
await writeFile3(
|
|
4316
|
-
|
|
4931
|
+
join8(input.workDir, files.runtime),
|
|
4317
4932
|
createPackageLocalRuntimeModuleSource({
|
|
4318
4933
|
packageContext: input.packageContext,
|
|
4319
4934
|
mockStorage: input.mockStorage
|
|
4320
4935
|
})
|
|
4321
4936
|
);
|
|
4322
4937
|
await writeFile3(
|
|
4323
|
-
|
|
4938
|
+
join8(input.workDir, localWorkerModuleNames.runtimeFlatAlias),
|
|
4324
4939
|
createRuntimeFlatAliasSource()
|
|
4325
4940
|
);
|
|
4326
4941
|
await writeFile3(
|
|
4327
|
-
|
|
4942
|
+
join8(input.workDir, "config.capnp"),
|
|
4328
4943
|
createWorkerdConfig({
|
|
4329
4944
|
bridgePort: input.bridgePort,
|
|
4330
4945
|
files,
|
|
@@ -4474,7 +5089,7 @@ async function runDevServe(input) {
|
|
|
4474
5089
|
statusUrl
|
|
4475
5090
|
};
|
|
4476
5091
|
if (input.readyFile) {
|
|
4477
|
-
await mkdir3(
|
|
5092
|
+
await mkdir3(dirname4(input.readyFile), { recursive: true });
|
|
4478
5093
|
await writeFile4(input.readyFile, `${JSON.stringify(ready, null, 2)}
|
|
4479
5094
|
`);
|
|
4480
5095
|
}
|
|
@@ -4676,8 +5291,8 @@ async function runDevWebhook(input) {
|
|
|
4676
5291
|
target: input.target
|
|
4677
5292
|
});
|
|
4678
5293
|
}
|
|
4679
|
-
const rawBody = await
|
|
4680
|
-
|
|
5294
|
+
const rawBody = await readFile5(
|
|
5295
|
+
resolve8(input.cwd ?? process.cwd(), input.bodyPath),
|
|
4681
5296
|
"utf8"
|
|
4682
5297
|
);
|
|
4683
5298
|
let jsonBody = null;
|
|
@@ -4747,8 +5362,8 @@ async function runDevEmit(input) {
|
|
|
4747
5362
|
target: input.target
|
|
4748
5363
|
});
|
|
4749
5364
|
}
|
|
4750
|
-
const rawBody = await
|
|
4751
|
-
|
|
5365
|
+
const rawBody = await readFile5(
|
|
5366
|
+
resolve8(input.cwd ?? process.cwd(), input.bodyPath),
|
|
4752
5367
|
"utf8"
|
|
4753
5368
|
);
|
|
4754
5369
|
let envelope;
|
|
@@ -4805,8 +5420,14 @@ async function runDevCheck(input) {
|
|
|
4805
5420
|
const manifest = await loadPackageManifest(input.cwd);
|
|
4806
5421
|
const checks = [];
|
|
4807
5422
|
const credentialSignals = [];
|
|
4808
|
-
const
|
|
4809
|
-
|
|
5423
|
+
const fetchBodyHits = [];
|
|
5424
|
+
const push = (name, ok, detail, level) => {
|
|
5425
|
+
checks.push({
|
|
5426
|
+
name,
|
|
5427
|
+
ok,
|
|
5428
|
+
...detail !== void 0 ? { detail } : {},
|
|
5429
|
+
...level !== void 0 ? { level } : {}
|
|
5430
|
+
});
|
|
4810
5431
|
};
|
|
4811
5432
|
const bundleAndScan = async (label, modulePath) => {
|
|
4812
5433
|
try {
|
|
@@ -4815,6 +5436,12 @@ async function runDevCheck(input) {
|
|
|
4815
5436
|
credentialSignals.push(
|
|
4816
5437
|
...await detectCredentialedFetchInSource(bundled, label)
|
|
4817
5438
|
);
|
|
5439
|
+
fetchBodyHits.push(
|
|
5440
|
+
...await findPackageFetchBodyWarnings({
|
|
5441
|
+
entryPath: modulePath,
|
|
5442
|
+
packageRoot: manifest.root
|
|
5443
|
+
})
|
|
5444
|
+
);
|
|
4818
5445
|
} catch (error) {
|
|
4819
5446
|
push(label, false, error instanceof Error ? error.message : String(error));
|
|
4820
5447
|
}
|
|
@@ -4822,13 +5449,13 @@ async function runDevCheck(input) {
|
|
|
4822
5449
|
push("package.json", true, manifest.name);
|
|
4823
5450
|
push("kody.id", Boolean(manifest.kodyId), manifest.kodyId);
|
|
4824
5451
|
try {
|
|
4825
|
-
await
|
|
5452
|
+
await readFile5(resolve8(manifest.root, "README.md"));
|
|
4826
5453
|
push("README.md", true);
|
|
4827
5454
|
} catch {
|
|
4828
5455
|
push("README.md", false, "Publish requires README.md");
|
|
4829
5456
|
}
|
|
4830
5457
|
try {
|
|
4831
|
-
await
|
|
5458
|
+
await readFile5(resolve8(manifest.root, "AGENTS.md"));
|
|
4832
5459
|
push("AGENTS.md", true);
|
|
4833
5460
|
} catch {
|
|
4834
5461
|
push("AGENTS.md", false, "Publish requires AGENTS.md");
|
|
@@ -4861,7 +5488,7 @@ async function runDevCheck(input) {
|
|
|
4861
5488
|
}
|
|
4862
5489
|
let hasMocksFile = false;
|
|
4863
5490
|
try {
|
|
4864
|
-
await access(
|
|
5491
|
+
await access(join9(manifest.root, packageMocksRelativePath));
|
|
4865
5492
|
hasMocksFile = true;
|
|
4866
5493
|
} catch {
|
|
4867
5494
|
hasMocksFile = false;
|
|
@@ -4873,6 +5500,12 @@ async function runDevCheck(input) {
|
|
|
4873
5500
|
if (mocksDetail) {
|
|
4874
5501
|
push(packageMocksRelativePath, true, mocksDetail);
|
|
4875
5502
|
}
|
|
5503
|
+
const fetchBodyWarning = formatFetchBodySecretResolutionWarning(
|
|
5504
|
+
dedupeFetchBodyHits(fetchBodyHits)
|
|
5505
|
+
);
|
|
5506
|
+
if (fetchBodyWarning) {
|
|
5507
|
+
push("secret-resolution", true, fetchBodyWarning, "warning");
|
|
5508
|
+
}
|
|
4876
5509
|
const failed = checks.filter((check) => !check.ok);
|
|
4877
5510
|
if (input.json) {
|
|
4878
5511
|
input.io.stdout(
|
|
@@ -4896,7 +5529,7 @@ async function runDevCheck(input) {
|
|
|
4896
5529
|
);
|
|
4897
5530
|
} else {
|
|
4898
5531
|
for (const check of checks) {
|
|
4899
|
-
const mark = check.ok ? "
|
|
5532
|
+
const mark = !check.ok ? "FAIL" : check.level === "warning" ? "WARN" : "ok";
|
|
4900
5533
|
input.io.stdout(
|
|
4901
5534
|
`${mark.padEnd(4)} ${check.name}${check.detail ? ` \u2014 ${check.detail}` : ""}
|
|
4902
5535
|
`
|
|
@@ -4910,6 +5543,17 @@ async function runDevCheck(input) {
|
|
|
4910
5543
|
}
|
|
4911
5544
|
return failed.length === 0 ? 0 : 1;
|
|
4912
5545
|
}
|
|
5546
|
+
function dedupeFetchBodyHits(hits) {
|
|
5547
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5548
|
+
const unique = [];
|
|
5549
|
+
for (const hit of hits) {
|
|
5550
|
+
const key = `${hit.path}:${hit.line}`;
|
|
5551
|
+
if (seen.has(key)) continue;
|
|
5552
|
+
seen.add(key);
|
|
5553
|
+
unique.push(hit);
|
|
5554
|
+
}
|
|
5555
|
+
return unique;
|
|
5556
|
+
}
|
|
4913
5557
|
async function runPackageModuleOnce(input) {
|
|
4914
5558
|
const packageContext = buildLocalPackageContext({
|
|
4915
5559
|
kodyId: input.manifest.kodyId,
|
|
@@ -4998,7 +5642,7 @@ function parseDevSubcommand(positionals) {
|
|
|
4998
5642
|
}
|
|
4999
5643
|
async function removeOwnedReadyFile(path, ownerPid) {
|
|
5000
5644
|
try {
|
|
5001
|
-
const parsed = JSON.parse(await
|
|
5645
|
+
const parsed = JSON.parse(await readFile5(path, "utf8"));
|
|
5002
5646
|
if (parsed.pid !== ownerPid) return;
|
|
5003
5647
|
await rm4(path, { force: true });
|
|
5004
5648
|
} catch {
|
|
@@ -5022,4 +5666,4 @@ export {
|
|
|
5022
5666
|
chokidar/esm/index.js:
|
|
5023
5667
|
(*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
|
|
5024
5668
|
*/
|
|
5025
|
-
//# sourceMappingURL=dev-command-
|
|
5669
|
+
//# sourceMappingURL=dev-command-PCQDX5EH.js.map
|