cajonzero 0.1.2 → 0.1.3

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/scaffold.js CHANGED
@@ -1,7 +1,8 @@
1
- import { readFileSync, existsSync, statSync, mkdirSync, writeFileSync, readdirSync } from 'fs';
2
- import path from 'path';
1
+ import { readFileSync, existsSync, statSync, mkdirSync, writeFileSync, renameSync, rmSync, cpSync, readdirSync } from 'fs';
2
+ import path3 from 'path';
3
3
  import { fileURLToPath } from 'url';
4
- import { randomBytes } from 'crypto';
4
+ import { randomBytes, createHash } from 'crypto';
5
+ import { createRequire } from 'module';
5
6
 
6
7
  // src/scaffold/templates.ts
7
8
  var SCAFFOLD_ENTRY_PATH = "src/index.ts";
@@ -71,7 +72,7 @@ var SCAFFOLD_CONFIG_CONTENT = `${JSON.stringify(
71
72
  `;
72
73
  var SCAFFOLD_MAPS_CONTENT = `${JSON.stringify({ version: 1, maps: [] }, null, 2)}
73
74
  `;
74
- var SHIP_UI_SCRIPT = `node -e "const fs=require('node:fs'),p=require('node:path');fs.cpSync(p.join(p.dirname(require.resolve('cajonzero/package.json')),'dist','ui'),p.join('dist','ui'),{recursive:true,force:true})"`;
75
+ var PREPARE_ASSETS = "cj0 worker prepare";
75
76
  function packageJson(options) {
76
77
  const manifest = {
77
78
  name: options.packageName,
@@ -79,12 +80,14 @@ function packageJson(options) {
79
80
  private: true,
80
81
  type: "module",
81
82
  scripts: {
82
- dev: `${SHIP_UI_SCRIPT} && wrangler dev`,
83
- build: `${SHIP_UI_SCRIPT} && wrangler deploy --dry-run`,
84
- deploy: `${SHIP_UI_SCRIPT} && wrangler deploy`,
83
+ dev: `${PREPARE_ASSETS} && wrangler dev`,
84
+ build: `${PREPARE_ASSETS} && cj0 worker build-seed && wrangler deploy --dry-run`,
85
+ // Deploy always rebuilds: map content can change without `version` being
86
+ // bumped, and the room prefers the pack over the live CDN graph.
87
+ deploy: `${PREPARE_ASSETS} && cj0 worker build-seed --force && wrangler deploy`,
85
88
  // `prepare` also runs after `npm install`, so a plain install leaves a
86
- // ready-to-deploy project.
87
- prepare: SHIP_UI_SCRIPT
89
+ // ready-to-deploy project. Seed packs are network work and stay out of it.
90
+ prepare: PREPARE_ASSETS
88
91
  },
89
92
  dependencies: {
90
93
  cajonzero: options.cajonzeroRange,
@@ -113,6 +116,8 @@ function wranglerConfig(options) {
113
116
  " // cajonzero ships the built assets into this directory.",
114
117
  ' "assets": {',
115
118
  ' "directory": "dist/ui",',
119
+ " // Binding so the room can read seed packs bundled at deploy time.",
120
+ ' "binding": "ASSETS",',
116
121
  " // History routing: deep links (/play/x, /admin/bans) boot index.html.",
117
122
  ' "not_found_handling": "single-page-application",',
118
123
  ' "run_worker_first": ["/api/*", "/runtime/*"]',
@@ -163,17 +168,18 @@ function readme(options) {
163
168
  "",
164
169
  "```bash",
165
170
  "npm install",
166
- "npx cj0 setup # \u4EA4\u4E92\u5F0F\u914D\u7F6E\u5FC5\u9700/\u53EF\u9009\u7684 ENV",
171
+ "npx cj0 setup # \u4EA4\u4E92\u5F0F\u914D\u7F6E ENV + KV namespace",
167
172
  "npm run dev # http://localhost:8787",
168
173
  "```",
169
174
  "",
170
175
  "## \u73AF\u5883\u53D8\u91CF",
171
176
  "",
172
177
  "`cj0 setup` \u628A\u975E\u5BC6\u94A5\u5199\u5165 `wrangler.jsonc` \u7684 `vars`\uFF0C\u628A\u5BC6\u94A5\u5199\u5165 `.dev.vars`\uFF08\u672C\u5730\uFF09\u3002",
173
- "\u90E8\u7F72\u65F6\u5BC6\u94A5\u8981\u5355\u72EC\u8BBE\u7F6E\uFF1A",
178
+ "KV namespace \u4E5F\u7531 `cj0 setup` \u914D\u7F6E\uFF1A\u56DE\u8F66\u4F1A\u81EA\u52A8\u8C03\u7528 wrangler \u521B\u5EFA\u5E76\u5199\u56DE id\uFF08\u9700\u5148\u767B\u5F55\uFF09\uFF0C",
179
+ "\u4E5F\u53EF\u4EE5\u7C98\u8D34\u5DF2\u6709 id\u3002\u79BB\u7EBF\u65F6\u624B\u52A8\u8FD0\u884C\uFF1A",
174
180
  "",
175
181
  "```bash",
176
- "npx wrangler kv namespace create CAJONZERO_KV # id \u586B\u8FDB wrangler.jsonc",
182
+ "npx wrangler kv namespace create <name> --update-config --binding CAJONZERO_KV",
177
183
  "npx wrangler secret put CAJONZERO_SESSION_SECRET",
178
184
  "npx wrangler secret put BOX_PLAY_ADMIN_TOKEN",
179
185
  "```",
@@ -264,7 +270,7 @@ function readCajonzeroPackage(manifestPath) {
264
270
  return { version, wranglerRange, unstorageRange };
265
271
  }
266
272
  function toPackageName(folder) {
267
- const base = path.basename(folder);
273
+ const base = path3.basename(folder);
268
274
  const slug = base.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-._]+/, "").replace(/[-._]+$/, "");
269
275
  return slug.length > 0 ? slug : "cajonzero-app";
270
276
  }
@@ -279,7 +285,7 @@ function createProject(folder, options = {}) {
279
285
  throw new ScaffoldError("INVALID_TARGET", "create requires a target folder");
280
286
  }
281
287
  const cwd = options.cwd ?? process.cwd();
282
- const target = path.resolve(cwd, name);
288
+ const target = path3.resolve(cwd, name);
283
289
  if (existsSync(target) && !statSync(target).isDirectory()) {
284
290
  throw new ScaffoldError("INVALID_TARGET", `target exists and is not a directory: ${target}`);
285
291
  }
@@ -302,8 +308,8 @@ function createProject(folder, options = {}) {
302
308
  });
303
309
  mkdirSync(target, { recursive: true });
304
310
  for (const file of files) {
305
- const fullPath = path.join(target, file.path);
306
- mkdirSync(path.dirname(fullPath), { recursive: true });
311
+ const fullPath = path3.join(target, file.path);
312
+ mkdirSync(path3.dirname(fullPath), { recursive: true });
307
313
  writeFileSync(fullPath, file.content, "utf8");
308
314
  }
309
315
  return { target, files: files.map((file) => file.path) };
@@ -388,6 +394,13 @@ var SETUP_FIELDS = [
388
394
  required: true,
389
395
  hint: "\u7559\u7A7A\u81EA\u52A8\u751F\u6210\uFF1B\u672C\u5730\u5199\u5165 .dev.vars"
390
396
  },
397
+ {
398
+ name: "CAJONZERO_KV_ID",
399
+ label: "KV namespace id",
400
+ kind: "kv",
401
+ required: true,
402
+ hint: "\u56DE\u8F66\u81EA\u52A8\u521B\u5EFA\uFF08\u9700 wrangler \u767B\u5F55\uFF09\u6216\u7C98\u8D34\u5DF2\u6709 id"
403
+ },
391
404
  {
392
405
  name: "CAJONZERO_ENV",
393
406
  label: "\u90E8\u7F72\u540D\u79F0",
@@ -435,10 +448,11 @@ function serializeDevVars(values) {
435
448
  return `${lines.join("\n")}
436
449
  `;
437
450
  }
438
- function findVarsBlock(raw) {
439
- const match = /"vars"\s*:\s*\{/.exec(raw);
451
+ function findKeyBlock(raw, key, openChar) {
452
+ const closeChar = openChar === "{" ? "}" : "]";
453
+ const match = new RegExp(`"${key}"\\s*:\\s*\\${openChar}`).exec(raw);
440
454
  if (match === null) return null;
441
- const open = raw.indexOf("{", match.index);
455
+ const open = raw.indexOf(openChar, match.index);
442
456
  let depth = 0;
443
457
  let inString = false;
444
458
  let escaped = false;
@@ -451,8 +465,8 @@ function findVarsBlock(raw) {
451
465
  continue;
452
466
  }
453
467
  if (ch === '"') inString = true;
454
- else if (ch === "{") depth += 1;
455
- else if (ch === "}") {
468
+ else if (ch === openChar) depth += 1;
469
+ else if (ch === closeChar) {
456
470
  depth -= 1;
457
471
  if (depth === 0) {
458
472
  const lineStart = raw.lastIndexOf("\n", match.index) + 1;
@@ -463,7 +477,10 @@ function findVarsBlock(raw) {
463
477
  }
464
478
  return null;
465
479
  }
466
- function parseJsoncObject(text) {
480
+ function findVarsBlock(raw) {
481
+ return findKeyBlock(raw, "vars", "{");
482
+ }
483
+ function stripJsoncComments(text) {
467
484
  let out = "";
468
485
  let inString = false;
469
486
  let escaped = false;
@@ -494,13 +511,95 @@ function parseJsoncObject(text) {
494
511
  }
495
512
  out += ch;
496
513
  }
497
- out = out.replace(/,(\s*[}\]])/g, "$1");
514
+ return out;
515
+ }
516
+ function parseJsonc(text) {
498
517
  try {
499
- const parsed = JSON.parse(out);
500
- return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
518
+ const clean = text.replace(/^\uFEFF/, "");
519
+ return JSON.parse(stripJsoncComments(clean).replace(/,(\s*[}\]])/g, "$1"));
501
520
  } catch {
502
- return {};
521
+ return void 0;
522
+ }
523
+ }
524
+ function parseJsoncObject(text) {
525
+ const parsed = parseJsonc(text);
526
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
527
+ }
528
+ function parseJsoncArray(text) {
529
+ const parsed = parseJsonc(text);
530
+ return Array.isArray(parsed) ? parsed : [];
531
+ }
532
+ function escapeRegExp(text) {
533
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
534
+ }
535
+ function findBindingObject(raw, block, binding) {
536
+ const bindingPattern = new RegExp(`"binding"\\s*:\\s*"${escapeRegExp(binding)}"`);
537
+ const stack = [];
538
+ let inString = false;
539
+ let escaped = false;
540
+ for (let i = block.open; i <= block.close; i += 1) {
541
+ const ch = raw[i];
542
+ if (inString) {
543
+ if (escaped) escaped = false;
544
+ else if (ch === "\\") escaped = true;
545
+ else if (ch === '"') inString = false;
546
+ continue;
547
+ }
548
+ if (ch === '"') inString = true;
549
+ else if (ch === "{") stack.push(i);
550
+ else if (ch === "}") {
551
+ const start = stack.pop();
552
+ if (start !== void 0 && bindingPattern.test(raw.slice(start, i + 1))) {
553
+ const lineStart = raw.lastIndexOf("\n", start) + 1;
554
+ const indent = /^\s*/.exec(raw.slice(lineStart, start))?.[0] ?? " ";
555
+ return { start, end: i + 1, indent };
556
+ }
557
+ }
503
558
  }
559
+ return null;
560
+ }
561
+ function readWranglerKvNamespaceId(raw, binding = "CAJONZERO_KV") {
562
+ const block = findKeyBlock(raw, "kv_namespaces", "[");
563
+ if (block === null) return void 0;
564
+ const entries = parseJsoncArray(raw.slice(block.open, block.close + 1));
565
+ for (const entry of entries) {
566
+ if (typeof entry !== "object" || entry === null) continue;
567
+ const record = entry;
568
+ if (record["binding"] !== binding) continue;
569
+ const id = record["id"];
570
+ return typeof id === "string" && id.length > 0 ? id : void 0;
571
+ }
572
+ return void 0;
573
+ }
574
+ function setWranglerKvNamespaceId(raw, binding, id) {
575
+ const block = findKeyBlock(raw, "kv_namespaces", "[");
576
+ if (block !== null) {
577
+ const entry = findBindingObject(raw, block, binding);
578
+ if (entry !== null) {
579
+ const entryText = raw.slice(entry.start, entry.end);
580
+ const nextEntry = /"id"\s*:/.test(entryText) ? entryText.replace(/("id"\s*:\s*)"(?:[^"\\]|\\.)*"/, `$1${JSON.stringify(id)}`) : entryText.replace(
581
+ /("binding"\s*:\s*"(?:[^"\\]|\\.)*")/,
582
+ `$1,
583
+ ${entry.indent}"id": ${JSON.stringify(id)}`
584
+ );
585
+ return raw.slice(0, entry.start) + nextEntry + raw.slice(entry.end);
586
+ }
587
+ }
588
+ const existing = block === null ? [] : parseJsoncArray(raw.slice(block.open, block.close + 1));
589
+ const filtered = existing.filter(
590
+ (entry) => !(typeof entry === "object" && entry !== null && entry["binding"] === binding)
591
+ );
592
+ const indent = block?.indent ?? " ";
593
+ const arrayText = JSON.stringify([...filtered, { binding, id }], null, 2).split("\n").map((line, index) => index === 0 ? line : `${indent}${line}`).join("\n");
594
+ if (block !== null) {
595
+ return raw.slice(0, block.open) + arrayText + raw.slice(block.close + 1);
596
+ }
597
+ const close = raw.lastIndexOf("}");
598
+ if (close < 0) throw new Error("wrangler config is not a JSON object");
599
+ const body = raw.slice(0, close).trimEnd();
600
+ const separator = body.endsWith("{") || body.endsWith(",") ? "\n" : ",\n";
601
+ return `${body}${separator}${indent}"kv_namespaces": ${arrayText}
602
+ ${raw.slice(close)}`;
504
603
  }
505
604
  function setWranglerVars(raw, vars) {
506
605
  const managed = new Set(SETUP_FIELDS.filter((f) => f.kind === "var").map((f) => f.name));
@@ -543,26 +642,33 @@ function readSetupValues(cwd, configPath, devVarsPath) {
543
642
  if (typeof value === "string") out[key] = value;
544
643
  }
545
644
  }
645
+ const kvId = readWranglerKvNamespaceId(raw);
646
+ if (kvId !== void 0 && kvId !== SCAFFOLD_KV_PLACEHOLDER_ID) {
647
+ out["CAJONZERO_KV_ID"] = kvId;
648
+ }
546
649
  }
547
650
  return out;
548
651
  }
549
652
  function applySetup(options) {
550
653
  const cwd = options.cwd ?? process.cwd();
551
- const configPath = path.resolve(cwd, options.configPath ?? "wrangler.jsonc");
552
- const devVarsPath = path.join(path.dirname(configPath), ".dev.vars");
654
+ const configPath = path3.resolve(cwd, options.configPath ?? "wrangler.jsonc");
655
+ const devVarsPath = path3.join(path3.dirname(configPath), ".dev.vars");
553
656
  if (!existsSync(configPath)) {
554
- throw new Error(`\u627E\u4E0D\u5230 ${path.basename(configPath)}\uFF0C\u8BF7\u5728 cj0 create \u751F\u6210\u7684\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C`);
657
+ throw new Error(`\u627E\u4E0D\u5230 ${path3.basename(configPath)}\uFF0C\u8BF7\u5728 cj0 create \u751F\u6210\u7684\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C`);
555
658
  }
556
659
  const vars = {};
557
660
  const secrets = {};
661
+ let kvId;
558
662
  for (const field of SETUP_FIELDS) {
559
663
  const value = options.values[field.name]?.trim();
560
664
  if (value === void 0 || value.length === 0) continue;
561
665
  if (field.kind === "secret") secrets[field.name] = value;
666
+ else if (field.kind === "kv") kvId = value;
562
667
  else vars[field.name] = value;
563
668
  }
564
669
  const raw = readFileSync(configPath, "utf8");
565
- const next = setWranglerVars(raw, vars);
670
+ let next = setWranglerVars(raw, vars);
671
+ if (kvId !== void 0) next = setWranglerKvNamespaceId(next, "CAJONZERO_KV", kvId);
566
672
  if (next !== raw) writeFileSync(configPath, next, "utf8");
567
673
  const existingDev = existsSync(devVarsPath) ? parseDevVars(readFileSync(devVarsPath, "utf8")) : {};
568
674
  const managedSecrets = new Set(
@@ -574,9 +680,164 @@ function applySetup(options) {
574
680
  }
575
681
  Object.assign(mergedDev, secrets);
576
682
  writeFileSync(devVarsPath, serializeDevVars(mergedDev), "utf8");
577
- return { configPath, devVarsPath, vars, secrets };
683
+ return { configPath, devVarsPath, vars, secrets, ...kvId !== void 0 ? { kvId } : {} };
684
+ }
685
+ var ASSETS_STAMP_FILE = ".cajonzero-assets.json";
686
+ var ASSETS_SEED_DIR = "seed";
687
+ var DEFAULT_CONFIG = "wrangler.jsonc";
688
+ function resolvePackageRoot() {
689
+ try {
690
+ return path3.dirname(createRequire(import.meta.url).resolve("cajonzero/package.json"));
691
+ } catch {
692
+ return path3.dirname(fileURLToPath(new URL("../../package.json", import.meta.url)));
693
+ }
694
+ }
695
+ function readPackageVersion(root) {
696
+ try {
697
+ const parsed = JSON.parse(readFileSync(path3.join(root, "package.json"), "utf8"));
698
+ return typeof parsed.version === "string" ? parsed.version : void 0;
699
+ } catch {
700
+ return void 0;
701
+ }
702
+ }
703
+ function readWranglerAssetsDirectory(configPath) {
704
+ if (!existsSync(configPath)) {
705
+ throw new Error(`\u627E\u4E0D\u5230 ${path3.basename(configPath)}\uFF0C\u8BF7\u5728 cj0 create \u751F\u6210\u7684\u9879\u76EE\u76EE\u5F55\u4E2D\u8FD0\u884C`);
706
+ }
707
+ const ext = path3.extname(configPath).toLowerCase();
708
+ if (ext !== ".json" && ext !== ".jsonc") {
709
+ throw new Error(
710
+ `\u4E0D\u652F\u6301\u8BFB\u53D6 ${path3.basename(configPath)}\uFF08\u53EA\u652F\u6301 JSON/JSONC wrangler \u914D\u7F6E\uFF1B\u7528 --assets \u6307\u5B9A\u76EE\u5F55\uFF09`
711
+ );
712
+ }
713
+ const parsed = parseJsoncObject(readFileSync(configPath, "utf8"));
714
+ const assets = parsed["assets"];
715
+ if (typeof assets === "object" && assets !== null && !Array.isArray(assets)) {
716
+ const directory = assets["directory"];
717
+ if (typeof directory === "string" && directory.length > 0) return directory;
718
+ }
719
+ return void 0;
720
+ }
721
+ function fingerprintTree(dir) {
722
+ const entries = [];
723
+ const walk = (relative) => {
724
+ const absolute = relative.length === 0 ? dir : path3.join(dir, relative);
725
+ for (const entry of readdirSync(absolute, { withFileTypes: true })) {
726
+ if (entry.name === ASSETS_STAMP_FILE) continue;
727
+ const child = relative.length === 0 ? entry.name : `${relative}/${entry.name}`;
728
+ if (entry.isDirectory()) walk(child);
729
+ else if (entry.isFile()) entries.push(child);
730
+ }
731
+ };
732
+ walk("");
733
+ entries.sort();
734
+ const hash = createHash("sha256");
735
+ let bytes = 0;
736
+ for (const relative of entries) {
737
+ const content = readFileSync(path3.join(dir, relative));
738
+ bytes += content.length;
739
+ hash.update(relative);
740
+ hash.update("\0");
741
+ hash.update(content);
742
+ hash.update("\0");
743
+ }
744
+ return { files: entries.length, bytes, hash: hash.digest("hex") };
745
+ }
746
+ function readStamp(targetDir) {
747
+ try {
748
+ const parsed = JSON.parse(
749
+ readFileSync(path3.join(targetDir, ASSETS_STAMP_FILE), "utf8")
750
+ );
751
+ if (parsed.version !== 1 || typeof parsed.fingerprint !== "string") return void 0;
752
+ return { version: 1, fingerprint: parsed.fingerprint, packageVersion: parsed.packageVersion };
753
+ } catch {
754
+ return void 0;
755
+ }
756
+ }
757
+ function assertSafeTarget(targetDir, sourceDir, configDir) {
758
+ const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path3.sep}`);
759
+ if (targetDir === path3.parse(targetDir).root) {
760
+ throw new Error(`\u62D2\u7EDD\u628A\u6587\u4EF6\u7CFB\u7EDF\u6839\u76EE\u5F55\u4F5C\u4E3A assets \u76EE\u5F55\uFF1A${targetDir}`);
761
+ }
762
+ if (contains(targetDir, configDir) || contains(targetDir, sourceDir) || contains(sourceDir, targetDir)) {
763
+ throw new Error(`assets \u76EE\u5F55\u4E0D\u80FD\u5305\u542B\u9879\u76EE\u914D\u7F6E/cajonzero \u8D44\u6E90\u76EE\u5F55\uFF1A${targetDir}`);
764
+ }
765
+ }
766
+ async function prepareWorkerAssets(options = {}) {
767
+ const cwd = options.cwd ?? process.cwd();
768
+ const configPath = path3.resolve(cwd, options.configPath ?? DEFAULT_CONFIG);
769
+ const configDir = path3.dirname(configPath);
770
+ const packageRoot = resolvePackageRoot();
771
+ const sourceDir = path3.resolve(options.sourceDir ?? path3.join(packageRoot, "dist", "ui"));
772
+ if (!existsSync(sourceDir)) {
773
+ throw new Error(
774
+ `cajonzero \u7684 UI \u8D44\u6E90\u7F3A\u5931\uFF1A${sourceDir}\uFF08\u8BF7\u91CD\u65B0\u5B89\u88C5 cajonzero\uFF0C\u6216\u5728\u6E90\u7801\u4ED3\u5E93\u5148 npm run build\uFF09`
775
+ );
776
+ }
777
+ const configured = options.assetsDir ?? readWranglerAssetsDirectory(configPath);
778
+ if (configured === void 0) {
779
+ throw new Error(
780
+ `${path3.basename(configPath)} \u672A\u914D\u7F6E assets.directory\uFF1B\u7528 --assets <dir> \u6307\u5B9A\u8F93\u51FA\u76EE\u5F55`
781
+ );
782
+ }
783
+ const targetDir = path3.resolve(configDir, configured);
784
+ assertSafeTarget(targetDir, sourceDir, configDir);
785
+ const source = fingerprintTree(sourceDir);
786
+ const stamp = readStamp(targetDir);
787
+ if (!options.force && stamp?.fingerprint === source.hash && existsSync(targetDir)) {
788
+ return {
789
+ sourceDir,
790
+ targetDir,
791
+ fingerprint: source.hash,
792
+ copied: false,
793
+ files: source.files,
794
+ bytes: source.bytes
795
+ };
796
+ }
797
+ const seedDir = path3.join(targetDir, ASSETS_SEED_DIR);
798
+ const seedBackup = `${targetDir}.${ASSETS_SEED_DIR}-backup`;
799
+ if (!existsSync(seedDir) && existsSync(seedBackup)) {
800
+ mkdirSync(path3.dirname(seedDir), { recursive: true });
801
+ renameSync(seedBackup, seedDir);
802
+ }
803
+ let hasSeed = false;
804
+ if (existsSync(seedDir)) {
805
+ rmSync(seedBackup, { recursive: true, force: true });
806
+ renameSync(seedDir, seedBackup);
807
+ hasSeed = true;
808
+ }
809
+ try {
810
+ rmSync(targetDir, { recursive: true, force: true });
811
+ mkdirSync(targetDir, { recursive: true });
812
+ cpSync(sourceDir, targetDir, {
813
+ recursive: true,
814
+ force: true,
815
+ filter: (from) => path3.basename(from) !== ASSETS_STAMP_FILE
816
+ });
817
+ } finally {
818
+ if (hasSeed && existsSync(seedBackup)) {
819
+ mkdirSync(targetDir, { recursive: true });
820
+ rmSync(seedDir, { recursive: true, force: true });
821
+ renameSync(seedBackup, seedDir);
822
+ }
823
+ }
824
+ const next = {
825
+ version: 1,
826
+ fingerprint: source.hash,
827
+ packageVersion: readPackageVersion(packageRoot)
828
+ };
829
+ writeFileSync(path3.join(targetDir, ASSETS_STAMP_FILE), `${JSON.stringify(next, null, 2)}
830
+ `, "utf8");
831
+ return {
832
+ sourceDir,
833
+ targetDir,
834
+ fingerprint: source.hash,
835
+ copied: true,
836
+ files: source.files,
837
+ bytes: source.bytes
838
+ };
578
839
  }
579
840
 
580
- export { SCAFFOLD_COMPATIBILITY_DATE, SCAFFOLD_CONFIG_CONTENT, SCAFFOLD_ENTRY_CONTENT, SCAFFOLD_ENTRY_PATH, SCAFFOLD_KV_PLACEHOLDER_ID, SCAFFOLD_MAPS_CONTENT, SETUP_FIELDS, ScaffoldError, applySetup, buildScaffoldFiles, createProject, generateAdminToken, generateSecret, parseDevVars, readCajonzeroPackage, readSetupValues, serializeDevVars, setWranglerVars, suggestedValue, toPackageName };
841
+ export { ASSETS_SEED_DIR, ASSETS_STAMP_FILE, SCAFFOLD_COMPATIBILITY_DATE, SCAFFOLD_CONFIG_CONTENT, SCAFFOLD_ENTRY_CONTENT, SCAFFOLD_ENTRY_PATH, SCAFFOLD_KV_PLACEHOLDER_ID, SCAFFOLD_MAPS_CONTENT, SETUP_FIELDS, ScaffoldError, applySetup, buildScaffoldFiles, createProject, generateAdminToken, generateSecret, parseDevVars, parseJsoncObject, prepareWorkerAssets, readCajonzeroPackage, readSetupValues, readWranglerAssetsDirectory, readWranglerKvNamespaceId, serializeDevVars, setWranglerKvNamespaceId, setWranglerVars, suggestedValue, toPackageName };
581
842
  //# sourceMappingURL=scaffold.js.map
582
843
  //# sourceMappingURL=scaffold.js.map
package/dist/serve.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ExecutionContext } from 'hono';
2
- import { R as Room, D as DurableObjectNamespace, b as Env } from './providers-BX7e4pNW.js';
2
+ import { R as Room, D as DurableObjectNamespace, b as Env } from './providers-BwJKzGkd.js';
3
3
  import { StorageSource, EnvProvider, SettingDefaults } from './core.js';
4
4
  import 'unstorage';
5
5
  import 'gl-matrix';