everything-dev 2.0.0-rc.6 → 2.0.0-rc.7

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.
Files changed (116) hide show
  1. package/README.md +2 -2
  2. package/dist/build.cjs +1 -1
  3. package/dist/build.mjs +1 -1
  4. package/dist/bundle-cache.cjs +1 -1
  5. package/dist/bundle-cache.cjs.map +1 -1
  6. package/dist/bundle-cache.mjs +1 -1
  7. package/dist/bundle-cache.mjs.map +1 -1
  8. package/dist/cli.cjs +2 -2
  9. package/dist/cli.cjs.map +1 -1
  10. package/dist/cli.mjs +1 -1
  11. package/dist/cli.mjs.map +1 -1
  12. package/dist/commands/deploy.cjs +111 -1
  13. package/dist/commands/deploy.cjs.map +1 -1
  14. package/dist/commands/deploy.mjs +112 -2
  15. package/dist/commands/deploy.mjs.map +1 -1
  16. package/dist/commands/smoke.cjs +41 -0
  17. package/dist/commands/smoke.cjs.map +1 -0
  18. package/dist/commands/smoke.mjs +41 -0
  19. package/dist/commands/smoke.mjs.map +1 -0
  20. package/dist/commands/upgrade.cjs +2 -2
  21. package/dist/commands/upgrade.cjs.map +1 -1
  22. package/dist/commands/upgrade.mjs +1 -1
  23. package/dist/commands/upgrade.mjs.map +1 -1
  24. package/dist/contract.cjs +27 -1
  25. package/dist/contract.cjs.map +1 -1
  26. package/dist/contract.d.cts +65 -1
  27. package/dist/contract.d.mts +65 -1
  28. package/dist/contract.meta.cjs +13 -1
  29. package/dist/contract.meta.cjs.map +1 -1
  30. package/dist/contract.meta.d.cts +23 -1
  31. package/dist/contract.meta.d.mts +23 -1
  32. package/dist/contract.meta.mjs +13 -1
  33. package/dist/contract.meta.mjs.map +1 -1
  34. package/dist/contract.mjs +26 -2
  35. package/dist/contract.mjs.map +1 -1
  36. package/dist/dev-log-pipeline.cjs +6 -0
  37. package/dist/dev-log-pipeline.cjs.map +1 -1
  38. package/dist/dev-log-pipeline.mjs +6 -0
  39. package/dist/dev-log-pipeline.mjs.map +1 -1
  40. package/dist/dev-program.cjs +20 -3
  41. package/dist/dev-program.cjs.map +1 -1
  42. package/dist/dev-program.mjs +20 -4
  43. package/dist/dev-program.mjs.map +1 -1
  44. package/dist/dev-session.cjs +1 -0
  45. package/dist/dev-session.cjs.map +1 -1
  46. package/dist/dev-session.mjs +1 -0
  47. package/dist/dev-session.mjs.map +1 -1
  48. package/dist/fastkv.cjs +21 -3
  49. package/dist/fastkv.cjs.map +1 -1
  50. package/dist/fastkv.d.cts +14 -1
  51. package/dist/fastkv.d.mts +14 -1
  52. package/dist/fastkv.mjs +21 -5
  53. package/dist/fastkv.mjs.map +1 -1
  54. package/dist/{mf.cjs → federation.cjs} +6 -13
  55. package/dist/federation.cjs.map +1 -0
  56. package/dist/{mf.d.cts → federation.d.cts} +2 -2
  57. package/dist/{mf.d.mts → federation.d.mts} +2 -2
  58. package/dist/{mf.mjs → federation.mjs} +6 -13
  59. package/dist/federation.mjs.map +1 -0
  60. package/dist/http-client.cjs +70 -53
  61. package/dist/http-client.cjs.map +1 -1
  62. package/dist/http-client.mjs +70 -54
  63. package/dist/http-client.mjs.map +1 -1
  64. package/dist/image-deploy.cjs +9 -0
  65. package/dist/image-deploy.cjs.map +1 -1
  66. package/dist/image-deploy.mjs +9 -1
  67. package/dist/image-deploy.mjs.map +1 -1
  68. package/dist/index.cjs +4 -0
  69. package/dist/index.d.cts +3 -3
  70. package/dist/index.d.mts +3 -3
  71. package/dist/index.mjs +3 -3
  72. package/dist/orchestrator.cjs +39 -35
  73. package/dist/orchestrator.cjs.map +1 -1
  74. package/dist/orchestrator.mjs +39 -35
  75. package/dist/orchestrator.mjs.map +1 -1
  76. package/dist/plugin.cjs +2 -0
  77. package/dist/plugin.cjs.map +1 -1
  78. package/dist/plugin.d.cts +24 -0
  79. package/dist/plugin.d.mts +24 -0
  80. package/dist/plugin.mjs +2 -0
  81. package/dist/plugin.mjs.map +1 -1
  82. package/dist/process-registry.cjs +1 -1
  83. package/dist/process-registry.mjs +1 -1
  84. package/dist/publish.cjs +3 -3
  85. package/dist/publish.cjs.map +1 -1
  86. package/dist/publish.mjs +4 -4
  87. package/dist/publish.mjs.map +1 -1
  88. package/dist/resolver.cjs +293 -0
  89. package/dist/resolver.cjs.map +1 -0
  90. package/dist/resolver.d.cts +99 -0
  91. package/dist/resolver.d.mts +99 -0
  92. package/dist/resolver.mjs +284 -0
  93. package/dist/resolver.mjs.map +1 -0
  94. package/dist/smoke.cjs +262 -0
  95. package/dist/smoke.cjs.map +1 -0
  96. package/dist/smoke.mjs +260 -0
  97. package/dist/smoke.mjs.map +1 -0
  98. package/dist/version-manifest-resolve.cjs +3 -3
  99. package/dist/version-manifest-resolve.cjs.map +1 -1
  100. package/dist/version-manifest-resolve.mjs +1 -1
  101. package/dist/version-manifest-resolve.mjs.map +1 -1
  102. package/dist/workspace.cjs +1 -1
  103. package/dist/workspace.mjs +1 -1
  104. package/package.json +9 -9
  105. package/dist/bundle-fs-resolve.cjs +0 -235
  106. package/dist/bundle-fs-resolve.cjs.map +0 -1
  107. package/dist/bundle-fs-resolve.d.cts +0 -82
  108. package/dist/bundle-fs-resolve.d.mts +0 -82
  109. package/dist/bundle-fs-resolve.mjs +0 -228
  110. package/dist/bundle-fs-resolve.mjs.map +0 -1
  111. package/dist/bundle-path.cjs +0 -48
  112. package/dist/bundle-path.cjs.map +0 -1
  113. package/dist/bundle-path.mjs +0 -45
  114. package/dist/bundle-path.mjs.map +0 -1
  115. package/dist/mf.cjs.map +0 -1
  116. package/dist/mf.mjs.map +0 -1
package/dist/plugin.d.cts CHANGED
@@ -458,6 +458,7 @@ declare const _default: import("every-plugin").LoadedPluginWithBinding<{
458
458
  registry: z.ZodOptional<z.ZodString>;
459
459
  imageDigest: z.ZodOptional<z.ZodString>;
460
460
  fullUpload: z.ZodDefault<z.ZodBoolean>;
461
+ smoke: z.ZodDefault<z.ZodBoolean>;
461
462
  }, z.core.$strip>, z.ZodObject<{
462
463
  status: z.ZodEnum<{
463
464
  deployed: "deployed";
@@ -493,6 +494,29 @@ declare const _default: import("every-plugin").LoadedPluginWithBinding<{
493
494
  durationMs: z.ZodOptional<z.ZodNumber>;
494
495
  }, z.core.$strip>>>;
495
496
  }, z.core.$strip>, object>;
497
+ smoke: import("@orpc/contract").ProcedureContract<z.ZodObject<{
498
+ image: z.ZodOptional<z.ZodString>;
499
+ port: z.ZodDefault<z.ZodNumber>;
500
+ keep: z.ZodDefault<z.ZodBoolean>;
501
+ account: z.ZodOptional<z.ZodString>;
502
+ gateway: z.ZodOptional<z.ZodString>;
503
+ apiDatabaseUrl: z.ZodOptional<z.ZodString>;
504
+ authDatabaseUrl: z.ZodOptional<z.ZodString>;
505
+ env: z.ZodDefault<z.ZodEnum<{
506
+ production: "production";
507
+ staging: "staging";
508
+ }>>;
509
+ registry: z.ZodOptional<z.ZodString>;
510
+ }, z.core.$strip>, z.ZodObject<{
511
+ status: z.ZodEnum<{
512
+ error: "error";
513
+ ok: "ok";
514
+ }>;
515
+ image: z.ZodOptional<z.ZodString>;
516
+ summary: z.ZodOptional<z.ZodString>;
517
+ diagnosis: z.ZodOptional<z.ZodString>;
518
+ error: z.ZodOptional<z.ZodString>;
519
+ }, z.core.$strip>, object>;
496
520
  keyPublish: import("@orpc/contract").ProcedureContract<z.ZodObject<{
497
521
  allowance: z.ZodDefault<z.ZodString>;
498
522
  env: z.ZodDefault<z.ZodEnum<{
package/dist/plugin.d.mts CHANGED
@@ -458,6 +458,7 @@ declare const _default: import("every-plugin").LoadedPluginWithBinding<{
458
458
  registry: z.ZodOptional<z.ZodString>;
459
459
  imageDigest: z.ZodOptional<z.ZodString>;
460
460
  fullUpload: z.ZodDefault<z.ZodBoolean>;
461
+ smoke: z.ZodDefault<z.ZodBoolean>;
461
462
  }, z.core.$strip>, z.ZodObject<{
462
463
  status: z.ZodEnum<{
463
464
  deployed: "deployed";
@@ -493,6 +494,29 @@ declare const _default: import("every-plugin").LoadedPluginWithBinding<{
493
494
  durationMs: z.ZodOptional<z.ZodNumber>;
494
495
  }, z.core.$strip>>>;
495
496
  }, z.core.$strip>, object>;
497
+ smoke: import("@orpc/contract").ProcedureContract<z.ZodObject<{
498
+ image: z.ZodOptional<z.ZodString>;
499
+ port: z.ZodDefault<z.ZodNumber>;
500
+ keep: z.ZodDefault<z.ZodBoolean>;
501
+ account: z.ZodOptional<z.ZodString>;
502
+ gateway: z.ZodOptional<z.ZodString>;
503
+ apiDatabaseUrl: z.ZodOptional<z.ZodString>;
504
+ authDatabaseUrl: z.ZodOptional<z.ZodString>;
505
+ env: z.ZodDefault<z.ZodEnum<{
506
+ production: "production";
507
+ staging: "staging";
508
+ }>>;
509
+ registry: z.ZodOptional<z.ZodString>;
510
+ }, z.core.$strip>, z.ZodObject<{
511
+ status: z.ZodEnum<{
512
+ error: "error";
513
+ ok: "ok";
514
+ }>;
515
+ image: z.ZodOptional<z.ZodString>;
516
+ summary: z.ZodOptional<z.ZodString>;
517
+ diagnosis: z.ZodOptional<z.ZodString>;
518
+ error: z.ZodOptional<z.ZodString>;
519
+ }, z.core.$strip>, object>;
496
520
  keyPublish: import("@orpc/contract").ProcedureContract<z.ZodObject<{
497
521
  allowance: z.ZodDefault<z.ZodString>;
498
522
  env: z.ZodDefault<z.ZodEnum<{
package/dist/plugin.mjs CHANGED
@@ -15,6 +15,7 @@ import { registerInit } from "./commands/init.mjs";
15
15
  import { registerKeys } from "./commands/keys.mjs";
16
16
  import { registerOps } from "./commands/ops.mjs";
17
17
  import { registerPlugins } from "./commands/plugins.mjs";
18
+ import { registerSmoke } from "./commands/smoke.mjs";
18
19
  import { registerUpgrade } from "./commands/upgrade.mjs";
19
20
  import { Context, Effect, Layer } from "effect";
20
21
  import { buildScoped, buildScopedContext } from "every-plugin";
@@ -54,6 +55,7 @@ var plugin_default = createPlugin({
54
55
  ...registerDev(builder),
55
56
  ...registerBuild(builder),
56
57
  ...registerDeploy(builder),
58
+ ...registerSmoke(builder),
57
59
  ...registerKeys(builder),
58
60
  ...registerInit(builder),
59
61
  ...registerUpgrade(builder),
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { buildScoped, buildScopedContext } from \"every-plugin\";\nimport { registerBuild } from \"./commands/build\";\nimport { registerConfig } from \"./commands/config\";\nimport { registerDb } from \"./commands/db\";\nimport { registerDeploy } from \"./commands/deploy\";\nimport { registerDev } from \"./commands/dev\";\nimport { registerInit } from \"./commands/init\";\nimport { registerKeys } from \"./commands/keys\";\nimport { registerOps } from \"./commands/ops\";\nimport { registerPlugins } from \"./commands/plugins\";\nimport { type BosDeps, BosDepsTag } from \"./commands/shared\";\nimport { registerUpgrade } from \"./commands/upgrade\";\nimport { bosContract } from \"./contract\";\nimport { DatabaseBindings, DrizzleKit, makeDatabaseBindings, makeDrizzleKitLive } from \"./db\";\nimport { ProjectEnv, ProjectEnvLive } from \"./env/project-env\";\nimport { openResolution } from \"./resolution/session\";\nimport { createPlugin, z } from \"./sdk\";\n\nexport { resolveRemoteConfigChain } from \"./commands/config\";\nexport type { DevSessionData, StartSummary } from \"./dev-program\";\nexport { type ProgressEvent, pluginEvents } from \"./progress\";\n\nexport default createPlugin({\n variables: z.object({\n configPath: z.string().optional(),\n // The artifact root (cwd-derived) — decoupled from configPath so an\n // explicit boot config (--config-path fixture) validates and loads\n // without redirecting where the CLI writes generated artifacts.\n configDir: z.string().optional(),\n }),\n secrets: z.object({}),\n contract: bosContract,\n initialize: (config, _plugins) =>\n Effect.gen(function* () {\n const session = yield* Effect.promise(() =>\n openResolution({ path: config.variables.configPath }),\n );\n\n const projectEnv = yield* buildScoped(ProjectEnv, ProjectEnvLive);\n const effectContext = yield* Effect.context();\n\n const configDir = config.variables.configDir ?? session?.root ?? process.cwd();\n\n const services = yield* buildScopedContext(\n Layer.mergeAll(\n makeDatabaseBindings({\n projectDir: configDir,\n loadRuntimeConfig: async () => (await session?.buildRuntime()) ?? null,\n loadEnv: () => Effect.runPromiseWith(effectContext)(projectEnv.load(configDir)),\n }),\n makeDrizzleKitLive({\n projectDir: configDir,\n onLog: (message) => p.log.info(message),\n }),\n ),\n );\n\n return Layer.succeed(BosDepsTag, {\n session,\n databaseBindings: Context.get(services, DatabaseBindings),\n drizzleKit: Context.get(services, DrizzleKit),\n } satisfies BosDeps);\n }),\n createRouter: (builder) => ({\n ...registerConfig(builder),\n ...registerPlugins(builder),\n ...registerDev(builder),\n ...registerBuild(builder),\n ...registerDeploy(builder),\n ...registerKeys(builder),\n ...registerInit(builder),\n ...registerUpgrade(builder),\n ...registerDb(builder),\n ...registerOps(builder),\n }),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,qBAAe,aAAa;CAC1B,WAAW,EAAE,OAAO;EAClB,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;EAIhC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,CAAC;CACD,SAAS,EAAE,OAAO,CAAC,CAAC;CACpB,UAAU;CACV,aAAa,QAAQ,aACnB,OAAO,IAAI,aAAa;EACtB,MAAM,UAAU,OAAO,OAAO,cAC5B,eAAe,EAAE,MAAM,OAAO,UAAU,WAAW,CAAC,CACtD;EAEA,MAAM,aAAa,OAAO,YAAY,YAAY,cAAc;EAChE,MAAM,gBAAgB,OAAO,OAAO,QAAQ;EAE5C,MAAM,YAAY,OAAO,UAAU,aAAa,SAAS,QAAQ,QAAQ,IAAI;EAE7E,MAAM,WAAW,OAAO,mBACtB,MAAM,SACJ,qBAAqB;GACnB,YAAY;GACZ,mBAAmB,YAAa,MAAM,SAAS,aAAa,KAAM;GAClE,eAAe,OAAO,eAAe,aAAa,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC;EAChF,CAAC,GACD,mBAAmB;GACjB,YAAY;GACZ,QAAQ,YAAY,EAAE,IAAI,KAAK,OAAO;EACxC,CAAC,CACH,CACF;EAEA,OAAO,MAAM,QAAQ,YAAY;GAC/B;GACA,kBAAkB,QAAQ,IAAI,UAAU,gBAAgB;GACxD,YAAY,QAAQ,IAAI,UAAU,UAAU;EAC9C,CAAmB;CACrB,CAAC;CACH,eAAe,aAAa;EAC1B,GAAG,eAAe,OAAO;EACzB,GAAG,gBAAgB,OAAO;EAC1B,GAAG,YAAY,OAAO;EACtB,GAAG,cAAc,OAAO;EACxB,GAAG,eAAe,OAAO;EACzB,GAAG,aAAa,OAAO;EACvB,GAAG,aAAa,OAAO;EACvB,GAAG,gBAAgB,OAAO;EAC1B,GAAG,WAAW,OAAO;EACrB,GAAG,YAAY,OAAO;CACxB;AACF,CAAC"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { buildScoped, buildScopedContext } from \"every-plugin\";\nimport { registerBuild } from \"./commands/build\";\nimport { registerConfig } from \"./commands/config\";\nimport { registerDb } from \"./commands/db\";\nimport { registerDeploy } from \"./commands/deploy\";\nimport { registerDev } from \"./commands/dev\";\nimport { registerInit } from \"./commands/init\";\nimport { registerKeys } from \"./commands/keys\";\nimport { registerOps } from \"./commands/ops\";\nimport { registerPlugins } from \"./commands/plugins\";\nimport { type BosDeps, BosDepsTag } from \"./commands/shared\";\nimport { registerSmoke } from \"./commands/smoke\";\nimport { registerUpgrade } from \"./commands/upgrade\";\nimport { bosContract } from \"./contract\";\nimport { DatabaseBindings, DrizzleKit, makeDatabaseBindings, makeDrizzleKitLive } from \"./db\";\nimport { ProjectEnv, ProjectEnvLive } from \"./env/project-env\";\nimport { openResolution } from \"./resolution/session\";\nimport { createPlugin, z } from \"./sdk\";\n\nexport { resolveRemoteConfigChain } from \"./commands/config\";\nexport type { DevSessionData, StartSummary } from \"./dev-program\";\nexport { type ProgressEvent, pluginEvents } from \"./progress\";\n\nexport default createPlugin({\n variables: z.object({\n configPath: z.string().optional(),\n // The artifact root (cwd-derived) — decoupled from configPath so an\n // explicit boot config (--config-path fixture) validates and loads\n // without redirecting where the CLI writes generated artifacts.\n configDir: z.string().optional(),\n }),\n secrets: z.object({}),\n contract: bosContract,\n initialize: (config, _plugins) =>\n Effect.gen(function* () {\n const session = yield* Effect.promise(() =>\n openResolution({ path: config.variables.configPath }),\n );\n\n const projectEnv = yield* buildScoped(ProjectEnv, ProjectEnvLive);\n const effectContext = yield* Effect.context();\n\n const configDir = config.variables.configDir ?? session?.root ?? process.cwd();\n\n const services = yield* buildScopedContext(\n Layer.mergeAll(\n makeDatabaseBindings({\n projectDir: configDir,\n loadRuntimeConfig: async () => (await session?.buildRuntime()) ?? null,\n loadEnv: () => Effect.runPromiseWith(effectContext)(projectEnv.load(configDir)),\n }),\n makeDrizzleKitLive({\n projectDir: configDir,\n onLog: (message) => p.log.info(message),\n }),\n ),\n );\n\n return Layer.succeed(BosDepsTag, {\n session,\n databaseBindings: Context.get(services, DatabaseBindings),\n drizzleKit: Context.get(services, DrizzleKit),\n } satisfies BosDeps);\n }),\n createRouter: (builder) => ({\n ...registerConfig(builder),\n ...registerPlugins(builder),\n ...registerDev(builder),\n ...registerBuild(builder),\n ...registerDeploy(builder),\n ...registerSmoke(builder),\n ...registerKeys(builder),\n ...registerInit(builder),\n ...registerUpgrade(builder),\n ...registerDb(builder),\n ...registerOps(builder),\n }),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,qBAAe,aAAa;CAC1B,WAAW,EAAE,OAAO;EAClB,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;EAIhC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,CAAC;CACD,SAAS,EAAE,OAAO,CAAC,CAAC;CACpB,UAAU;CACV,aAAa,QAAQ,aACnB,OAAO,IAAI,aAAa;EACtB,MAAM,UAAU,OAAO,OAAO,cAC5B,eAAe,EAAE,MAAM,OAAO,UAAU,WAAW,CAAC,CACtD;EAEA,MAAM,aAAa,OAAO,YAAY,YAAY,cAAc;EAChE,MAAM,gBAAgB,OAAO,OAAO,QAAQ;EAE5C,MAAM,YAAY,OAAO,UAAU,aAAa,SAAS,QAAQ,QAAQ,IAAI;EAE7E,MAAM,WAAW,OAAO,mBACtB,MAAM,SACJ,qBAAqB;GACnB,YAAY;GACZ,mBAAmB,YAAa,MAAM,SAAS,aAAa,KAAM;GAClE,eAAe,OAAO,eAAe,aAAa,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC;EAChF,CAAC,GACD,mBAAmB;GACjB,YAAY;GACZ,QAAQ,YAAY,EAAE,IAAI,KAAK,OAAO;EACxC,CAAC,CACH,CACF;EAEA,OAAO,MAAM,QAAQ,YAAY;GAC/B;GACA,kBAAkB,QAAQ,IAAI,UAAU,gBAAgB;GACxD,YAAY,QAAQ,IAAI,UAAU,UAAU;EAC9C,CAAmB;CACrB,CAAC;CACH,eAAe,aAAa;EAC1B,GAAG,eAAe,OAAO;EACzB,GAAG,gBAAgB,OAAO;EAC1B,GAAG,YAAY,OAAO;EACtB,GAAG,cAAc,OAAO;EACxB,GAAG,eAAe,OAAO;EACzB,GAAG,cAAc,OAAO;EACxB,GAAG,aAAa,OAAO;EACvB,GAAG,aAAa,OAAO;EACvB,GAAG,gBAAgB,OAAO;EAC1B,GAAG,WAAW,OAAO;EACrB,GAAG,YAAY,OAAO;CACxB;AACF,CAAC"}
@@ -1,8 +1,8 @@
1
1
  let node_fs = require("node:fs");
2
2
  let node_path = require("node:path");
3
3
  let effect = require("effect");
4
- let node_os = require("node:os");
5
4
  let node_fs_promises = require("node:fs/promises");
5
+ let node_os = require("node:os");
6
6
  let node_child_process = require("node:child_process");
7
7
 
8
8
  //#region src/process-registry.ts
@@ -1,8 +1,8 @@
1
1
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { Effect } from "effect";
4
- import { homedir } from "node:os";
5
4
  import { access } from "node:fs/promises";
5
+ import { homedir } from "node:os";
6
6
  import { spawnSync } from "node:child_process";
7
7
 
8
8
  //#region src/process-registry.ts
package/dist/publish.cjs CHANGED
@@ -252,7 +252,7 @@ async function preflightPublish(input) {
252
252
  let publishedConfig = null;
253
253
  let publishedConfigState = "missing";
254
254
  try {
255
- publishedConfig = await require_fastkv.fetchBosConfigFromFastKv(registryUrl, input.registry);
255
+ publishedConfig = await require_fastkv.fetchPublishedConfigFromFastKv(registryUrl);
256
256
  publishedConfigState = "fetched";
257
257
  } catch (error) {
258
258
  if ((error instanceof Error ? error.message : String(error)).startsWith("No config found")) console.log(require_theme.colors.dim(" Note: no published config found yet (first publish) — continuing"));
@@ -381,7 +381,7 @@ async function publishToFastKv(input) {
381
381
  };
382
382
  rawConfig = opened.rawConfig;
383
383
  }
384
- if (tsForm && !input.build && plan.publishedConfigState === "unreachable") return {
384
+ if (tsForm && !input.build && input.exactPayload !== true && plan.publishedConfigState === "unreachable") return {
385
385
  status: "error",
386
386
  registryUrl,
387
387
  built,
@@ -389,7 +389,7 @@ async function publishToFastKv(input) {
389
389
  deployResults,
390
390
  error: "Cannot read the currently published config from the registry — a config-only publish would overwrite live bundle URLs. Retry when the registry is reachable, or run a full deploy."
391
391
  };
392
- let publishPayload = tsForm && !input.build ? require_merge.mergeAuthoredOverPublished(plan.publishedConfig ?? {}, rawConfig) : rawConfig;
392
+ let publishPayload = input.exactPayload === true ? input.bosConfig : tsForm && !input.build ? require_merge.mergeAuthoredOverPublished(plan.publishedConfig ?? {}, rawConfig) : rawConfig;
393
393
  const urlOrigin = plan.cdnOrigin ?? `https://${gateway}`;
394
394
  const deployTargets = (built ?? []).filter((key) => targets.includes(key));
395
395
  const platformEntries = [];
@@ -1 +1 @@
1
- {"version":3,"file":"publish.cjs","names":["composeWorkspaceVersionManifest","uploadBundle","colors","padRight","localSriMap","resolveSlotVersion","diffWorkspaceFiles","uploadWorkspaceDist","mergedFileIntegrity","process","fetchBosConfigFromFastKv","fetchResponse","join","existsSync","readFileSync","getNetworkIdForAccount","buildRegistryConfigUrlForNetwork","readSessionHandle","resolveSigningStrategy","describeSigningStrategy","resolveCdnDeployInputs","probeStorageOrigin","getRegistryNamespaceForNetwork","selectWorkspaceTargets","generateCodeArtifacts","buildWorkspaceTargets","icons","openResolution","findConfigPath","isAppDescriptorPath","mergeAuthoredOverPublished","pinsFromPublishedConfig","pinsFromDeployState","resolveWorkspaceTarget","collectDistFiles","readBuildReport","formatDuration","platformUrlDeployEntries","hasFolderFormUi","resolveUiRuntimeName","pluginUiUrlDeployEntries","applyDeployResults","verifyRollbackSnapshot","pointerFingerprint","slotPins","ensureDelegateKey","submitRegistryWriteDelegated","submitRegistryWrite"],"sources":["../src/publish.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { hasFolderFormUi } from \"every-plugin/build/ui\";\nimport { readSessionHandle } from \"./auth-session\";\nimport { buildWorkspaceTargets, resolveWorkspaceTarget, selectWorkspaceTargets } from \"./build\";\nimport { type CdnDeployInputs, probeStorageOrigin, resolveCdnDeployInputs } from \"./cdn-deploy\";\nimport { formatDuration } from \"./cli/timing\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { findConfigPath, isAppDescriptorPath, resolveUiRuntimeName } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { ensureDelegateKey, submitRegistryWriteDelegated } from \"./delegate-signer\";\nimport {\n diffWorkspaceFiles,\n localSriMap,\n mergedFileIntegrity,\n type PreviousPin,\n pinsFromDeployState,\n pinsFromPublishedConfig,\n upsertDeployStatePins,\n} from \"./deploy-diff\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n type NetworkId,\n} from \"./fastkv\";\nimport { pointerFingerprint, slotPins } from \"./fingerprint\";\nimport { fetchResponse } from \"./http-client\";\nimport { applyDeployResults, type DeployResultEntry } from \"./integrity\";\nimport { mergeAuthoredOverPublished } from \"./merge\";\nimport {\n describeSigningStrategy,\n resolveSigningStrategy,\n type SigningStrategy,\n submitRegistryWrite,\n} from \"./near-signer\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport { platformUrlDeployEntries, pluginUiUrlDeployEntries } from \"./platform-deploy\";\nimport { openResolution } from \"./resolution/session\";\nimport { verifyRollbackSnapshot } from \"./rollback\";\nimport {\n collectDistFiles,\n type DistFile,\n uploadBundle,\n uploadWorkspaceDist,\n} from \"./storage-upload\";\nimport type { BosConfig, BosConfigInput, PublishConfig, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\nimport { composeWorkspaceVersionManifest, readBuildReport } from \"./version-manifest-deploy\";\nimport { resolveSlotVersion } from \"./version-manifest-resolve\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Compose + upload the workspace's version manifest (atomic-deploys 03): the\n * manifest is built from the dist build report + the **server-computed** SRI\n * map of the just-finished upload, uploaded additively at\n * `versions/<version>.json`, and returned as the slot's pointer. Returns\n * undefined when the dist predates hashed entry names (no report / no entry\n * SRI) — the caller aborts the train: uploaded workspaces must pin.\n */\n/**\n * The manifest's own storage backend — when every dist file was diff-skipped\n * it is the only upload of the leg, so it is the only signal for the\n * memory-backend abort below.\n */\nexport interface VersionManifestPin {\n file: string;\n integrity: string;\n storage?: \"s3\" | \"memory\";\n}\n\nasync function pinWorkspaceVersionManifest(input: {\n origin: string;\n apiKey?: string;\n account: string;\n gateway: string;\n workspace: string;\n report: ReturnType<typeof readBuildReport>;\n ssrReport: ReturnType<typeof readBuildReport>;\n integrityMap: Record<string, string>;\n /** full per-file SRI map of the dist — recorded for the next deploy's diff */\n files?: Record<string, string>;\n}): Promise<VersionManifestPin | undefined> {\n if (!input.report) return undefined;\n const versionManifest = composeWorkspaceVersionManifest({\n report: input.report,\n ssrReport: input.ssrReport,\n integrityMap: input.integrityMap,\n ...(input.files ? { files: input.files } : {}),\n });\n if (!versionManifest) return undefined;\n\n const manifestFile = `versions/${versionManifest.version}.json`;\n const manifestUpload = await uploadBundle({\n origin: input.origin,\n apiKey: input.apiKey,\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n files: [\n {\n path: manifestFile,\n bytes: new TextEncoder().encode(`${JSON.stringify(versionManifest, null, 2)}\\n`),\n },\n ],\n });\n const manifestIntegrity = manifestUpload.integrity[manifestFile];\n if (!manifestIntegrity) return undefined;\n console.log(\n ` ${colors.dim(`${padRight(\"\", 28)} version manifest ${manifestFile} (SRI pinned)`)}`,\n );\n return { file: manifestFile, integrity: manifestIntegrity, storage: manifestUpload.storage };\n}\n\ninterface DiffUploadOutcome {\n result: {\n stored: number;\n totalBytes: number;\n integrity: Record<string, string>;\n storage?: \"s3\" | \"memory\";\n };\n /** per-file SRI map covering the whole dist (uploaded → server SRI, skipped → previous manifest SRI) */\n fileIntegrity: Record<string, string>;\n uploaded: number;\n skipped: number;\n total: number;\n}\n\n/**\n * One workspace's upload leg with skip-unchanged diffing: resolve the previous\n * manifest's `files` map, hash the local dist, upload only new/changed files,\n * and return the merged per-file SRI map for the version manifest. Any failure\n * to resolve the previous map degrades to a full upload.\n */\nasync function diffUploadWorkspace(input: {\n origin: string;\n apiKey?: string;\n account: string;\n gateway: string;\n workspace: string;\n files: DistFile[];\n base: string;\n previousPin: PreviousPin | undefined;\n}): Promise<DiffUploadOutcome> {\n const localSri = localSriMap(input.files);\n let uploadFiles = input.files;\n let prevFiles: Record<string, string> | undefined;\n if (input.previousPin) {\n try {\n const resolved = await resolveSlotVersion({ base: input.base, pin: input.previousPin });\n if (resolved.files) {\n const diff = diffWorkspaceFiles(input.files, localSri, resolved.files);\n prevFiles = resolved.files;\n uploadFiles = diff.upload;\n if (diff.skipped > 0) {\n console.log(\n ` ${colors.dim(`${padRight(input.workspace, 28)} ${diff.skipped} unchanged file(s) — skipping (manifest diff)`)}`,\n );\n }\n }\n } catch {\n console.log(\n ` ${colors.dim(`${padRight(input.workspace, 28)} previous manifest unusable — uploading everything`)}`,\n );\n }\n }\n\n console.log(\n ` ${padRight(input.workspace, 28)} uploading ${uploadFiles.length} of ${input.files.length} files (${formatBundleMb(uploadFiles)}) → ${input.base}`,\n );\n const result =\n uploadFiles.length > 0\n ? await uploadWorkspaceDist({\n origin: input.origin,\n apiKey: input.apiKey,\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n files: uploadFiles,\n })\n : { stored: 0, totalBytes: 0, integrity: {}, storage: undefined };\n return {\n result,\n fileIntegrity: mergedFileIntegrity(input.files, result.integrity, prevFiles),\n uploaded: result.stored,\n skipped: input.files.length - uploadFiles.length,\n total: input.files.length,\n };\n}\n\nfunction formatBundleMb(files: Array<{ bytes: Uint8Array }>): string {\n const total = files.reduce((sum, file) => sum + file.bytes.byteLength, 0);\n return `${(total / 1024 / 1024).toFixed(1)} MB`;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n registry?: string;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n opts.registry,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\nexport async function isConfigAlreadyPublished(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n registry?: string;\n}): Promise<boolean> {\n try {\n const current = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n opts.registry,\n );\n return JSON.stringify(current) === JSON.stringify(opts.publishConfig);\n } catch {\n return false;\n }\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n wallet?: boolean;\n registry?: string;\n /** Skip the diff upload and re-upload every dist file (escape hatch). */\n fullUpload?: boolean;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n fingerprint?: string;\n slotPins?: Record<string, string>;\n}\n\nexport type PublishedConfigState = \"fetched\" | \"missing\" | \"unreachable\";\n\nexport interface PublishPreflightPlan {\n isStaging: boolean;\n account: string;\n gateway: string;\n network: NetworkId;\n registryUrl: string;\n registryNamespace: string;\n targets: string[];\n useWallet: boolean;\n strategy?: SigningStrategy;\n cdnOrigin: string | undefined;\n storageOrigin: string;\n storageApiKey?: string;\n /** The config currently published to FastKV (null when missing or unreachable). */\n publishedConfig: Record<string, unknown> | null;\n /** Whether the preflight FastKV read succeeded, found nothing, or failed. */\n publishedConfigState: PublishedConfigState;\n}\n\nexport type PublishPreflight =\n | { kind: \"dry-run\"; registryUrl: string }\n | { kind: \"error\"; registryUrl: string; error: string }\n | { kind: \"ready\"; plan: PublishPreflightPlan };\n\nconst FRAMEWORK_PACKAGE_NAMES = [\"better-near-auth\", \"every-plugin\", \"everything-dev\"] as const;\n\n/**\n * Whether npm serves `name@version` (true), definitively does not (404 —\n * false), or whether publishability could not be determined (network error,\n * unexpected status — null; callers must not block on that).\n */\nexport async function npmVersionPublished(name: string, version: string): Promise<boolean | null> {\n try {\n const res = await fetchResponse(`https://registry.npmjs.org/${name}/${version}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.status === 200) return true;\n if (res.status === 404) return false;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * The npm-publish gate: a workspace that vendors the framework packages'\n * sources must not ship bundles ahead of npm — the update check, child\n * scaffolds (`bos init`), and template syncs all read those versions from\n * the registry. Reads only apply when the sources are workspace-local (the\n * parent repo); child projects install the framework from npm and are\n * inherently in sync.\n */\nexport async function findUnpublishedFrameworkPackages(\n configDir: string,\n): Promise<Array<{ name: string; version: string }>> {\n const unpublished: Array<{ name: string; version: string }> = [];\n for (const name of FRAMEWORK_PACKAGE_NAMES) {\n const manifestPath = join(configDir, \"packages\", name, \"package.json\");\n if (!existsSync(manifestPath)) continue;\n const version = (JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { version?: string })\n .version;\n if (!version) continue;\n const published = await npmVersionPublished(name, version);\n if (published === false) {\n unpublished.push({ name, version });\n } else if (published === null) {\n console.log(\n colors.yellow(\n ` ! Could not verify ${name}@${version} on npm (registry unreachable) — continuing`,\n ),\n );\n }\n }\n return unpublished;\n}\n\n// Pure preflight (resolve, don't mutate) — every failure returns before the\n// build train runs (issue #287). Dry-run exits after the auth guards, before\n// any signing (keychain/TTY side effects).\nexport async function preflightPublish(input: PublishToFastKvInput): Promise<PublishPreflight> {\n const { configDir } = input;\n const bosConfig = input.bosConfig;\n\n const isStaging = input.env === \"staging\";\n const account = isStaging ? (bosConfig.staging?.account ?? bosConfig.account) : bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n kind: \"error\",\n registryUrl: \"\",\n error: \"authored config must define domain to publish\",\n };\n }\n\n const network: NetworkId = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway, input.registry);\n const fail = (error: string): PublishPreflight => ({ kind: \"error\", registryUrl, error });\n\n const publishAuth: PublishConfig[\"auth\"] = bosConfig.publish?.auth;\n const governsWalletPublish = (publishAuth === \"session\" || input.wallet) && !input.privateKey;\n if (governsWalletPublish) {\n const session = readSessionHandle(configDir);\n if (!session?.credential) {\n return fail(\n (input.wallet\n ? \"--wallet requires\"\n : 'the authored config sets publish.auth = \"session\", but') +\n \" no CLI session is stored in .bos/ for this project. Run bos login to create one.\",\n );\n }\n if (session.credential.accountId && session.credential.accountId !== account) {\n return fail(\n `The CLI session was created for ${session.credential.accountId}, but the configured ` +\n `account is ${account}. Gasless wallet publish relays the FastKV write under the session's ` +\n \"NEAR account. Run bos login again under the matching account.\",\n );\n }\n }\n if (publishAuth && !input.privateKey) {\n if (publishAuth === \"custody\") {\n return fail(\n 'the authored config sets publish.auth = \"custody\", but custody publish is not implemented yet (see NEARBuilders/everything-dev#291).',\n );\n }\n }\n\n if (input.dryRun) {\n return { kind: \"dry-run\", registryUrl };\n }\n\n const useWallet = input.wallet === true;\n let strategy: SigningStrategy | undefined;\n if (useWallet) {\n console.log(\n ` Signing via ${colors.cyan(\"gasless NEP-366 delegate action (relayed by the platform relayer)\")}`,\n );\n } else {\n try {\n strategy = await resolveSigningStrategy({ privateKey: input.privateKey, account, network });\n console.log(` Signing via ${colors.cyan(describeSigningStrategy(strategy))}`);\n } catch (error) {\n return fail(error instanceof Error ? error.message : \"Unknown error\");\n }\n }\n\n // CDN deploy credentials (ADR 0020) — resolved before the build train so a\n // missing bundle origin or BOS_STORAGE_API_KEY fails fast instead of after\n // the full build. Config-only publishes ship the committed config verbatim;\n // nothing is uploaded, so no deploy origins are required.\n const session = readSessionHandle(configDir);\n let cdnDeploy: CdnDeployInputs = {\n cdnOrigin: undefined,\n storageOrigin: \"\",\n apiKey: undefined,\n };\n if (input.build) {\n const unpublished = await findUnpublishedFrameworkPackages(configDir);\n if (unpublished.length > 0) {\n const listing = unpublished.map((pkg) => `${pkg.name}@${pkg.version}`).join(\", \");\n return fail(\n `Framework package(s) ${listing} are not published to npm yet — deploys must not ship ` +\n \"bundles ahead of the registry (child scaffolds and update checks read these versions). \" +\n \"Re-run the Release workflow (or `pnpm run release`) first.\",\n );\n }\n\n cdnDeploy = resolveCdnDeployInputs({\n env: process.env as Record<string, string | undefined>,\n bosConfig,\n session: session?.credential ?? null,\n account,\n gateway,\n uploadsPlanned: input.build,\n });\n if (cdnDeploy.error) {\n return fail(cdnDeploy.error);\n }\n if (cdnDeploy.warning) {\n console.log(colors.yellow(` ! ${cdnDeploy.warning}`));\n }\n const cdnOrigin = cdnDeploy.cdnOrigin;\n if (!cdnOrigin) {\n return fail(\"CDN deploy resolved no bundle origin\");\n }\n const probeError = await probeStorageOrigin(cdnDeploy.storageOrigin);\n if (probeError) {\n return fail(\n `The bundle upload origin ${cdnDeploy.storageOrigin} is not running the platform API — ` +\n `${probeError}. Check BOS_STORAGE_ORIGIN / the bos login session, then re-run.`,\n );\n }\n }\n\n // Registry reachability + published-state capture: one FastKV read. A\n // missing config is fine for a first publish — an early signal, not a hard\n // gate. The captured config is the merge base for a config-only publish on\n // a TS-form project (authored hand-edits win; live pipeline state carries).\n let publishedConfig: Record<string, unknown> | null = null;\n let publishedConfigState: PublishedConfigState = \"missing\";\n try {\n publishedConfig = await fetchBosConfigFromFastKv<Record<string, unknown>>(\n registryUrl,\n input.registry,\n );\n publishedConfigState = \"fetched\";\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.startsWith(\"No config found\")) {\n console.log(colors.dim(\" Note: no published config found yet (first publish) — continuing\"));\n } else {\n publishedConfigState = \"unreachable\";\n console.log(colors.dim(\" Note: registry read failed — continuing\"));\n }\n }\n\n return {\n kind: \"ready\",\n plan: {\n isStaging,\n account,\n gateway,\n network,\n registryUrl,\n registryNamespace: getRegistryNamespaceForNetwork(network, input.registry),\n targets: selectWorkspaceTargets(input.packages, bosConfig),\n useWallet,\n strategy,\n cdnOrigin: cdnDeploy.cdnOrigin,\n storageOrigin: cdnDeploy.storageOrigin,\n storageApiKey: cdnDeploy.apiKey,\n publishedConfig,\n publishedConfigState,\n },\n };\n}\n\n/**\n * The deploy-train publish core (ADR 0020, as amended): preflight\n * (storage/CDN creds + signing) fails fast before the build, then build →\n * upload → version-manifest pin → config write-back → FastKV publish +\n * read-back. Scoped to one plugin via `packages`, a single-plugin redeploy\n * ships real bytes to the storage origin — same as the full train, nothing\n * image-native left.\n */\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const preflight = await preflightPublish(input);\n if (preflight.kind === \"error\") {\n return { status: \"error\", registryUrl: preflight.registryUrl, error: preflight.error };\n }\n if (preflight.kind === \"dry-run\") {\n return { status: \"dry-run\", registryUrl: preflight.registryUrl };\n }\n const plan = preflight.plan;\n const {\n isStaging,\n account,\n gateway,\n network,\n registryUrl,\n registryNamespace,\n targets,\n useWallet,\n strategy,\n } = plan;\n const storageOrigin = plan.storageOrigin;\n const storageApiKey = plan.storageApiKey;\n\n const { configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n let refreshedRawConfig: BosConfigInput | null = null;\n\n if (input.build) {\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await openResolution({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload the config after build\",\n };\n }\n\n bosConfig = refreshed.config;\n refreshedRawConfig = refreshed.rawConfig;\n }\n\n const authoredPath = findConfigPath(configDir);\n const tsForm = authoredPath !== null && isAppDescriptorPath(authoredPath);\n let rawConfig: BosConfigInput;\n if (refreshedRawConfig) {\n rawConfig = refreshedRawConfig;\n } else {\n const opened = await openResolution({ cwd: configDir });\n if (!opened?.rawConfig) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to load the authored config for publish\",\n };\n }\n rawConfig = opened.rawConfig;\n }\n if (tsForm && !input.build && plan.publishedConfigState === \"unreachable\") {\n // A config-only TS-form publish derives its pipeline state from the live\n // published config — publishing without it would wipe bundle URLs.\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"Cannot read the currently published config from the registry — a config-only publish would overwrite live bundle URLs. Retry when the registry is reachable, or run a full deploy.\",\n };\n }\n let publishPayload: BosConfigInput =\n tsForm && !input.build\n ? // Config-only publish on a TS-form project: the authored config owns\n // composition (hand-edits win) while live pipeline state (bundle\n // URLs, integrity) carries over from the published config.\n mergeAuthoredOverPublished((plan.publishedConfig ?? {}) as BosConfigInput, rawConfig)\n : rawConfig;\n\n const urlOrigin = plan.cdnOrigin ?? `https://${gateway}`;\n const deployTargets = (built ?? []).filter((key) => targets.includes(key));\n const platformEntries: DeployResultEntry[] = [];\n const fullUpload = input.fullUpload === true || process.env.BOS_FULL_UPLOAD === \"1\";\n // Previous per-workspace pins for the diff upload: the local pointer wins\n // (written after every confirmed publish), the published config is the\n // fallback. Neither → full upload.\n const prevPins: Record<string, PreviousPin> = fullUpload\n ? {}\n : {\n ...pinsFromPublishedConfig(\n (plan.publishedConfig ?? {}) as BosConfigInput,\n account,\n gateway,\n ),\n ...pinsFromDeployState(configDir, account, gateway),\n };\n\n console.log();\n console.log(` CDN deploy — uploading workspace dists to ${storageOrigin}...`);\n for (const key of deployTargets) {\n const ws = resolveWorkspaceTarget(key, bosConfig, runtimeConfig, configDir);\n if (!ws) continue;\n\n const distFiles = await collectDistFiles(join(ws.path, \"dist\"));\n const workspaceBase = `${urlOrigin}/bundles/${account}/${gateway}/${key}/`;\n const startedAt = Date.now();\n // an upload failure aborts the train as a structured error — the\n // previously published version stays fully live (ticket 05)\n let outcome: DiffUploadOutcome;\n try {\n outcome = await diffUploadWorkspace({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: key,\n files: distFiles,\n base: workspaceBase,\n previousPin: prevPins[key],\n });\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: error instanceof Error ? error.message : `[publish] bundle upload for ${key} failed`,\n };\n }\n const report = readBuildReport(join(ws.path, \"dist\"));\n const ssrReport = readBuildReport(join(ws.path, \"dist\", \"ssr\"));\n // the entry SRI keyed by the build report's hashed name\n const integrity = report ? outcome.fileIntegrity[report.entry] : undefined;\n const ssrIntegrity = ssrReport?.entry\n ? outcome.fileIntegrity[`ssr/${ssrReport.entry}`]\n : undefined;\n\n const manifestPointer = await pinWorkspaceVersionManifest({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: key,\n report,\n ssrReport,\n integrityMap: outcome.fileIntegrity,\n files: outcome.fileIntegrity,\n });\n if (!manifestPointer) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `bundle upload for ${key}: version manifest missing — the dist predates hashed entry names (rebuild required; atomic-deploys hard break)`,\n };\n }\n\n if (outcome.result.storage === \"memory\" || manifestPointer.storage === \"memory\") {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"The receiving instance is serving bundle storage from memory (BOS_STORAGE_* R2 credentials are not configured there) — uploaded bytes would be lost on restart. Aborting before publish.\",\n };\n }\n\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(key, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}/ (${outcome.uploaded} uploaded, ${outcome.skipped} skipped, ${formatDuration(Date.now() - startedAt)})`,\n );\n\n platformEntries.push(\n ...platformUrlDeployEntries({\n origin: urlOrigin,\n account,\n gateway,\n key,\n kind: ws.kind,\n integrity,\n ssrIntegrity,\n pin: manifestPointer,\n }),\n );\n\n // Folder-form plugin ui: the workspace build also produces <plugin>/ui/dist\n // (web remoteEntry + ssr container) — upload it as its own bundle key and\n // pin <slot>.<key>.ui.* so the host can compose the ui surface in production.\n if (hasFolderFormUi(ws.path)) {\n const uiDistDir = join(ws.path, \"ui\", \"dist\");\n const uiSlot = ws.kind === \"app\" ? \"app\" : \"plugins\";\n const rawSlot = (uiSlot === \"app\" ? rawConfig.app : rawConfig.plugins) as\n | Record<string, Record<string, unknown> | undefined>\n | undefined;\n const rawUi = rawSlot?.[key]?.ui as Record<string, unknown> | undefined;\n const uiName = resolveUiRuntimeName(rawUi, join(ws.path, \"ui\"), key);\n let uiIntegrity: string | undefined;\n let uiSsrIntegrity: string | undefined;\n let uiManifestPointer: VersionManifestPin | undefined;\n if (existsSync(uiDistDir)) {\n const uiDistFiles = await collectDistFiles(uiDistDir);\n const uiStartedAt = Date.now();\n const uiOutcome = await diffUploadWorkspace({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: `${key}-ui`,\n files: uiDistFiles,\n base: `${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/`,\n previousPin: prevPins[`${key}-ui`],\n });\n const uiReport = readBuildReport(uiDistDir);\n const uiSsrReport = readBuildReport(join(uiDistDir, \"ssr\"));\n uiIntegrity = uiReport ? uiOutcome.fileIntegrity[uiReport.entry] : undefined;\n uiSsrIntegrity = uiSsrReport?.entry\n ? uiOutcome.fileIntegrity[`ssr/${uiSsrReport.entry}`]\n : undefined;\n\n uiManifestPointer = await pinWorkspaceVersionManifest({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: `${key}-ui`,\n report: uiReport,\n ssrReport: uiSsrReport,\n integrityMap: uiOutcome.fileIntegrity,\n files: uiOutcome.fileIntegrity,\n });\n if (!uiManifestPointer) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `bundle upload for ${key}-ui: version manifest missing — the dist predates hashed entry names (rebuild required; atomic-deploys hard break)`,\n };\n }\n\n if (uiOutcome.result.storage === \"memory\" || uiManifestPointer.storage === \"memory\") {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"The receiving instance is serving bundle storage from memory (BOS_STORAGE_* R2 credentials are not configured there) — uploaded bytes would be lost on restart. Aborting before publish.\",\n };\n }\n\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(`${key}-ui`, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/ (${uiOutcome.uploaded} uploaded, ${uiOutcome.skipped} skipped, ${formatDuration(Date.now() - uiStartedAt)})`,\n );\n } else {\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(`${key}-ui`, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/`,\n );\n }\n\n platformEntries.push(\n ...pluginUiUrlDeployEntries({\n origin: urlOrigin,\n account,\n gateway,\n key,\n kind: ws.kind,\n integrity: uiIntegrity,\n ssrIntegrity: uiSsrIntegrity,\n name: uiName,\n pin: uiManifestPointer,\n }),\n );\n }\n }\n\n if (platformEntries.length > 0) {\n const merged = applyDeployResults(rawConfig as Record<string, unknown>, platformEntries);\n if (!tsForm) {\n // Legacy JSON-form children keep their local write-back; TS-form keeps\n // pipeline state in FastKV only — a write-back would shadow the\n // authored bos.app.ts descriptor.\n try {\n writeFileSync(join(configDir, \"bos.config.json\"), `${JSON.stringify(merged, null, 2)}\\n`);\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `Failed to write bundle URLs to bos.config.json: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n publishPayload = merged as BosConfigInput;\n }\n if (isStaging) {\n publishPayload = { ...publishPayload, domain: gateway };\n }\n\n const pinVerification = await verifyRollbackSnapshot(publishPayload);\n if (pinVerification.verifiable && !pinVerification.ok) {\n const failures = pinVerification.slots\n .filter((check) => !check.ok)\n .map((check) => ` ${check.slot}: ${check.reason}`)\n .join(\"\\n\");\n console.error(\n ` ${colors.error(icons.err)} Publish blocked — a pinned slot's bytes do not serve at its production URL:\\n${failures}`,\n );\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `Publish blocked — pinned slot bytes missing or SRI mismatched:\\n${failures}`,\n };\n }\n\n const registryKey = `apps/${account}/${gateway}/bos.config.json`;\n const publishedAt = new Date().toISOString();\n // version identity printed + returned for every deploy (atomic-deploys 12)\n const fingerprint = pointerFingerprint(publishPayload as never);\n const publishSlotPins = slotPins(publishPayload as never);\n const registryEntries: Record<string, string> = {\n [registryKey]: JSON.stringify(publishPayload),\n };\n const manifestKey = `apps/${account}/${gateway}/manifests/${publishedAt.replace(/[:.]/g, \"-\")}.json`;\n registryEntries[manifestKey] = JSON.stringify({\n account,\n gateway,\n network,\n publishedAt,\n registryUrl,\n });\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n console.log(` ${colors.dim(\"Fingerprint:\")} ${fingerprint}`);\n for (const [slot, pin] of Object.entries(publishSlotPins)) {\n console.log(` ${colors.dim(`${slot}:`)}`);\n console.log(` ${pin}`);\n }\n console.log(\n ` ${colors.dim(`+ per-deploy manifest ${manifestKey.split(\"/\").pop()} (audit trail)`)}`,\n );\n\n // Record the live pins for the next deploy's diff upload — only after the\n // config is confirmed published, so the pointer never claims undeployed state.\n const persistDeployState = () => {\n try {\n const pins = pinsFromPublishedConfig(publishPayload as BosConfigInput, account, gateway);\n if (Object.keys(pins).length > 0) {\n upsertDeployStatePins(configDir, account, gateway, pins);\n }\n } catch (error) {\n console.log(\n colors.dim(\n ` Note: could not update .bos/deploy-state.json — ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n }\n };\n\n try {\n const alreadyPublished = await isConfigAlreadyPublished({\n account,\n gateway,\n publishConfig: publishPayload,\n registry: input.registry,\n });\n if (alreadyPublished) {\n console.log(\" Already up to date — skipping transaction\");\n persistDeployState();\n return {\n status: \"published\",\n registryUrl,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n }\n\n console.log(` Submitting transaction on ${network}...`);\n\n let result: { success: boolean; txHash?: string };\n if (useWallet) {\n const session = readSessionHandle(configDir);\n const credential = session?.credential;\n if (!credential || credential.accountId !== account) {\n return {\n status: \"error\",\n registryUrl,\n error: `--wallet requires a CLI session under ${account}. Run bos login first.`,\n };\n }\n const record = await ensureDelegateKey({\n configDir,\n account,\n contract: registryNamespace,\n network,\n siteUrl: credential.siteUrl,\n });\n result = await submitRegistryWriteDelegated({\n account,\n contract: registryNamespace,\n network,\n args: registryEntries,\n delegatePrivateKey: record.privateKey,\n relayEndpoint: `${credential.siteUrl}/api/auth/near/relay`,\n apiKey: credential.apiKey,\n });\n } else {\n if (!strategy) {\n return {\n status: \"error\",\n registryUrl,\n error: \"non-wallet publish requires a resolved signing strategy\",\n };\n }\n result = await submitRegistryWrite(\n {\n account,\n contract: registryNamespace,\n method: \"__fastdata_kv\",\n args: registryEntries,\n network,\n privateKey: input.privateKey,\n },\n strategy,\n );\n }\n\n if (result.txHash) {\n console.log(` Transaction submitted: ${colors.dim(result.txHash)}`);\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n registry: input.registry,\n });\n persistDeployState();\n\n return {\n status: \"published\",\n registryUrl,\n txHash: result.txHash,\n fingerprint,\n slotPins: publishSlotPins,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"does not have enough allowance\")) {\n return (\n \"The publish access key has insufficient allowance to cover this transaction.\\n\" +\n \" Regenerate your key with a higher allowance:\\n\" +\n \" bos key generate\\n\" +\n ` Original: ${message}`\n );\n }\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"publish.cjs","names":["composeWorkspaceVersionManifest","uploadBundle","colors","padRight","localSriMap","resolveSlotVersion","diffWorkspaceFiles","uploadWorkspaceDist","mergedFileIntegrity","process","fetchBosConfigFromFastKv","fetchResponse","join","existsSync","readFileSync","getNetworkIdForAccount","buildRegistryConfigUrlForNetwork","readSessionHandle","resolveSigningStrategy","describeSigningStrategy","resolveCdnDeployInputs","probeStorageOrigin","fetchPublishedConfigFromFastKv","getRegistryNamespaceForNetwork","selectWorkspaceTargets","generateCodeArtifacts","buildWorkspaceTargets","icons","openResolution","findConfigPath","isAppDescriptorPath","mergeAuthoredOverPublished","pinsFromPublishedConfig","pinsFromDeployState","resolveWorkspaceTarget","collectDistFiles","readBuildReport","formatDuration","platformUrlDeployEntries","hasFolderFormUi","resolveUiRuntimeName","pluginUiUrlDeployEntries","applyDeployResults","verifyRollbackSnapshot","pointerFingerprint","slotPins","ensureDelegateKey","submitRegistryWriteDelegated","submitRegistryWrite"],"sources":["../src/publish.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { hasFolderFormUi } from \"every-plugin/build/ui\";\nimport { readSessionHandle } from \"./auth-session\";\nimport { buildWorkspaceTargets, resolveWorkspaceTarget, selectWorkspaceTargets } from \"./build\";\nimport { type CdnDeployInputs, probeStorageOrigin, resolveCdnDeployInputs } from \"./cdn-deploy\";\nimport { formatDuration } from \"./cli/timing\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { findConfigPath, isAppDescriptorPath, resolveUiRuntimeName } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { ensureDelegateKey, submitRegistryWriteDelegated } from \"./delegate-signer\";\nimport {\n diffWorkspaceFiles,\n localSriMap,\n mergedFileIntegrity,\n type PreviousPin,\n pinsFromDeployState,\n pinsFromPublishedConfig,\n upsertDeployStatePins,\n} from \"./deploy-diff\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n fetchPublishedConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n type NetworkId,\n} from \"./fastkv\";\nimport { pointerFingerprint, slotPins } from \"./fingerprint\";\nimport { fetchResponse } from \"./http-client\";\nimport { applyDeployResults, type DeployResultEntry } from \"./integrity\";\nimport { mergeAuthoredOverPublished } from \"./merge\";\nimport {\n describeSigningStrategy,\n resolveSigningStrategy,\n type SigningStrategy,\n submitRegistryWrite,\n} from \"./near-signer\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport { platformUrlDeployEntries, pluginUiUrlDeployEntries } from \"./platform-deploy\";\nimport { openResolution } from \"./resolution/session\";\nimport { verifyRollbackSnapshot } from \"./rollback\";\nimport {\n collectDistFiles,\n type DistFile,\n uploadBundle,\n uploadWorkspaceDist,\n} from \"./storage-upload\";\nimport type { BosConfig, BosConfigInput, PublishConfig, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\nimport { composeWorkspaceVersionManifest, readBuildReport } from \"./version-manifest-deploy\";\nimport { resolveSlotVersion } from \"./version-manifest-resolve\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Compose + upload the workspace's version manifest (atomic-deploys 03): the\n * manifest is built from the dist build report + the **server-computed** SRI\n * map of the just-finished upload, uploaded additively at\n * `versions/<version>.json`, and returned as the slot's pointer. Returns\n * undefined when the dist predates hashed entry names (no report / no entry\n * SRI) — the caller aborts the train: uploaded workspaces must pin.\n */\n/**\n * The manifest's own storage backend — when every dist file was diff-skipped\n * it is the only upload of the leg, so it is the only signal for the\n * memory-backend abort below.\n */\nexport interface VersionManifestPin {\n file: string;\n integrity: string;\n storage?: \"s3\" | \"memory\";\n}\n\nasync function pinWorkspaceVersionManifest(input: {\n origin: string;\n apiKey?: string;\n account: string;\n gateway: string;\n workspace: string;\n report: ReturnType<typeof readBuildReport>;\n ssrReport: ReturnType<typeof readBuildReport>;\n integrityMap: Record<string, string>;\n /** full per-file SRI map of the dist — recorded for the next deploy's diff */\n files?: Record<string, string>;\n}): Promise<VersionManifestPin | undefined> {\n if (!input.report) return undefined;\n const versionManifest = composeWorkspaceVersionManifest({\n report: input.report,\n ssrReport: input.ssrReport,\n integrityMap: input.integrityMap,\n ...(input.files ? { files: input.files } : {}),\n });\n if (!versionManifest) return undefined;\n\n const manifestFile = `versions/${versionManifest.version}.json`;\n const manifestUpload = await uploadBundle({\n origin: input.origin,\n apiKey: input.apiKey,\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n files: [\n {\n path: manifestFile,\n bytes: new TextEncoder().encode(`${JSON.stringify(versionManifest, null, 2)}\\n`),\n },\n ],\n });\n const manifestIntegrity = manifestUpload.integrity[manifestFile];\n if (!manifestIntegrity) return undefined;\n console.log(\n ` ${colors.dim(`${padRight(\"\", 28)} version manifest ${manifestFile} (SRI pinned)`)}`,\n );\n return { file: manifestFile, integrity: manifestIntegrity, storage: manifestUpload.storage };\n}\n\ninterface DiffUploadOutcome {\n result: {\n stored: number;\n totalBytes: number;\n integrity: Record<string, string>;\n storage?: \"s3\" | \"memory\";\n };\n /** per-file SRI map covering the whole dist (uploaded → server SRI, skipped → previous manifest SRI) */\n fileIntegrity: Record<string, string>;\n uploaded: number;\n skipped: number;\n total: number;\n}\n\n/**\n * One workspace's upload leg with skip-unchanged diffing: resolve the previous\n * manifest's `files` map, hash the local dist, upload only new/changed files,\n * and return the merged per-file SRI map for the version manifest. Any failure\n * to resolve the previous map degrades to a full upload.\n */\nasync function diffUploadWorkspace(input: {\n origin: string;\n apiKey?: string;\n account: string;\n gateway: string;\n workspace: string;\n files: DistFile[];\n base: string;\n previousPin: PreviousPin | undefined;\n}): Promise<DiffUploadOutcome> {\n const localSri = localSriMap(input.files);\n let uploadFiles = input.files;\n let prevFiles: Record<string, string> | undefined;\n if (input.previousPin) {\n try {\n const resolved = await resolveSlotVersion({ base: input.base, pin: input.previousPin });\n if (resolved.files) {\n const diff = diffWorkspaceFiles(input.files, localSri, resolved.files);\n prevFiles = resolved.files;\n uploadFiles = diff.upload;\n if (diff.skipped > 0) {\n console.log(\n ` ${colors.dim(`${padRight(input.workspace, 28)} ${diff.skipped} unchanged file(s) — skipping (manifest diff)`)}`,\n );\n }\n }\n } catch {\n console.log(\n ` ${colors.dim(`${padRight(input.workspace, 28)} previous manifest unusable — uploading everything`)}`,\n );\n }\n }\n\n console.log(\n ` ${padRight(input.workspace, 28)} uploading ${uploadFiles.length} of ${input.files.length} files (${formatBundleMb(uploadFiles)}) → ${input.base}`,\n );\n const result =\n uploadFiles.length > 0\n ? await uploadWorkspaceDist({\n origin: input.origin,\n apiKey: input.apiKey,\n account: input.account,\n gateway: input.gateway,\n workspace: input.workspace,\n files: uploadFiles,\n })\n : { stored: 0, totalBytes: 0, integrity: {}, storage: undefined };\n return {\n result,\n fileIntegrity: mergedFileIntegrity(input.files, result.integrity, prevFiles),\n uploaded: result.stored,\n skipped: input.files.length - uploadFiles.length,\n total: input.files.length,\n };\n}\n\nfunction formatBundleMb(files: Array<{ bytes: Uint8Array }>): string {\n const total = files.reduce((sum, file) => sum + file.bytes.byteLength, 0);\n return `${(total / 1024 / 1024).toFixed(1)} MB`;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n registry?: string;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n opts.registry,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\nexport async function isConfigAlreadyPublished(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n registry?: string;\n}): Promise<boolean> {\n try {\n const current = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n opts.registry,\n );\n return JSON.stringify(current) === JSON.stringify(opts.publishConfig);\n } catch {\n return false;\n }\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n wallet?: boolean;\n registry?: string;\n /** Skip the diff upload and re-upload every dist file (escape hatch). */\n fullUpload?: boolean;\n /** Publish `bosConfig` verbatim — no authored/published merge, no ts-form\n * config-only guard. Rollbacks use this: the payload is the previous\n * snapshot, already assembled. */\n exactPayload?: boolean;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n fingerprint?: string;\n slotPins?: Record<string, string>;\n}\n\nexport type PublishedConfigState = \"fetched\" | \"missing\" | \"unreachable\";\n\nexport interface PublishPreflightPlan {\n isStaging: boolean;\n account: string;\n gateway: string;\n network: NetworkId;\n registryUrl: string;\n registryNamespace: string;\n targets: string[];\n useWallet: boolean;\n strategy?: SigningStrategy;\n cdnOrigin: string | undefined;\n storageOrigin: string;\n storageApiKey?: string;\n /** The config currently published to FastKV (null when missing or unreachable). */\n publishedConfig: Record<string, unknown> | null;\n /** Whether the preflight FastKV read succeeded, found nothing, or failed. */\n publishedConfigState: PublishedConfigState;\n}\n\nexport type PublishPreflight =\n | { kind: \"dry-run\"; registryUrl: string }\n | { kind: \"error\"; registryUrl: string; error: string }\n | { kind: \"ready\"; plan: PublishPreflightPlan };\n\nconst FRAMEWORK_PACKAGE_NAMES = [\"better-near-auth\", \"every-plugin\", \"everything-dev\"] as const;\n\n/**\n * Whether npm serves `name@version` (true), definitively does not (404 —\n * false), or whether publishability could not be determined (network error,\n * unexpected status — null; callers must not block on that).\n */\nexport async function npmVersionPublished(name: string, version: string): Promise<boolean | null> {\n try {\n const res = await fetchResponse(`https://registry.npmjs.org/${name}/${version}`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.status === 200) return true;\n if (res.status === 404) return false;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * The npm-publish gate: a workspace that vendors the framework packages'\n * sources must not ship bundles ahead of npm — the update check, child\n * scaffolds (`bos init`), and template syncs all read those versions from\n * the registry. Reads only apply when the sources are workspace-local (the\n * parent repo); child projects install the framework from npm and are\n * inherently in sync.\n */\nexport async function findUnpublishedFrameworkPackages(\n configDir: string,\n): Promise<Array<{ name: string; version: string }>> {\n const unpublished: Array<{ name: string; version: string }> = [];\n for (const name of FRAMEWORK_PACKAGE_NAMES) {\n const manifestPath = join(configDir, \"packages\", name, \"package.json\");\n if (!existsSync(manifestPath)) continue;\n const version = (JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { version?: string })\n .version;\n if (!version) continue;\n const published = await npmVersionPublished(name, version);\n if (published === false) {\n unpublished.push({ name, version });\n } else if (published === null) {\n console.log(\n colors.yellow(\n ` ! Could not verify ${name}@${version} on npm (registry unreachable) — continuing`,\n ),\n );\n }\n }\n return unpublished;\n}\n\n// Pure preflight (resolve, don't mutate) — every failure returns before the\n// build train runs (issue #287). Dry-run exits after the auth guards, before\n// any signing (keychain/TTY side effects).\nexport async function preflightPublish(input: PublishToFastKvInput): Promise<PublishPreflight> {\n const { configDir } = input;\n const bosConfig = input.bosConfig;\n\n const isStaging = input.env === \"staging\";\n const account = isStaging ? (bosConfig.staging?.account ?? bosConfig.account) : bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n kind: \"error\",\n registryUrl: \"\",\n error: \"authored config must define domain to publish\",\n };\n }\n\n const network: NetworkId = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway, input.registry);\n const fail = (error: string): PublishPreflight => ({ kind: \"error\", registryUrl, error });\n\n const publishAuth: PublishConfig[\"auth\"] = bosConfig.publish?.auth;\n const governsWalletPublish = (publishAuth === \"session\" || input.wallet) && !input.privateKey;\n if (governsWalletPublish) {\n const session = readSessionHandle(configDir);\n if (!session?.credential) {\n return fail(\n (input.wallet\n ? \"--wallet requires\"\n : 'the authored config sets publish.auth = \"session\", but') +\n \" no CLI session is stored in .bos/ for this project. Run bos login to create one.\",\n );\n }\n if (session.credential.accountId && session.credential.accountId !== account) {\n return fail(\n `The CLI session was created for ${session.credential.accountId}, but the configured ` +\n `account is ${account}. Gasless wallet publish relays the FastKV write under the session's ` +\n \"NEAR account. Run bos login again under the matching account.\",\n );\n }\n }\n if (publishAuth && !input.privateKey) {\n if (publishAuth === \"custody\") {\n return fail(\n 'the authored config sets publish.auth = \"custody\", but custody publish is not implemented yet (see NEARBuilders/everything-dev#291).',\n );\n }\n }\n\n if (input.dryRun) {\n return { kind: \"dry-run\", registryUrl };\n }\n\n const useWallet = input.wallet === true;\n let strategy: SigningStrategy | undefined;\n if (useWallet) {\n console.log(\n ` Signing via ${colors.cyan(\"gasless NEP-366 delegate action (relayed by the platform relayer)\")}`,\n );\n } else {\n try {\n strategy = await resolveSigningStrategy({ privateKey: input.privateKey, account, network });\n console.log(` Signing via ${colors.cyan(describeSigningStrategy(strategy))}`);\n } catch (error) {\n return fail(error instanceof Error ? error.message : \"Unknown error\");\n }\n }\n\n // CDN deploy credentials (ADR 0020) — resolved before the build train so a\n // missing bundle origin or BOS_STORAGE_API_KEY fails fast instead of after\n // the full build. Config-only publishes ship the committed config verbatim;\n // nothing is uploaded, so no deploy origins are required.\n const session = readSessionHandle(configDir);\n let cdnDeploy: CdnDeployInputs = {\n cdnOrigin: undefined,\n storageOrigin: \"\",\n apiKey: undefined,\n };\n if (input.build) {\n const unpublished = await findUnpublishedFrameworkPackages(configDir);\n if (unpublished.length > 0) {\n const listing = unpublished.map((pkg) => `${pkg.name}@${pkg.version}`).join(\", \");\n return fail(\n `Framework package(s) ${listing} are not published to npm yet — deploys must not ship ` +\n \"bundles ahead of the registry (child scaffolds and update checks read these versions). \" +\n \"Re-run the Release workflow (or `pnpm run release`) first.\",\n );\n }\n\n cdnDeploy = resolveCdnDeployInputs({\n env: process.env as Record<string, string | undefined>,\n bosConfig,\n session: session?.credential ?? null,\n account,\n gateway,\n uploadsPlanned: input.build,\n });\n if (cdnDeploy.error) {\n return fail(cdnDeploy.error);\n }\n if (cdnDeploy.warning) {\n console.log(colors.yellow(` ! ${cdnDeploy.warning}`));\n }\n const cdnOrigin = cdnDeploy.cdnOrigin;\n if (!cdnOrigin) {\n return fail(\"CDN deploy resolved no bundle origin\");\n }\n const probeError = await probeStorageOrigin(cdnDeploy.storageOrigin);\n if (probeError) {\n return fail(\n `The bundle upload origin ${cdnDeploy.storageOrigin} is not running the platform API — ` +\n `${probeError}. Check BOS_STORAGE_ORIGIN / the bos login session, then re-run.`,\n );\n }\n }\n\n // Registry reachability + published-state capture: one FastKV read. A\n // missing config is fine for a first publish — an early signal, not a hard\n // gate. The captured config is the merge base for a config-only publish on\n // a TS-form project (authored hand-edits win; live pipeline state carries).\n let publishedConfig: Record<string, unknown> | null = null;\n let publishedConfigState: PublishedConfigState = \"missing\";\n try {\n publishedConfig = await fetchPublishedConfigFromFastKv<Record<string, unknown>>(registryUrl);\n publishedConfigState = \"fetched\";\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.startsWith(\"No config found\")) {\n console.log(colors.dim(\" Note: no published config found yet (first publish) — continuing\"));\n } else {\n publishedConfigState = \"unreachable\";\n console.log(colors.dim(\" Note: registry read failed — continuing\"));\n }\n }\n\n return {\n kind: \"ready\",\n plan: {\n isStaging,\n account,\n gateway,\n network,\n registryUrl,\n registryNamespace: getRegistryNamespaceForNetwork(network, input.registry),\n targets: selectWorkspaceTargets(input.packages, bosConfig),\n useWallet,\n strategy,\n cdnOrigin: cdnDeploy.cdnOrigin,\n storageOrigin: cdnDeploy.storageOrigin,\n storageApiKey: cdnDeploy.apiKey,\n publishedConfig,\n publishedConfigState,\n },\n };\n}\n\n/**\n * The deploy-train publish core (ADR 0020, as amended): preflight\n * (storage/CDN creds + signing) fails fast before the build, then build →\n * upload → version-manifest pin → config write-back → FastKV publish +\n * read-back. Scoped to one plugin via `packages`, a single-plugin redeploy\n * ships real bytes to the storage origin — same as the full train, nothing\n * image-native left.\n */\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const preflight = await preflightPublish(input);\n if (preflight.kind === \"error\") {\n return { status: \"error\", registryUrl: preflight.registryUrl, error: preflight.error };\n }\n if (preflight.kind === \"dry-run\") {\n return { status: \"dry-run\", registryUrl: preflight.registryUrl };\n }\n const plan = preflight.plan;\n const {\n isStaging,\n account,\n gateway,\n network,\n registryUrl,\n registryNamespace,\n targets,\n useWallet,\n strategy,\n } = plan;\n const storageOrigin = plan.storageOrigin;\n const storageApiKey = plan.storageApiKey;\n\n const { configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n let refreshedRawConfig: BosConfigInput | null = null;\n\n if (input.build) {\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await openResolution({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload the config after build\",\n };\n }\n\n bosConfig = refreshed.config;\n refreshedRawConfig = refreshed.rawConfig;\n }\n\n const authoredPath = findConfigPath(configDir);\n const tsForm = authoredPath !== null && isAppDescriptorPath(authoredPath);\n let rawConfig: BosConfigInput;\n if (refreshedRawConfig) {\n rawConfig = refreshedRawConfig;\n } else {\n const opened = await openResolution({ cwd: configDir });\n if (!opened?.rawConfig) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to load the authored config for publish\",\n };\n }\n rawConfig = opened.rawConfig;\n }\n if (\n tsForm &&\n !input.build &&\n input.exactPayload !== true &&\n plan.publishedConfigState === \"unreachable\"\n ) {\n // A config-only TS-form publish derives its pipeline state from the live\n // published config — publishing without it would wipe bundle URLs.\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"Cannot read the currently published config from the registry — a config-only publish would overwrite live bundle URLs. Retry when the registry is reachable, or run a full deploy.\",\n };\n }\n let publishPayload: BosConfigInput =\n input.exactPayload === true\n ? input.bosConfig\n : tsForm && !input.build\n ? // Config-only publish on a TS-form project: the authored config owns\n // composition (hand-edits win) while live pipeline state (bundle\n // URLs, integrity) carries over from the published config.\n mergeAuthoredOverPublished((plan.publishedConfig ?? {}) as BosConfigInput, rawConfig)\n : rawConfig;\n\n const urlOrigin = plan.cdnOrigin ?? `https://${gateway}`;\n const deployTargets = (built ?? []).filter((key) => targets.includes(key));\n const platformEntries: DeployResultEntry[] = [];\n const fullUpload = input.fullUpload === true || process.env.BOS_FULL_UPLOAD === \"1\";\n // Previous per-workspace pins for the diff upload: the local pointer wins\n // (written after every confirmed publish), the published config is the\n // fallback. Neither → full upload.\n const prevPins: Record<string, PreviousPin> = fullUpload\n ? {}\n : {\n ...pinsFromPublishedConfig(\n (plan.publishedConfig ?? {}) as BosConfigInput,\n account,\n gateway,\n ),\n ...pinsFromDeployState(configDir, account, gateway),\n };\n\n console.log();\n console.log(` CDN deploy — uploading workspace dists to ${storageOrigin}...`);\n for (const key of deployTargets) {\n const ws = resolveWorkspaceTarget(key, bosConfig, runtimeConfig, configDir);\n if (!ws) continue;\n\n const distFiles = await collectDistFiles(join(ws.path, \"dist\"));\n const workspaceBase = `${urlOrigin}/bundles/${account}/${gateway}/${key}/`;\n const startedAt = Date.now();\n // an upload failure aborts the train as a structured error — the\n // previously published version stays fully live (ticket 05)\n let outcome: DiffUploadOutcome;\n try {\n outcome = await diffUploadWorkspace({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: key,\n files: distFiles,\n base: workspaceBase,\n previousPin: prevPins[key],\n });\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: error instanceof Error ? error.message : `[publish] bundle upload for ${key} failed`,\n };\n }\n const report = readBuildReport(join(ws.path, \"dist\"));\n const ssrReport = readBuildReport(join(ws.path, \"dist\", \"ssr\"));\n // the entry SRI keyed by the build report's hashed name\n const integrity = report ? outcome.fileIntegrity[report.entry] : undefined;\n const ssrIntegrity = ssrReport?.entry\n ? outcome.fileIntegrity[`ssr/${ssrReport.entry}`]\n : undefined;\n\n const manifestPointer = await pinWorkspaceVersionManifest({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: key,\n report,\n ssrReport,\n integrityMap: outcome.fileIntegrity,\n files: outcome.fileIntegrity,\n });\n if (!manifestPointer) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `bundle upload for ${key}: version manifest missing — the dist predates hashed entry names (rebuild required; atomic-deploys hard break)`,\n };\n }\n\n if (outcome.result.storage === \"memory\" || manifestPointer.storage === \"memory\") {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"The receiving instance is serving bundle storage from memory (BOS_STORAGE_* R2 credentials are not configured there) — uploaded bytes would be lost on restart. Aborting before publish.\",\n };\n }\n\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(key, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}/ (${outcome.uploaded} uploaded, ${outcome.skipped} skipped, ${formatDuration(Date.now() - startedAt)})`,\n );\n\n platformEntries.push(\n ...platformUrlDeployEntries({\n origin: urlOrigin,\n account,\n gateway,\n key,\n kind: ws.kind,\n integrity,\n ssrIntegrity,\n pin: manifestPointer,\n }),\n );\n\n // Folder-form plugin ui: the workspace build also produces <plugin>/ui/dist\n // (web remoteEntry + ssr container) — upload it as its own bundle key and\n // pin <slot>.<key>.ui.* so the host can compose the ui surface in production.\n if (hasFolderFormUi(ws.path)) {\n const uiDistDir = join(ws.path, \"ui\", \"dist\");\n const uiSlot = ws.kind === \"app\" ? \"app\" : \"plugins\";\n const rawSlot = (uiSlot === \"app\" ? rawConfig.app : rawConfig.plugins) as\n | Record<string, Record<string, unknown> | undefined>\n | undefined;\n const rawUi = rawSlot?.[key]?.ui as Record<string, unknown> | undefined;\n const uiName = resolveUiRuntimeName(rawUi, join(ws.path, \"ui\"), key);\n let uiIntegrity: string | undefined;\n let uiSsrIntegrity: string | undefined;\n let uiManifestPointer: VersionManifestPin | undefined;\n if (existsSync(uiDistDir)) {\n const uiDistFiles = await collectDistFiles(uiDistDir);\n const uiStartedAt = Date.now();\n const uiOutcome = await diffUploadWorkspace({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: `${key}-ui`,\n files: uiDistFiles,\n base: `${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/`,\n previousPin: prevPins[`${key}-ui`],\n });\n const uiReport = readBuildReport(uiDistDir);\n const uiSsrReport = readBuildReport(join(uiDistDir, \"ssr\"));\n uiIntegrity = uiReport ? uiOutcome.fileIntegrity[uiReport.entry] : undefined;\n uiSsrIntegrity = uiSsrReport?.entry\n ? uiOutcome.fileIntegrity[`ssr/${uiSsrReport.entry}`]\n : undefined;\n\n uiManifestPointer = await pinWorkspaceVersionManifest({\n origin: storageOrigin,\n apiKey: storageApiKey,\n account,\n gateway,\n workspace: `${key}-ui`,\n report: uiReport,\n ssrReport: uiSsrReport,\n integrityMap: uiOutcome.fileIntegrity,\n files: uiOutcome.fileIntegrity,\n });\n if (!uiManifestPointer) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `bundle upload for ${key}-ui: version manifest missing — the dist predates hashed entry names (rebuild required; atomic-deploys hard break)`,\n };\n }\n\n if (uiOutcome.result.storage === \"memory\" || uiManifestPointer.storage === \"memory\") {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error:\n \"The receiving instance is serving bundle storage from memory (BOS_STORAGE_* R2 credentials are not configured there) — uploaded bytes would be lost on restart. Aborting before publish.\",\n };\n }\n\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(`${key}-ui`, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/ (${uiOutcome.uploaded} uploaded, ${uiOutcome.skipped} skipped, ${formatDuration(Date.now() - uiStartedAt)})`,\n );\n } else {\n console.log(\n ` ${colors.green(icons.ok)} ${padRight(`${key}-ui`, 28)} → ${urlOrigin}/bundles/${account}/${gateway}/${key}-ui/`,\n );\n }\n\n platformEntries.push(\n ...pluginUiUrlDeployEntries({\n origin: urlOrigin,\n account,\n gateway,\n key,\n kind: ws.kind,\n integrity: uiIntegrity,\n ssrIntegrity: uiSsrIntegrity,\n name: uiName,\n pin: uiManifestPointer,\n }),\n );\n }\n }\n\n if (platformEntries.length > 0) {\n const merged = applyDeployResults(rawConfig as Record<string, unknown>, platformEntries);\n if (!tsForm) {\n // Legacy JSON-form children keep their local write-back; TS-form keeps\n // pipeline state in FastKV only — a write-back would shadow the\n // authored bos.app.ts descriptor.\n try {\n writeFileSync(join(configDir, \"bos.config.json\"), `${JSON.stringify(merged, null, 2)}\\n`);\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `Failed to write bundle URLs to bos.config.json: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n publishPayload = merged as BosConfigInput;\n }\n if (isStaging) {\n publishPayload = { ...publishPayload, domain: gateway };\n }\n\n const pinVerification = await verifyRollbackSnapshot(publishPayload);\n if (pinVerification.verifiable && !pinVerification.ok) {\n const failures = pinVerification.slots\n .filter((check) => !check.ok)\n .map((check) => ` ${check.slot}: ${check.reason}`)\n .join(\"\\n\");\n console.error(\n ` ${colors.error(icons.err)} Publish blocked — a pinned slot's bytes do not serve at its production URL:\\n${failures}`,\n );\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `Publish blocked — pinned slot bytes missing or SRI mismatched:\\n${failures}`,\n };\n }\n\n const registryKey = `apps/${account}/${gateway}/bos.config.json`;\n const publishedAt = new Date().toISOString();\n // version identity printed + returned for every deploy (atomic-deploys 12)\n const fingerprint = pointerFingerprint(publishPayload as never);\n const publishSlotPins = slotPins(publishPayload as never);\n const registryEntries: Record<string, string> = {\n [registryKey]: JSON.stringify(publishPayload),\n };\n const manifestKey = `apps/${account}/${gateway}/manifests/${publishedAt.replace(/[:.]/g, \"-\")}.json`;\n registryEntries[manifestKey] = JSON.stringify({\n account,\n gateway,\n network,\n publishedAt,\n registryUrl,\n });\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n console.log(` ${colors.dim(\"Fingerprint:\")} ${fingerprint}`);\n for (const [slot, pin] of Object.entries(publishSlotPins)) {\n console.log(` ${colors.dim(`${slot}:`)}`);\n console.log(` ${pin}`);\n }\n console.log(\n ` ${colors.dim(`+ per-deploy manifest ${manifestKey.split(\"/\").pop()} (audit trail)`)}`,\n );\n\n // Record the live pins for the next deploy's diff upload — only after the\n // config is confirmed published, so the pointer never claims undeployed state.\n const persistDeployState = () => {\n try {\n const pins = pinsFromPublishedConfig(publishPayload as BosConfigInput, account, gateway);\n if (Object.keys(pins).length > 0) {\n upsertDeployStatePins(configDir, account, gateway, pins);\n }\n } catch (error) {\n console.log(\n colors.dim(\n ` Note: could not update .bos/deploy-state.json — ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n }\n };\n\n try {\n const alreadyPublished = await isConfigAlreadyPublished({\n account,\n gateway,\n publishConfig: publishPayload,\n registry: input.registry,\n });\n if (alreadyPublished) {\n console.log(\" Already up to date — skipping transaction\");\n persistDeployState();\n return {\n status: \"published\",\n registryUrl,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n }\n\n console.log(` Submitting transaction on ${network}...`);\n\n let result: { success: boolean; txHash?: string };\n if (useWallet) {\n const session = readSessionHandle(configDir);\n const credential = session?.credential;\n if (!credential || credential.accountId !== account) {\n return {\n status: \"error\",\n registryUrl,\n error: `--wallet requires a CLI session under ${account}. Run bos login first.`,\n };\n }\n const record = await ensureDelegateKey({\n configDir,\n account,\n contract: registryNamespace,\n network,\n siteUrl: credential.siteUrl,\n });\n result = await submitRegistryWriteDelegated({\n account,\n contract: registryNamespace,\n network,\n args: registryEntries,\n delegatePrivateKey: record.privateKey,\n relayEndpoint: `${credential.siteUrl}/api/auth/near/relay`,\n apiKey: credential.apiKey,\n });\n } else {\n if (!strategy) {\n return {\n status: \"error\",\n registryUrl,\n error: \"non-wallet publish requires a resolved signing strategy\",\n };\n }\n result = await submitRegistryWrite(\n {\n account,\n contract: registryNamespace,\n method: \"__fastdata_kv\",\n args: registryEntries,\n network,\n privateKey: input.privateKey,\n },\n strategy,\n );\n }\n\n if (result.txHash) {\n console.log(` Transaction submitted: ${colors.dim(result.txHash)}`);\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n registry: input.registry,\n });\n persistDeployState();\n\n return {\n status: \"published\",\n registryUrl,\n txHash: result.txHash,\n fingerprint,\n slotPins: publishSlotPins,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"does not have enough allowance\")) {\n return (\n \"The publish access key has insufficient allowance to cover this transaction.\\n\" +\n \" Regenerate your key with a higher allowance:\\n\" +\n \" bos key generate\\n\" +\n ` Original: ${message}`\n );\n }\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}
package/dist/publish.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { fetchResponse } from "./http-client.mjs";
2
2
  import { mergeAuthoredOverPublished } from "./merge.mjs";
3
- import { buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, getRegistryNamespaceForNetwork } from "./fastkv.mjs";
3
+ import { buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchPublishedConfigFromFastKv, getRegistryNamespaceForNetwork } from "./fastkv.mjs";
4
4
  import { getNetworkIdForAccount } from "./network.mjs";
5
5
  import { resolveSlotVersion } from "./version-manifest-resolve.mjs";
6
6
  import { findConfigPath, isAppDescriptorPath, resolveUiRuntimeName } from "./config.mjs";
@@ -250,7 +250,7 @@ async function preflightPublish(input) {
250
250
  let publishedConfig = null;
251
251
  let publishedConfigState = "missing";
252
252
  try {
253
- publishedConfig = await fetchBosConfigFromFastKv(registryUrl, input.registry);
253
+ publishedConfig = await fetchPublishedConfigFromFastKv(registryUrl);
254
254
  publishedConfigState = "fetched";
255
255
  } catch (error) {
256
256
  if ((error instanceof Error ? error.message : String(error)).startsWith("No config found")) console.log(colors.dim(" Note: no published config found yet (first publish) — continuing"));
@@ -379,7 +379,7 @@ async function publishToFastKv(input) {
379
379
  };
380
380
  rawConfig = opened.rawConfig;
381
381
  }
382
- if (tsForm && !input.build && plan.publishedConfigState === "unreachable") return {
382
+ if (tsForm && !input.build && input.exactPayload !== true && plan.publishedConfigState === "unreachable") return {
383
383
  status: "error",
384
384
  registryUrl,
385
385
  built,
@@ -387,7 +387,7 @@ async function publishToFastKv(input) {
387
387
  deployResults,
388
388
  error: "Cannot read the currently published config from the registry — a config-only publish would overwrite live bundle URLs. Retry when the registry is reachable, or run a full deploy."
389
389
  };
390
- let publishPayload = tsForm && !input.build ? mergeAuthoredOverPublished(plan.publishedConfig ?? {}, rawConfig) : rawConfig;
390
+ let publishPayload = input.exactPayload === true ? input.bosConfig : tsForm && !input.build ? mergeAuthoredOverPublished(plan.publishedConfig ?? {}, rawConfig) : rawConfig;
391
391
  const urlOrigin = plan.cdnOrigin ?? `https://${gateway}`;
392
392
  const deployTargets = (built ?? []).filter((key) => targets.includes(key));
393
393
  const platformEntries = [];