everything-dev 1.51.5 → 1.51.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 (238) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +0 -2
  2. package/dist/api-contract.cjs +0 -1
  3. package/dist/api-contract.cjs.map +1 -1
  4. package/dist/api-contract.mjs.map +1 -1
  5. package/dist/app.cjs +1 -1
  6. package/dist/app.cjs.map +1 -1
  7. package/dist/app.mjs +1 -1
  8. package/dist/app.mjs.map +1 -1
  9. package/dist/build.cjs +16 -22
  10. package/dist/build.cjs.map +1 -1
  11. package/dist/build.mjs +16 -22
  12. package/dist/build.mjs.map +1 -1
  13. package/dist/cli/catalog.cjs.map +1 -1
  14. package/dist/cli/catalog.mjs.map +1 -1
  15. package/dist/cli/db-doctor.cjs +1 -2
  16. package/dist/cli/db-doctor.cjs.map +1 -1
  17. package/dist/cli/db-doctor.mjs +1 -1
  18. package/dist/cli/db-doctor.mjs.map +1 -1
  19. package/dist/cli/db-repair.cjs +1 -2
  20. package/dist/cli/db-repair.cjs.map +1 -1
  21. package/dist/cli/db-repair.mjs +1 -1
  22. package/dist/cli/db-repair.mjs.map +1 -1
  23. package/dist/cli/db-studio.cjs.map +1 -1
  24. package/dist/cli/db-studio.mjs.map +1 -1
  25. package/dist/cli/framework-version.cjs +2 -1
  26. package/dist/cli/framework-version.cjs.map +1 -1
  27. package/dist/cli/framework-version.mjs +1 -1
  28. package/dist/cli/framework-version.mjs.map +1 -1
  29. package/dist/cli/help.cjs.map +1 -1
  30. package/dist/cli/help.mjs.map +1 -1
  31. package/dist/cli/infra.cjs +4 -0
  32. package/dist/cli/infra.cjs.map +1 -1
  33. package/dist/cli/infra.mjs +1 -1
  34. package/dist/cli/infra.mjs.map +1 -1
  35. package/dist/cli/init.cjs +3 -4
  36. package/dist/cli/init.cjs.map +1 -1
  37. package/dist/cli/init.d.cts +0 -1
  38. package/dist/cli/init.d.cts.map +1 -1
  39. package/dist/cli/init.d.mts +0 -1
  40. package/dist/cli/init.d.mts.map +1 -1
  41. package/dist/cli/init.mjs +3 -3
  42. package/dist/cli/init.mjs.map +1 -1
  43. package/dist/cli/parse.cjs.map +1 -1
  44. package/dist/cli/parse.mjs.map +1 -1
  45. package/dist/cli/prompts.cjs.map +1 -1
  46. package/dist/cli/prompts.mjs.map +1 -1
  47. package/dist/cli/snapshot.cjs +0 -1
  48. package/dist/cli/snapshot.cjs.map +1 -1
  49. package/dist/cli/snapshot.mjs.map +1 -1
  50. package/dist/cli/status.cjs +0 -1
  51. package/dist/cli/status.cjs.map +1 -1
  52. package/dist/cli/status.mjs.map +1 -1
  53. package/dist/cli/sync.cjs +2 -2
  54. package/dist/cli/sync.cjs.map +1 -1
  55. package/dist/cli/sync.mjs +2 -2
  56. package/dist/cli/sync.mjs.map +1 -1
  57. package/dist/cli/timing.cjs.map +1 -1
  58. package/dist/cli/timing.mjs.map +1 -1
  59. package/dist/cli/upgrade.cjs +3 -0
  60. package/dist/cli/upgrade.cjs.map +1 -1
  61. package/dist/cli/upgrade.mjs +1 -1
  62. package/dist/cli/upgrade.mjs.map +1 -1
  63. package/dist/cli.cjs.map +1 -1
  64. package/dist/cli.d.cts +1 -1
  65. package/dist/cli.d.mts +1 -1
  66. package/dist/cli.mjs.map +1 -1
  67. package/dist/code-artifacts.cjs +0 -1
  68. package/dist/code-artifacts.cjs.map +1 -1
  69. package/dist/code-artifacts.mjs.map +1 -1
  70. package/dist/components/dev-view.cjs +0 -1
  71. package/dist/components/dev-view.cjs.map +1 -1
  72. package/dist/components/dev-view.mjs.map +1 -1
  73. package/dist/components/streaming-view.cjs.map +1 -1
  74. package/dist/components/streaming-view.mjs.map +1 -1
  75. package/dist/config.cjs +0 -1
  76. package/dist/config.cjs.map +1 -1
  77. package/dist/config.d.cts +0 -1
  78. package/dist/config.d.cts.map +1 -1
  79. package/dist/config.d.mts +0 -1
  80. package/dist/config.d.mts.map +1 -1
  81. package/dist/config.mjs.map +1 -1
  82. package/dist/contract.cjs.map +1 -1
  83. package/dist/contract.d.cts +42 -44
  84. package/dist/contract.d.cts.map +1 -1
  85. package/dist/contract.d.mts +42 -44
  86. package/dist/contract.d.mts.map +1 -1
  87. package/dist/contract.meta.cjs.map +1 -1
  88. package/dist/contract.meta.d.cts.map +1 -1
  89. package/dist/contract.meta.d.mts.map +1 -1
  90. package/dist/contract.meta.mjs.map +1 -1
  91. package/dist/contract.mjs.map +1 -1
  92. package/dist/db.cjs +0 -1
  93. package/dist/db.cjs.map +1 -1
  94. package/dist/db.d.cts.map +1 -1
  95. package/dist/db.d.mts.map +1 -1
  96. package/dist/db.mjs.map +1 -1
  97. package/dist/dev-logs.cjs +2 -1
  98. package/dist/dev-logs.cjs.map +1 -1
  99. package/dist/dev-logs.mjs +1 -1
  100. package/dist/dev-logs.mjs.map +1 -1
  101. package/dist/dev-session.cjs +3 -1
  102. package/dist/dev-session.cjs.map +1 -1
  103. package/dist/dev-session.mjs +3 -2
  104. package/dist/dev-session.mjs.map +1 -1
  105. package/dist/fastkv.cjs +2 -7
  106. package/dist/fastkv.cjs.map +1 -1
  107. package/dist/fastkv.d.cts.map +1 -1
  108. package/dist/fastkv.d.mts.map +1 -1
  109. package/dist/fastkv.mjs +2 -7
  110. package/dist/fastkv.mjs.map +1 -1
  111. package/dist/http-client.cjs +4 -1
  112. package/dist/http-client.cjs.map +1 -1
  113. package/dist/http-client.mjs +1 -1
  114. package/dist/http-client.mjs.map +1 -1
  115. package/dist/index.cjs +0 -1
  116. package/dist/index.d.cts +1 -1
  117. package/dist/index.d.mts +1 -1
  118. package/dist/infra/planner.cjs +5 -1
  119. package/dist/infra/planner.cjs.map +1 -1
  120. package/dist/infra/planner.mjs +1 -1
  121. package/dist/infra/planner.mjs.map +1 -1
  122. package/dist/infra/preflight.cjs +1 -2
  123. package/dist/infra/preflight.cjs.map +1 -1
  124. package/dist/infra/preflight.mjs +1 -1
  125. package/dist/infra/preflight.mjs.map +1 -1
  126. package/dist/infra/types.cjs +0 -1
  127. package/dist/infra/types.cjs.map +1 -1
  128. package/dist/infra/types.mjs.map +1 -1
  129. package/dist/integrity.cjs +0 -1
  130. package/dist/integrity.cjs.map +1 -1
  131. package/dist/integrity.d.cts.map +1 -1
  132. package/dist/integrity.d.mts.map +1 -1
  133. package/dist/integrity.mjs.map +1 -1
  134. package/dist/internal/manifest-normalizer.cjs +2 -2
  135. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  136. package/dist/internal/manifest-normalizer.mjs +2 -2
  137. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  138. package/dist/merge.cjs +1 -2
  139. package/dist/merge.cjs.map +1 -1
  140. package/dist/merge.d.cts.map +1 -1
  141. package/dist/merge.d.mts.map +1 -1
  142. package/dist/merge.mjs +1 -1
  143. package/dist/merge.mjs.map +1 -1
  144. package/dist/mf.cjs +0 -1
  145. package/dist/mf.cjs.map +1 -1
  146. package/dist/mf.d.cts +0 -1
  147. package/dist/mf.d.cts.map +1 -1
  148. package/dist/mf.d.mts +0 -1
  149. package/dist/mf.d.mts.map +1 -1
  150. package/dist/mf.mjs.map +1 -1
  151. package/dist/near-cli.cjs +3 -1
  152. package/dist/near-cli.cjs.map +1 -1
  153. package/dist/near-cli.mjs +1 -1
  154. package/dist/near-cli.mjs.map +1 -1
  155. package/dist/network.cjs.map +1 -1
  156. package/dist/network.mjs.map +1 -1
  157. package/dist/orchestrator.cjs +5 -4
  158. package/dist/orchestrator.cjs.map +1 -1
  159. package/dist/orchestrator.mjs +5 -3
  160. package/dist/orchestrator.mjs.map +1 -1
  161. package/dist/plugin.cjs.map +1 -1
  162. package/dist/plugin.d.cts +43 -46
  163. package/dist/plugin.d.cts.map +1 -1
  164. package/dist/plugin.d.mts +43 -46
  165. package/dist/plugin.d.mts.map +1 -1
  166. package/dist/plugin.mjs.map +1 -1
  167. package/dist/process-registry.cjs +4 -1
  168. package/dist/process-registry.cjs.map +1 -1
  169. package/dist/process-registry.mjs +1 -1
  170. package/dist/process-registry.mjs.map +1 -1
  171. package/dist/publish.cjs +1 -0
  172. package/dist/publish.cjs.map +1 -1
  173. package/dist/publish.mjs +1 -1
  174. package/dist/publish.mjs.map +1 -1
  175. package/dist/sdk.cjs +0 -1
  176. package/dist/service-descriptor.cjs +0 -1
  177. package/dist/service-descriptor.cjs.map +1 -1
  178. package/dist/service-descriptor.d.cts +1 -0
  179. package/dist/service-descriptor.d.cts.map +1 -1
  180. package/dist/service-descriptor.d.mts +0 -1
  181. package/dist/service-descriptor.d.mts.map +1 -1
  182. package/dist/service-descriptor.mjs.map +1 -1
  183. package/dist/shared-deps.cjs +0 -1
  184. package/dist/shared-deps.cjs.map +1 -1
  185. package/dist/shared-deps.mjs.map +1 -1
  186. package/dist/types.cjs.map +1 -1
  187. package/dist/types.d.cts +0 -1
  188. package/dist/types.d.cts.map +1 -1
  189. package/dist/types.d.mts +0 -1
  190. package/dist/types.d.mts.map +1 -1
  191. package/dist/types.mjs.map +1 -1
  192. package/dist/ui/head.cjs.map +1 -1
  193. package/dist/ui/head.d.cts +0 -1
  194. package/dist/ui/head.d.cts.map +1 -1
  195. package/dist/ui/head.d.mts +0 -1
  196. package/dist/ui/head.d.mts.map +1 -1
  197. package/dist/ui/head.mjs.map +1 -1
  198. package/dist/ui/index.d.cts +1 -1
  199. package/dist/ui/index.d.mts +1 -1
  200. package/dist/ui/metadata.cjs +1 -1
  201. package/dist/ui/metadata.cjs.map +1 -1
  202. package/dist/ui/metadata.d.cts.map +1 -1
  203. package/dist/ui/metadata.d.mts.map +1 -1
  204. package/dist/ui/metadata.mjs +1 -1
  205. package/dist/ui/metadata.mjs.map +1 -1
  206. package/dist/ui/router.cjs.map +1 -1
  207. package/dist/ui/router.d.cts +0 -1
  208. package/dist/ui/router.d.cts.map +1 -1
  209. package/dist/ui/router.d.mts +0 -1
  210. package/dist/ui/router.d.mts.map +1 -1
  211. package/dist/ui/router.mjs.map +1 -1
  212. package/dist/ui/runtime.cjs.map +1 -1
  213. package/dist/ui/runtime.d.cts +0 -1
  214. package/dist/ui/runtime.d.cts.map +1 -1
  215. package/dist/ui/runtime.d.mts +0 -1
  216. package/dist/ui/runtime.d.mts.map +1 -1
  217. package/dist/ui/runtime.mjs.map +1 -1
  218. package/dist/ui/types.d.cts +0 -1
  219. package/dist/ui/types.d.cts.map +1 -1
  220. package/dist/ui/types.d.mts +0 -1
  221. package/dist/ui/types.d.mts.map +1 -1
  222. package/dist/utils/banner.cjs +0 -1
  223. package/dist/utils/banner.cjs.map +1 -1
  224. package/dist/utils/banner.mjs.map +1 -1
  225. package/dist/utils/linkify.cjs.map +1 -1
  226. package/dist/utils/linkify.mjs.map +1 -1
  227. package/dist/utils/run.cjs +0 -1
  228. package/dist/utils/run.cjs.map +1 -1
  229. package/dist/utils/run.mjs.map +1 -1
  230. package/dist/utils/save-config.cjs +0 -1
  231. package/dist/utils/save-config.cjs.map +1 -1
  232. package/dist/utils/save-config.mjs.map +1 -1
  233. package/dist/utils/string.cjs.map +1 -1
  234. package/dist/utils/string.mjs.map +1 -1
  235. package/dist/utils/theme.cjs.map +1 -1
  236. package/dist/utils/theme.mjs.map +1 -1
  237. package/package.json +4 -3
  238. package/dist/_virtual/_rolldown/runtime.mjs +0 -32
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.mts","names":[],"sources":["../src/merge.ts"],"mappings":";;cAGa,gBAAA;AAAA,KAgBD,MAAA;AAAA,iBAiEI,iBAAA,CACd,YAAA,WAAuB,aAAA,cACvB,GAAA,EAAK,MAAA;AAAA,iBAOS,yBAAA,CACd,MAAA,EAAQ,cAAA,EACR,KAAA,EAAO,cAAA,GACN,cAAA;AAAA,iBAqEa,oBAAA,WAA+B,MAAA,kBAAA,CAAyB,MAAA,EAAQ,CAAA,GAAI,CAAA"}
1
+ {"version":3,"file":"merge.d.mts","names":[],"sources":["../src/merge.ts"],"mappings":";;cAGa;KAgBD;iBAiEI,kBACd,uBAAuB,2BACvB,KAAK;iBAOS,0BACd,QAAQ,gBACR,OAAO,iBACN;iBAqEa,qBAAqB,UAAU,yBAAyB,QAAQ,IAAI"}
package/dist/merge.mjs CHANGED
@@ -14,7 +14,7 @@ const BOS_CONFIG_ORDER = [
14
14
  "app",
15
15
  "plugins"
16
16
  ];
17
- const ARRAY_UNION_KEYS = new Set(["secrets"]);
17
+ const ARRAY_UNION_KEYS = /* @__PURE__ */ new Set(["secrets"]);
18
18
  function isPlainObject(value) {
19
19
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"merge.mjs","names":[],"sources":["../src/merge.ts"],"sourcesContent":["import { createDefu } from \"defu\";\nimport type { BosConfigInput, ExtendsConfig } from \"./types\";\n\nexport const BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"title\",\n \"description\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"ci\",\n \"app\",\n \"plugins\",\n] as const;\n\nexport type BosConfigFieldName = (typeof BOS_CONFIG_ORDER)[number];\n\nexport type BosEnv = \"development\" | \"production\" | \"staging\";\n\nexport interface ResolvedConfigMeta {\n env: BosEnv;\n resolvedAt: string;\n extendsChain: string[];\n source?: string;\n}\n\nconst ARRAY_UNION_KEYS = new Set([\"secrets\"]);\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction unionArrays(a: unknown, b: unknown): unknown[] | undefined {\n const aArr = Array.isArray(a) ? a : [];\n const bArr = Array.isArray(b) ? b : [];\n if (aArr.length === 0 && bArr.length === 0) return undefined;\n const seen = new Set<string>();\n const result: unknown[] = [];\n for (const item of [...aArr, ...bArr]) {\n if (typeof item === \"string\") {\n if (seen.has(item)) continue;\n seen.add(item);\n }\n result.push(item);\n }\n return result;\n}\n\nfunction cleanNullSentinels(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) continue;\n if (isPlainObject(value)) {\n const cleaned = cleanNullSentinels(value);\n if (Object.keys(cleaned).length > 0) {\n out[key] = cleaned;\n }\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst bosConfigMerger = createDefu((obj: any, key: any, value: any): boolean | undefined => {\n if (obj[key] === null) return true;\n if (value === null) {\n obj[key] = null;\n return true;\n }\n if (Array.isArray(obj[key]) && Array.isArray(value)) {\n if (ARRAY_UNION_KEYS.has(key)) {\n obj[key] = unionArrays(obj[key], value);\n } else {\n obj[key] = value;\n }\n return true;\n }\n return false;\n});\n\nexport function resolveExtendsRef(\n extendsField: string | ExtendsConfig | undefined,\n env: BosEnv,\n): string | undefined {\n if (!extendsField) return undefined;\n if (typeof extendsField === \"string\") return extendsField;\n return extendsField[env] ?? extendsField.production ?? Object.values(extendsField).find(Boolean);\n}\n\nexport function mergeBosConfigWithExtends(\n parent: BosConfigInput,\n child: BosConfigInput,\n): BosConfigInput {\n const merged = bosConfigMerger(child, parent) as BosConfigInput;\n\n if (child.plugins !== undefined && isPlainObject(child.plugins)) {\n (merged as Record<string, unknown>).plugins = cleanNullSentinels(\n child.plugins as Record<string, unknown>,\n );\n }\n\n const mergedRecord = merged as Record<string, unknown>;\n\n if (isPlainObject(mergedRecord.app)) {\n for (const entryVal of Object.values(mergedRecord.app as Record<string, unknown>)) {\n if (!isPlainObject(entryVal)) continue;\n for (const secretKey of ARRAY_UNION_KEYS) {\n if (Array.isArray(entryVal[secretKey])) {\n entryVal[secretKey] =\n (unionArrays(entryVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(\n Boolean,\n ) ?? entryVal[secretKey];\n }\n }\n }\n }\n\n if (isPlainObject(mergedRecord.plugins)) {\n for (const pluginVal of Object.values(mergedRecord.plugins as Record<string, unknown>)) {\n if (!isPlainObject(pluginVal)) continue;\n for (const secretKey of ARRAY_UNION_KEYS) {\n if (Array.isArray(pluginVal[secretKey])) {\n pluginVal[secretKey] =\n (unionArrays(pluginVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(\n Boolean,\n ) ?? pluginVal[secretKey];\n }\n }\n }\n }\n\n return rebuildOrderedConfig(mergedRecord) as BosConfigInput;\n}\n\nexport function mergeBosConfigWithTemplate(\n local: BosConfigInput,\n template: BosConfigInput,\n): BosConfigInput {\n const merged = mergeJsonValuesPreservingLocalOrder(local, template) as BosConfigInput;\n return rebuildOrderedConfig(merged as Record<string, unknown>) as BosConfigInput;\n}\n\nfunction mergeJsonValuesPreservingLocalOrder(local: unknown, template: unknown): unknown {\n if (isPlainObject(local) && isPlainObject(template)) {\n const merged: Record<string, unknown> = {};\n for (const key of Object.keys(local)) {\n merged[key] = mergeJsonValuesPreservingLocalOrder(\n local[key],\n (template as Record<string, unknown>)[key],\n );\n }\n for (const key of Object.keys(template as Record<string, unknown>)) {\n if (!(key in merged)) {\n merged[key] = (template as Record<string, unknown>)[key];\n }\n }\n return merged;\n }\n return local ?? template;\n}\n\nexport function rebuildOrderedConfig<T extends Record<string, unknown>>(config: T): T {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key as BosConfigFieldName)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered as T;\n}\n\nexport { bosConfigMerger };\n"],"mappings":"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"}
1
+ {"version":3,"file":"merge.mjs","names":[],"sources":["../src/merge.ts"],"sourcesContent":["import { createDefu } from \"defu\";\nimport type { BosConfigInput, ExtendsConfig } from \"./types\";\n\nexport const BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"title\",\n \"description\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"ci\",\n \"app\",\n \"plugins\",\n] as const;\n\nexport type BosConfigFieldName = (typeof BOS_CONFIG_ORDER)[number];\n\nexport type BosEnv = \"development\" | \"production\" | \"staging\";\n\nexport interface ResolvedConfigMeta {\n env: BosEnv;\n resolvedAt: string;\n extendsChain: string[];\n source?: string;\n}\n\nconst ARRAY_UNION_KEYS = new Set([\"secrets\"]);\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction unionArrays(a: unknown, b: unknown): unknown[] | undefined {\n const aArr = Array.isArray(a) ? a : [];\n const bArr = Array.isArray(b) ? b : [];\n if (aArr.length === 0 && bArr.length === 0) return undefined;\n const seen = new Set<string>();\n const result: unknown[] = [];\n for (const item of [...aArr, ...bArr]) {\n if (typeof item === \"string\") {\n if (seen.has(item)) continue;\n seen.add(item);\n }\n result.push(item);\n }\n return result;\n}\n\nfunction cleanNullSentinels(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value === null || value === undefined) continue;\n if (isPlainObject(value)) {\n const cleaned = cleanNullSentinels(value);\n if (Object.keys(cleaned).length > 0) {\n out[key] = cleaned;\n }\n } else {\n out[key] = value;\n }\n }\n return out;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst bosConfigMerger = createDefu((obj: any, key: any, value: any): boolean | undefined => {\n if (obj[key] === null) return true;\n if (value === null) {\n obj[key] = null;\n return true;\n }\n if (Array.isArray(obj[key]) && Array.isArray(value)) {\n if (ARRAY_UNION_KEYS.has(key)) {\n obj[key] = unionArrays(obj[key], value);\n } else {\n obj[key] = value;\n }\n return true;\n }\n return false;\n});\n\nexport function resolveExtendsRef(\n extendsField: string | ExtendsConfig | undefined,\n env: BosEnv,\n): string | undefined {\n if (!extendsField) return undefined;\n if (typeof extendsField === \"string\") return extendsField;\n return extendsField[env] ?? extendsField.production ?? Object.values(extendsField).find(Boolean);\n}\n\nexport function mergeBosConfigWithExtends(\n parent: BosConfigInput,\n child: BosConfigInput,\n): BosConfigInput {\n const merged = bosConfigMerger(child, parent) as BosConfigInput;\n\n if (child.plugins !== undefined && isPlainObject(child.plugins)) {\n (merged as Record<string, unknown>).plugins = cleanNullSentinels(\n child.plugins as Record<string, unknown>,\n );\n }\n\n const mergedRecord = merged as Record<string, unknown>;\n\n if (isPlainObject(mergedRecord.app)) {\n for (const entryVal of Object.values(mergedRecord.app as Record<string, unknown>)) {\n if (!isPlainObject(entryVal)) continue;\n for (const secretKey of ARRAY_UNION_KEYS) {\n if (Array.isArray(entryVal[secretKey])) {\n entryVal[secretKey] =\n (unionArrays(entryVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(\n Boolean,\n ) ?? entryVal[secretKey];\n }\n }\n }\n }\n\n if (isPlainObject(mergedRecord.plugins)) {\n for (const pluginVal of Object.values(mergedRecord.plugins as Record<string, unknown>)) {\n if (!isPlainObject(pluginVal)) continue;\n for (const secretKey of ARRAY_UNION_KEYS) {\n if (Array.isArray(pluginVal[secretKey])) {\n pluginVal[secretKey] =\n (unionArrays(pluginVal[secretKey] as unknown[], []) as string[] | undefined)?.filter(\n Boolean,\n ) ?? pluginVal[secretKey];\n }\n }\n }\n }\n\n return rebuildOrderedConfig(mergedRecord) as BosConfigInput;\n}\n\nexport function mergeBosConfigWithTemplate(\n local: BosConfigInput,\n template: BosConfigInput,\n): BosConfigInput {\n const merged = mergeJsonValuesPreservingLocalOrder(local, template) as BosConfigInput;\n return rebuildOrderedConfig(merged as Record<string, unknown>) as BosConfigInput;\n}\n\nfunction mergeJsonValuesPreservingLocalOrder(local: unknown, template: unknown): unknown {\n if (isPlainObject(local) && isPlainObject(template)) {\n const merged: Record<string, unknown> = {};\n for (const key of Object.keys(local)) {\n merged[key] = mergeJsonValuesPreservingLocalOrder(\n local[key],\n (template as Record<string, unknown>)[key],\n );\n }\n for (const key of Object.keys(template as Record<string, unknown>)) {\n if (!(key in merged)) {\n merged[key] = (template as Record<string, unknown>)[key];\n }\n }\n return merged;\n }\n return local ?? template;\n}\n\nexport function rebuildOrderedConfig<T extends Record<string, unknown>>(config: T): T {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key as BosConfigFieldName)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered as T;\n}\n\nexport { bosConfigMerger };\n"],"mappings":"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"}
package/dist/mf.cjs CHANGED
@@ -1,5 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
3
2
  const require_integrity = require('./integrity.cjs');
4
3
  let _module_federation_enhanced_runtime = require("@module-federation/enhanced/runtime");
5
4
  let _module_federation_runtime_core = require("@module-federation/runtime-core");
package/dist/mf.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mf.cjs","names":["computeSriHash"],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mf.cjs","names":["computeSriHash"],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
package/dist/mf.d.cts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { IntegrityRegistry } from "./integrity.cjs";
2
2
  import { createInstance } from "@module-federation/enhanced/runtime";
3
-
4
3
  //#region src/mf.d.ts
5
4
  type FederationInstance = ReturnType<typeof createInstance>;
6
5
  declare function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void;
package/dist/mf.d.cts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mf.d.cts","names":[],"sources":["../src/mf.ts"],"mappings":";;;;KAIK,kBAAA,GAAqB,UAAA,QAAkB,cAAA;AAAA,iBAU5B,kCAAA,CAAmC,EAAA,EAAI,kBAAA;AAAA,iBAyBvC,yBAAA,CACd,EAAA,EAAI,kBAAA,EACJ,QAAA,EAAU,iBAAA;AAAA,iBAuCI,qBAAA,CAAA,GAAyB,kBAAA;AAAA,iBAoBnB,cAAA,CAAe,IAAA;EACnC,IAAA;EACA,KAAA;EACA,IAAA;AAAA,IACE,OAAA;AAAA,iBAqBkB,gBAAA,GAAA,CACpB,SAAA,UACA,OAAA;EAAY,WAAA;EAAuB,IAAA;AAAA,IAClC,OAAA,CAAQ,CAAA;AAAA,iBAeW,uBAAA,CAAA,GAA2B,OAAA"}
1
+ {"version":3,"file":"mf.d.cts","names":[],"sources":["../src/mf.ts"],"mappings":";;;KAIK,qBAAqB,kBAAkB;iBAU5B,mCAAmC,IAAI;iBAyBvC,0BACd,IAAI,oBACJ,UAAU;iBAuCI,yBAAyB;iBAoBnB,eAAe;EACnC;EACA;EACA;IACE;iBAqBkB,iBAAiB,GACrC,mBACA;EAAY;EAAuB;IAClC,QAAQ;iBAeW,2BAA2B"}
package/dist/mf.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { IntegrityRegistry } from "./integrity.mjs";
2
2
  import { createInstance } from "@module-federation/enhanced/runtime";
3
-
4
3
  //#region src/mf.d.ts
5
4
  type FederationInstance = ReturnType<typeof createInstance>;
6
5
  declare function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void;
package/dist/mf.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mf.d.mts","names":[],"sources":["../src/mf.ts"],"mappings":";;;;KAIK,kBAAA,GAAqB,UAAA,QAAkB,cAAA;AAAA,iBAU5B,kCAAA,CAAmC,EAAA,EAAI,kBAAA;AAAA,iBAyBvC,yBAAA,CACd,EAAA,EAAI,kBAAA,EACJ,QAAA,EAAU,iBAAA;AAAA,iBAuCI,qBAAA,CAAA,GAAyB,kBAAA;AAAA,iBAoBnB,cAAA,CAAe,IAAA;EACnC,IAAA;EACA,KAAA;EACA,IAAA;AAAA,IACE,OAAA;AAAA,iBAqBkB,gBAAA,GAAA,CACpB,SAAA,UACA,OAAA;EAAY,WAAA;EAAuB,IAAA;AAAA,IAClC,OAAA,CAAQ,CAAA;AAAA,iBAeW,uBAAA,CAAA,GAA2B,OAAA"}
1
+ {"version":3,"file":"mf.d.mts","names":[],"sources":["../src/mf.ts"],"mappings":";;;KAIK,qBAAqB,kBAAkB;iBAU5B,mCAAmC,IAAI;iBAyBvC,0BACd,IAAI,oBACJ,UAAU;iBAuCI,yBAAyB;iBAoBnB,eAAe;EACnC;EACA;EACA;IACE;iBAqBkB,iBAAiB,GACrC,mBACA;EAAY;EAAuB;IAClC,QAAQ;iBAeW,2BAA2B"}
package/dist/mf.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mf.mjs","names":[],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mf.mjs","names":[],"sources":["../src/mf.ts"],"sourcesContent":["import { createInstance, getInstance } from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { computeSriHash, type IntegrityRegistry } from \"./integrity\";\n\ntype FederationInstance = ReturnType<typeof createInstance>;\n\nlet mfInstance: FederationInstance | null = null;\n\nfunction fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer));\n}\n\nexport function patchManifestFetchForSsrPublicPath(mf: FederationInstance): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) return;\n if ((mf as any).__everythingDevPatchedManifestFetch === true) return;\n (mf as any).__everythingDevPatchedManifestFetch = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\" || !url.endsWith(\"/mf-manifest.json\")) {\n return;\n }\n return fetchWithTimeout(url as string, init as RequestInit, 15_000)\n .then((res) => res.json())\n .then((json: any) => {\n json.metaData = json.metaData ?? {};\n json.metaData.ssrPublicPath =\n json.metaData.ssrPublicPath ?? url.replace(/\\/mf-manifest\\.json$/, \"/\");\n if (json.metaData.publicPath === \"auto\" || json.metaData.publicPath === \"\") {\n json.metaData.publicPath = \"/\";\n }\n return new Response(JSON.stringify(json), {\n headers: { \"content-type\": \"application/json\" },\n });\n });\n });\n}\n\nexport function installIntegrityFetchHook(\n mf: FederationInstance,\n registry: IntegrityRegistry,\n): void {\n if (!mf || !(mf as any).loaderHook?.lifecycle?.fetch?.on) {\n console.warn(\"[SRI] MF lifecycle fetch hook not available, skipping integrity-in-pipeline\");\n return;\n }\n if ((mf as any).__everythingDevIntegrityHook === true) return;\n (mf as any).__everythingDevIntegrityHook = true;\n\n (mf as any).loaderHook.lifecycle.fetch.on((url: unknown, init: unknown) => {\n if (typeof url !== \"string\") return;\n\n const expectedHash = registry.get(url);\n if (!expectedHash) return;\n\n return fetchWithTimeout(url as string, init as RequestInit, 15_000).then(async (res) => {\n const buffer = Buffer.from(await res.arrayBuffer());\n const computed = computeSriHash(buffer);\n\n if (computed !== expectedHash) {\n console.error(\n `[SRI] Integrity check failed in MF fetch pipeline for ${url}\\n Expected: ${expectedHash}\\n Computed: ${computed}`,\n );\n return new Response(`Integrity check failed for ${url}`, {\n status: 500,\n statusText: \"Integrity Check Failed\",\n });\n }\n\n console.log(`[SRI] Integrity verified in pipeline for ${url}`);\n return new Response(buffer, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n });\n });\n}\n\nexport function getFederationInstance(): FederationInstance {\n if (mfInstance) return mfInstance;\n\n const existing = getInstance();\n if (existing) {\n mfInstance = existing as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n }\n\n mfInstance = createInstance({\n name: \"host\",\n remotes: [],\n }) as FederationInstance;\n setGlobalFederationInstance(mfInstance as any);\n patchManifestFetchForSsrPublicPath(mfInstance);\n return mfInstance;\n}\n\nexport async function registerRemote(opts: {\n name: string;\n entry: string;\n type?: \"manifest\" | \"script\";\n}): Promise<void> {\n const instance = getFederationInstance();\n\n const inferType = (): \"manifest\" | \"script\" => {\n if (opts.type) return opts.type;\n if (opts.entry.endsWith(\"/mf-manifest.json\")) return \"manifest\";\n if (opts.entry.endsWith(\"/remoteEntry.js\")) return \"script\";\n return typeof window === \"undefined\" ? \"script\" : \"manifest\";\n };\n\n const remoteType = inferType();\n\n instance.registerRemotes([\n {\n name: opts.name,\n entry: opts.entry,\n type: remoteType,\n },\n ]);\n}\n\nexport async function loadRemoteModule<T>(\n specifier: string,\n options?: { loadFactory?: boolean; from?: \"build\" | \"runtime\" },\n): Promise<T> {\n const instance = getFederationInstance();\n\n const isServer = typeof window === \"undefined\";\n if (isServer) {\n await (instance as any).initializeSharing?.(\"default\");\n }\n\n const mod = await instance.loadRemote<T>(specifier, options as any);\n if (!mod) {\n throw new Error(`Failed to load remote module: ${specifier}`);\n }\n return mod;\n}\n\nexport async function ensureNodeRuntimePlugin(): Promise<void> {\n const instance = getFederationInstance();\n if (typeof window !== \"undefined\") return;\n if ((instance as any).__nodeRuntimePluginLoaded) return;\n\n const mod: any = await import(\"@module-federation/node/runtimePlugin\");\n const factory = mod?.default ?? mod;\n const plugin = typeof factory === \"function\" ? factory() : null;\n if (plugin) {\n instance.registerPlugins([plugin]);\n }\n (instance as any).__nodeRuntimePluginLoaded = true;\n}\n"],"mappings":"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"}
package/dist/near-cli.cjs CHANGED
@@ -1,4 +1,3 @@
1
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
1
  const require_theme = require('./utils/theme.cjs');
3
2
  let effect = require("effect");
4
3
  let node_crypto = require("node:crypto");
@@ -221,10 +220,13 @@ async function addFunctionCallAccessKey(config) {
221
220
  }
222
221
 
223
222
  //#endregion
223
+ exports.NearCliNotFoundError = NearCliNotFoundError;
224
+ exports.NearTransactionError = NearTransactionError;
224
225
  exports.addFunctionCallAccessKey = addFunctionCallAccessKey;
225
226
  exports.deleteAccessKeys = deleteAccessKeys;
226
227
  exports.ensureNearCli = ensureNearCli;
227
228
  exports.executeTransaction = executeTransaction;
229
+ exports.generateNearKeyPair = generateNearKeyPair;
228
230
  exports.listPublishKeys = listPublishKeys;
229
231
  exports.resolveNearSigningMode = resolveNearSigningMode;
230
232
  //# sourceMappingURL=near-cli.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"near-cli.cjs","names":["Effect","colors"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"near-cli.cjs","names":["Effect","colors"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
package/dist/near-cli.mjs CHANGED
@@ -220,5 +220,5 @@ async function addFunctionCallAccessKey(config) {
220
220
  }
221
221
 
222
222
  //#endregion
223
- export { addFunctionCallAccessKey, deleteAccessKeys, ensureNearCli, executeTransaction, listPublishKeys, resolveNearSigningMode };
223
+ export { NearCliNotFoundError, NearTransactionError, addFunctionCallAccessKey, deleteAccessKeys, ensureNearCli, executeTransaction, generateNearKeyPair, listPublishKeys, resolveNearSigningMode };
224
224
  //# sourceMappingURL=near-cli.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"near-cli.mjs","names":[],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":";;;;;;AAqCA,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AAExB,IAAa,uBAAb,cAA0C,MAAM;CAC9C,AAAS,OAAO;CAChB,cAAc;AACZ,QAAM,qBAAqB;;;AAI/B,IAAa,uBAAb,cAA0C,MAAM;CAC9C,AAAS,OAAO;;AAOlB,SAAS,iBAAiB,OAA2B;CACnD,MAAM,aAAa,MAAM,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;AAC9D,QAAO,IAAI,WAAW,OAAO,KAAK,YAAY,SAAS,CAAC;;AAG1D,SAAS,aAAa,OAA2B;AAC/C,KAAI,MAAM,WAAW,EAAG,QAAO;CAE/B,MAAM,SAAmB,CAAC,EAAE;AAC5B,MAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,QAAQ;AACZ,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAS,OAAO,MAAO;AACvB,UAAO,KAAK,QAAQ;AACpB,WAAQ,KAAK,MAAM,QAAQ,GAAG;;AAEhC,SAAO,QAAQ,GAAG;AAChB,UAAO,KAAK,QAAQ,GAAG;AACvB,WAAQ,KAAK,MAAM,QAAQ,GAAG;;;CAIlC,IAAI,SAAS;AACb,MAAK,MAAM,QAAQ,MACjB,KAAI,SAAS,EAAG,WAAU,gBAAgB;KACrC;AAGP,MAAK,IAAI,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,IACtC,WAAU,gBAAgB,OAAO;AAGnC,QAAO;;AAGT,SAAgB,sBAAmC;CACjD,MAAM,EAAE,WAAW,eAAe,oBAAoB,UAAU;CAChE,MAAM,YAAY,UAAU,OAAO,EAAE,QAAQ,OAAO,CAAC;CACrD,MAAM,aAAa,WAAW,OAAO,EAAE,QAAQ,OAAO,CAAC;AAEvD,KAAI,CAAC,UAAU,KAAK,CAAC,WAAW,EAC9B,OAAM,IAAI,MAAM,kCAAkC;CAGpD,MAAM,cAAc,iBAAiB,UAAU,EAAE;CACjD,MAAM,cAAc,iBAAiB,WAAW,EAAE;CAClD,MAAM,cAAc,IAAI,WAAW,YAAY,SAAS,YAAY,OAAO;AAC3E,aAAY,IAAI,aAAa,EAAE;AAC/B,aAAY,IAAI,aAAa,YAAY,OAAO;AAEhD,QAAO;EACL,WAAW,WAAW,aAAa,YAAY;EAC/C,YAAY,WAAW,aAAa,YAAY;EACjD;;AAGH,MAAM,wBAAwB,OAAO,WAAW;CAC9C,KAAK,YAAY;AACf,MAAI;AACF,SAAM,MAAM,QAAQ,CAAC,YAAY,EAAE,EAAE,OAAO,QAAQ,CAAC;AACrD,UAAO;UACD;AACN,UAAO;;;CAGX,6BAAa,IAAI,MAAM,2BAA2B;CACnD,CAAC;AAEF,eAAe,eAAe,MAA+B;AAC3D,KAAI,CAAC,QAAQ,MAAM,MACjB,OAAM,IAAI,qBACR,oGACD;AAGH,OAAM,MAAM,QAAQ,MAAM;EAAE,OAAO;EAAW,QAAQ;EAAW,QAAQ;EAAW,CAAC;;AAGvF,SAAgB,uBAAuB,YAAsC;AAC3E,KAAI,WACF,QAAO;EAAE,MAAM;EAAc;EAAY;AAG3C,KAAI,CAAC,QAAQ,MAAM,MACjB,OAAM,IAAI,qBACR,gIACD;AAGH,SAAQ,IACN,OAAO,OACL,qFACD,CACF;AACD,QAAO,EAAE,MAAM,uBAAuB;;AAGxC,MAAa,gBAAgB,OAAO,IAAI,aAAa;AAEnD,KAAI,OADuB,sBACV;AAEjB,SAAQ,KAAK;AACb,SAAQ,IAAI,uBAAuB;AAEnC,SAAQ,KAAK;AACb,SAAQ,IAAI,gEAAgE,cAAc,OAAO;AACjG,SAAQ,KAAK;AACb,QAAO,OAAO,KAAK,IAAI,sBAAsB,CAAC;EAC9C;AAEF,SAAS,kBAAkB,QAAiB,QAAyB;AACnE,QAAO,CAAC,QAAQ,OAAO,CAAC,QAAQ,UAAU,SAAS,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,KAAK;;AAGxF,SAAS,uBAAuB,QAAoC;AAElE,QADc,OAAO,MAAM,oCACf,GAAG;;AAGjB,MAAa,sBACX,QACA,gBAEA,OAAO,IAAI,aAAa;CACtB,MAAM,sBAAsB,eAAe,uBAAuB,OAAO,WAAW;CACpF,MAAM,OAAO,OAAO,OAAO,WAAW,QAAQ,QAAQ,GAAG;CACzD,MAAM,WAAW,OAAO,WAAW,SAAS,QAAQ,QAAQ,GAAG;CAC/D,MAAM,UAAU,OAAO,YAAY,OAAO,QAAQ,SAAS,WAAW,GAAG,YAAY;CAErF,MAAM,OAAO;EACX;EACA;EACA;EACA,OAAO;EACP,OAAO;EACP;EACA,OAAO;EACP;EACA;EACA;EACA;EACA;EACA,OAAO;EACP;EACA;EACD;AAED,KAAI,oBAAoB,SAAS,aAC/B,MAAK,KAAK,mCAAmC,oBAAoB,YAAY,OAAO;KAEpF,MAAK,KAAK,sBAAsB,OAAO;CAGzC,MAAM,SAAS,OAAO,OAAO,WAAW;EACtC,KAAK,YAAY;GACf,MAAM,mBAAmB,oBAAoB,SAAS;GACtD,MAAM,UAAU,OAAO,WAAW;GAElC,MAAM,OAAO,MAAM,QAAQ,MAAM;IAC/B,OAAO,mBAAmB,WAAW;IACrC,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS,MAAS;IACnB,CAAC;AAEF,QAAK,QAAQ,GAAG,SAAS,UAAkB;AACzC,QAAI,QACF,SAAQ,OAAO,MAAM,MAAM;KAE7B;AAEF,QAAK,QAAQ,GAAG,SAAS,UAAkB;AACzC,QAAI,QACF,SAAQ,OAAO,MAAM,MAAM;KAE7B;GAEF,MAAM,SAAS,MAAM;GAGrB,MAAM,WAAW,kBAFC,OAAO,UAAU,IACjB,OAAO,UAAU,GACqB;GACxD,MAAM,SAAS,uBAAuB,SAAS;GAC/C,MAAM,sBAAsB,oBAAoB,KAAK,SAAS;AAE9D,OAAI,OAAO,aAAa,KAAK,qBAAqB;AAChD,QAAI,oBACF,SAAQ,IACN,KAAK,OAAO,MAAM,IAAI,CAAC,wBAAwB,SAAS,IAAI,OAAO,IAAI,OAAO,KAAK,KACpF;AAEH,WAAO;KACL,SAAS;KACT;KACA,QAAQ,YAAY;KACrB;;AAGH,SAAM,IAAI,qBACR,YAAY,gCAAgC,OAAO,WACpD;;EAEH,QAAQ,UAAU;EACnB,CAAC;AAEF,QAAO;EACL,SAAS;EACT,QAAQ,OAAO;EACf,QAAQ,OAAO;EAChB;EACD;AAEJ,eAAsB,gBAAgB,QAIhB;CACpB,MAAM,aAAa,MAAM,MACvB,QACA;EAAC;EAAW;EAAa,OAAO;EAAS;EAAkB,OAAO;EAAS;EAAM,EACjF;EAAE,QAAQ;EAAQ,QAAQ;EAAQ,QAAQ;EAAO,CAClD;AAED,KAAI,WAAW,aAAa,EAC1B,OAAM,IAAI,qBACR,gCAAgC,WAAW,UAAU,WAAW,UAAU,kBAC3E;CAGH,MAAM,SAAS,WAAW,UAAU;CACpC,MAAM,UAAoB,EAAE;AAE5B,MAAK,MAAM,QAAQ,OAAO,MAAM,KAAK,CACnC,KAAI,KAAK,SAAS,OAAO,SAAS,IAAI,KAAK,SAAS,gBAAgB,EAAE;EACpE,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,MACF,SAAQ,KAAK,MAAM,GAAG;;AAK5B,QAAO;;AAGT,eAAsB,iBACpB,SACA,YACA,SACe;AAYf,OAAM,eAAe;EAVnB;EACA;EACA;EACA;EACA,WAAW,KAAK,IAAI;EACpB;EACA;EACA;EACA;EAEuB,CAAC;;AAG5B,eAAsB,yBACpB,QACsB;CACtB,MAAM,UAAU,qBAAqB;AAoBrC,OAAM,eAAe;EAlBnB;EACA;EACA,OAAO;EACP;EACA;EACA,OAAO;EACP;EACA,OAAO;EACP;EACA,OAAO,cAAc,KAAK,KAAK;EAC/B;EACA,QAAQ;EACR;EACA,OAAO,YAAY,OAAO,QAAQ,SAAS,WAAW,GAAG,YAAY;EACrE;EACA;EAGuB,CAAC;AAC1B,QAAO"}
1
+ {"version":3,"file":"near-cli.mjs","names":[],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n verbose?: boolean;\n}\n\nexport interface NearTransactionResult {\n success: true;\n txHash?: string;\n output?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n | { _tag: \"privateKey\"; privateKey: string }\n | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n try {\n await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n if (privateKey) {\n return { _tag: \"privateKey\", privateKey };\n }\n\n if (!process.stdin.isTTY) {\n throw new NearTransactionError(\n \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n );\n }\n\n console.log(\n colors.yellow(\n \" Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n ),\n );\n return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (resolvedSigningMode._tag === \"privateKey\") {\n args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n const verbose = config.verbose ?? false;\n\n const proc = execa(\"near\", args, {\n stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n timeout: 5 * 60 * 1000,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stdout.write(chunk);\n }\n });\n\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n if (verbose) {\n process.stderr.write(chunk);\n }\n });\n\n const result = await proc;\n const stdoutStr = result.stdout ?? \"\";\n const stderrStr = result.stderr ?? \"\";\n const combined = combineNearOutput(stdoutStr, stderrStr);\n const txHash = extractTransactionHash(combined);\n const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n\n if (result.exitCode === 0 || hasCodeDoesNotExist) {\n if (hasCodeDoesNotExist) {\n console.log(\n ` ${colors.green(\"✓\")} Transaction confirmed${txHash ? ` ${colors.dim(txHash)}` : \"\"}`,\n );\n }\n return {\n success: true,\n txHash,\n output: combined || undefined,\n };\n }\n\n throw new NearTransactionError(\n combined || `Transaction failed with code ${result.exitCode}`,\n );\n },\n catch: (error) => error as Error,\n });\n\n return {\n success: true,\n txHash: output.txHash,\n output: output.output,\n };\n });\n\nexport async function listPublishKeys(config: {\n account: string;\n contract: string;\n network: \"mainnet\" | \"testnet\";\n}): Promise<string[]> {\n const listResult = await execa(\n \"near\",\n [\"account\", \"list-keys\", config.account, \"network-config\", config.network, \"now\"],\n { stdout: \"pipe\", stderr: \"pipe\", reject: false },\n );\n\n if (listResult.exitCode !== 0) {\n throw new NearTransactionError(\n `Failed to list account keys: ${listResult.stderr || listResult.stdout || \"unknown error\"}`,\n );\n }\n\n const output = listResult.stdout ?? \"\";\n const oldKeys: string[] = [];\n\n for (const line of output.split(\"\\n\")) {\n if (line.includes(config.contract) && line.includes(\"__fastdata_kv\")) {\n const match = line.match(/ed25519:[A-Za-z0-9]+/);\n if (match) {\n oldKeys.push(match[0]);\n }\n }\n }\n\n return oldKeys;\n}\n\nexport async function deleteAccessKeys(\n account: string,\n publicKeys: string[],\n network: \"mainnet\" | \"testnet\",\n): Promise<void> {\n const args = [\n \"account\",\n \"delete-keys\",\n account,\n \"public-keys\",\n publicKeys.join(\",\"),\n \"network-config\",\n network,\n \"sign-with-keychain\",\n \"send\",\n ];\n await runNearCommand(args);\n}\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"network.cjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,SAAwC;AAC7E,QAAO,QAAQ,SAAS,WAAW,GAAG,YAAY"}
1
+ {"version":3,"file":"network.cjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,SAAwC;CAC7E,OAAO,QAAQ,SAAS,UAAU,IAAI,YAAY;AACpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"network.mjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,SAAwC;AAC7E,QAAO,QAAQ,SAAS,WAAW,GAAG,YAAY"}
1
+ {"version":3,"file":"network.mjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,SAAwC;CAC7E,OAAO,QAAQ,SAAS,UAAU,IAAI,YAAY;AACpD"}
@@ -1,4 +1,3 @@
1
- const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
1
  const require_mf = require('./mf.cjs');
3
2
  const require_service_descriptor = require('./service-descriptor.cjs');
4
3
  let effect = require("effect");
@@ -209,7 +208,8 @@ const spawnDevProcess = (descriptor, callbacks) => effect.Effect.gen(function* (
209
208
  yield* effect.Effect.forkScoped(effect.Effect.gen(function* () {
210
209
  const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;
211
210
  if (port > 0) {
212
- const url = `http://127.0.0.1:${port}${descriptor.readinessPath}`;
211
+ const readinessPath = descriptor.readinessPath;
212
+ const url = `http://127.0.0.1:${port}${readinessPath}`;
213
213
  while (Date.now() < deadline) {
214
214
  const status = yield* effect.Ref.get(statusRef);
215
215
  if (status === "ready" || status === "error") return;
@@ -332,10 +332,11 @@ const makeDevProcess = (pkg, callbacks, portOverride) => effect.Effect.gen(funct
332
332
  }
333
333
  if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks);
334
334
  if (descriptor.source === "remote" || !descriptor.localPath) return yield* spawnRemoteProbe(pkg, descriptor, callbacks);
335
- return yield* spawnDevProcess(portOverride ? {
335
+ const resolvedDescriptor = portOverride ? {
336
336
  ...descriptor,
337
337
  port: portOverride
338
- } : descriptor, callbacks);
338
+ } : descriptor;
339
+ return yield* spawnDevProcess(resolvedDescriptor, callbacks);
339
340
  });
340
341
  function getProcessStates(packages, services, portOverride) {
341
342
  return packages.map((pkg) => {
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.cjs","names":["Effect","DevRuntimeConfig","Deferred","Ref","Command","Stream","Option","ServiceDescriptorMap"],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n DevRuntimeConfig,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nprocess.on(\"unhandledRejection\", (reason) => {\n console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(\"[Orchestrator] Uncaught exception:\", err);\n});\n\nexport interface ProcessCallbacks {\n onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n name: string;\n pid: number | undefined;\n kill: Effect.Effect<void, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<ExitCode, unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: \"local\" | \"remote\";\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n Effect.tryPromise({\n try: async () => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n },\n catch: () => false,\n });\n\nconst LOCAL_PROBE_DEADLINE_MS = 90_000;\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\n\nconst detectStatus = (\n line: string,\n descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n const errorPatterns = descriptor.errorPatterns ?? [];\n const readyPatterns = descriptor.readyPatterns ?? [];\n for (const pattern of errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\n port?: number;\n env?: Record<string, string>;\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n const originalLog = console.log;\n const originalError = console.error;\n const originalWarn = console.warn;\n const originalInfo = console.info;\n\n const formatArgs = (args: unknown[], isError = false): string => {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n const parts = [`${arg.name}: ${arg.message}`];\n if (arg.cause instanceof Error)\n parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n else if (arg.cause) parts.push(`(cause: ${String(arg.cause)})`);\n if (isError && arg.stack) parts.push(arg.stack);\n return parts.join(\"\\n\");\n }\n return typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg);\n })\n .join(\" \");\n };\n\n console.log = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.error = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args, true), true);\n };\n console.warn = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.info = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n\n return () => {\n console.log = originalLog;\n console.error = originalError;\n console.warn = originalWarn;\n console.info = originalInfo;\n };\n};\n\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n const remoteUrl = descriptor.remoteUrl;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\n }\n\n callbacks.onStatus(descriptor.key, \"starting\");\n callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(descriptor.key, callbacks);\n callbacks.onLog(descriptor.key, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n let res: Response;\n try {\n res = await fetch(manifestUrl, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n if (!res.ok) return remoteEntryUrl;\n const json = (await res.json()) as Record<string, unknown>;\n if (\n json &&\n typeof json === \"object\" &&\n \"metaData\" in json &&\n \"exposes\" in json &&\n \"shared\" in json\n ) {\n return manifestUrl;\n }\n } catch (e) {\n console.warn(\n `[Orchestrator] Failed to fetch or parse manifest from ${manifestUrl}, falling back to remoteEntryUrl: ${e}`,\n );\n }\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(descriptor.key, \"Starting server...\");\n const hostPort = runtimeConfig.host?.port;\n const hostEnv: Record<string, string> | undefined = hostPort\n ? { PORT: String(hostPort) }\n : undefined;\n const serverHandle = hostModule.runServer({\n config: runtimeConfig,\n port: hostPort,\n env: hostEnv,\n });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(descriptor.key, \"ready\");\n\n return {\n name: descriptor.key,\n pid: process.pid,\n kill: Effect.gen(function* () {\n callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n restoreConsole();\n yield* Effect.tryPromise({\n try: () => serverHandle.shutdown(),\n catch: () => {},\n }).pipe(Effect.ignore);\n }),\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n\n if (!descriptor.localPath) {\n return yield* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n }\n\n const fullCwd = descriptor.localPath;\n const command = descriptor.command ?? \"bun\";\n const args = descriptor.args ?? [\"run\", \"dev\"];\n const port = descriptor.port ?? descriptor.defaultPort;\n const name = descriptor.key;\n\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n FORCE_COLOR: \"1\",\n ...(port > 0 ? { PORT: String(port) } : {}),\n };\n\n if (name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const cmd = Command.make(command, ...args).pipe(\n Command.workingDirectory(fullCwd),\n Command.env(envVars),\n );\n\n const proc = yield* Command.start(cmd);\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n callbacks.onStatus(name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n const markError = (message: string) =>\n Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(name, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(message)).pipe(Effect.ignore);\n });\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;\n\n if (port > 0) {\n const readinessPath = descriptor.readinessPath;\n const url = `http://127.0.0.1:${port}${readinessPath}`;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = yield* probeHttpOk(url);\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(`${LOCAL_PROBE_INTERVAL_MS} millis`);\n }\n } else {\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n yield* Effect.sleep(\"500 millis\");\n }\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\" && status !== \"error\") {\n callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n yield* markError(`Probe deadline exceeded: ${name}`);\n }\n }),\n );\n\n const pid = Number(proc.pid);\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const exitCode = yield* proc.exitCode;\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n yield* markError(`Process exited before ready: ${name}`);\n }),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n const cleanLine = stripAnsi(line);\n const looksLikeError =\n isStderr &&\n /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n !/^\\$/.test(cleanLine);\n callbacks.onLog(name, line, looksLikeError);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n\n const detected = detectStatus(line, descriptor);\n if (detected) {\n if (detected.status === \"ready\") {\n yield* markReady;\n } else {\n yield* markError(`Process failed: ${name}`);\n }\n }\n });\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, false))(\n Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n ),\n );\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, true))(\n Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n ),\n );\n\n return {\n name,\n pid,\n kill: Effect.gen(function* () {\n const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n if (Option.isNone(result)) {\n const pid = Number(proc.pid);\n yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n yield* Effect.sleep(\"250 millis\");\n }\n }).pipe(Effect.ignore),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: proc.exitCode,\n } satisfies ProcessHandle;\n });\n\nconst spawnRemoteProbe = (\n pkg: string,\n descriptor: ServiceDescriptor,\n callbacks: ProcessCallbacks,\n) =>\n Effect.gen(function* () {\n callbacks.onStatus(pkg, \"starting\");\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n callbacks.onStatus(pkg, \"ready\", \"loaded\");\n });\n\n const markError = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`)).pipe(\n Effect.ignore,\n );\n callbacks.onStatus(pkg, \"error\", \"unreachable\");\n });\n\n const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + REMOTE_PROBE_DEADLINE_MS;\n let delay = REMOTE_PROBE_BACKOFF_INITIAL_MS;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n\n const ok = yield* probeHttpOk(probeUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (ok) {\n yield* markReady;\n return;\n }\n\n const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (fallbackOk) {\n yield* markReady;\n return;\n }\n\n yield* Effect.sleep(`${delay} millis`);\n delay = Math.min(Math.round(delay * 1.5), REMOTE_PROBE_BACKOFF_MAX_MS);\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\") {\n yield* markError;\n }\n }),\n );\n\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.gen(function* () {\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(\"Killed\")).pipe(Effect.ignore);\n }),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n Effect.gen(function* () {\n const services = yield* ServiceDescriptorMap;\n const descriptor = services.get(pkg);\n\n if (!descriptor) {\n callbacks.onStatus(pkg, \"ready\", \"Remote\");\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n }\n\n if (pkg === \"host\" && descriptor.source === \"remote\") {\n return yield* spawnRemoteHost(descriptor, callbacks);\n }\n\n if (descriptor.source === \"remote\" || !descriptor.localPath) {\n return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n }\n\n const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n });\n\nexport function getProcessStates(\n packages: string[],\n services: Map<string, ServiceDescriptor>,\n portOverride?: number,\n): ProcessState[] {\n return packages.map((pkg) => {\n const descriptor = services.get(pkg);\n return {\n name: pkg,\n status: \"pending\" as const,\n port:\n portOverride && pkg === \"host\"\n ? portOverride\n : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n source: descriptor?.source,\n };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.cjs","names":["Effect","DevRuntimeConfig","Deferred","Ref","Command","Stream","Option","ServiceDescriptorMap"],"sources":["../src/orchestrator.ts"],"sourcesContent":["import { Command } from \"@effect/platform\";\nimport type { ExitCode } from \"@effect/platform/CommandExecutor\";\nimport { Deferred, Effect, Option, Ref, Stream } from \"effect\";\nimport { patchManifestFetchForSsrPublicPath } from \"./mf\";\nimport {\n DevRuntimeConfig,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nprocess.on(\"unhandledRejection\", (reason) => {\n console.error(\"[Orchestrator] Unhandled rejection:\", reason);\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(\"[Orchestrator] Uncaught exception:\", err);\n});\n\nexport interface ProcessCallbacks {\n onStatus: (name: string, status: ProcessStatus, message?: string) => void;\n onLog: (name: string, line: string, isError?: boolean) => void;\n}\n\nexport interface ProcessHandle {\n name: string;\n pid: number | undefined;\n kill: Effect.Effect<void, unknown>;\n waitForReady: Effect.Effect<void, Error>;\n waitForExit: Effect.Effect<ExitCode, unknown>;\n}\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: \"local\" | \"remote\";\n}\n\nconst stripAnsi = (input: string): string => {\n const ESC = String.fromCharCode(27);\n const BEL = String.fromCharCode(7);\n return input\n .replace(new RegExp(`${ESC}\\\\][^${BEL}]*${BEL}`, \"g\"), \"\")\n .replace(new RegExp(`${ESC}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n};\n\nconst probeHttpOk = (url: string, timeoutMs = 400) =>\n Effect.tryPromise({\n try: async () => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n },\n catch: () => false,\n });\n\nconst LOCAL_PROBE_DEADLINE_MS = 90_000;\nconst LOCAL_PROBE_INTERVAL_MS = 200;\n\nconst REMOTE_PROBE_TIMEOUT_MS = 5000;\nconst REMOTE_PROBE_DEADLINE_MS = 60_000;\nconst REMOTE_PROBE_BACKOFF_INITIAL_MS = 1000;\nconst REMOTE_PROBE_BACKOFF_MAX_MS = 15_000;\n\nconst detectStatus = (\n line: string,\n descriptor: ServiceDescriptor,\n): { status: ProcessStatus; isError: boolean } | null => {\n const cleanLine = stripAnsi(line);\n const errorPatterns = descriptor.errorPatterns ?? [];\n const readyPatterns = descriptor.readyPatterns ?? [];\n for (const pattern of errorPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"error\", isError: true };\n }\n }\n for (const pattern of readyPatterns) {\n if (pattern.test(cleanLine)) {\n return { status: \"ready\", isError: false };\n }\n }\n return null;\n};\n\ninterface ServerHandle {\n ready: Promise<void>;\n shutdown: () => Promise<void>;\n}\n\ninterface ServerInput {\n config: RuntimeConfig;\n port?: number;\n env?: Record<string, string>;\n}\n\nconst patchConsole = (name: string, callbacks: ProcessCallbacks): (() => void) => {\n const originalLog = console.log;\n const originalError = console.error;\n const originalWarn = console.warn;\n const originalInfo = console.info;\n\n const formatArgs = (args: unknown[], isError = false): string => {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n const parts = [`${arg.name}: ${arg.message}`];\n if (arg.cause instanceof Error)\n parts.push(`(cause: ${arg.cause.name}: ${arg.cause.message})`);\n else if (arg.cause) parts.push(`(cause: ${String(arg.cause)})`);\n if (isError && arg.stack) parts.push(arg.stack);\n return parts.join(\"\\n\");\n }\n return typeof arg === \"object\" ? JSON.stringify(arg, null, 2) : String(arg);\n })\n .join(\" \");\n };\n\n console.log = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.error = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args, true), true);\n };\n console.warn = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n console.info = (...args: unknown[]) => {\n callbacks.onLog(name, formatArgs(args), false);\n };\n\n return () => {\n console.log = originalLog;\n console.error = originalError;\n console.warn = originalWarn;\n console.info = originalInfo;\n };\n};\n\nconst spawnRemoteHost = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n const remoteUrl = descriptor.remoteUrl;\n if (!remoteUrl) {\n return yield* Effect.fail(new Error(\"remoteUrl not provided on host descriptor\"));\n }\n\n callbacks.onStatus(descriptor.key, \"starting\");\n callbacks.onLog(descriptor.key, `Remote: ${remoteUrl}`);\n const restoreConsole = patchConsole(descriptor.key, callbacks);\n callbacks.onLog(descriptor.key, \"Loading Module Federation runtime...\");\n\n const mfRuntime = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/enhanced/runtime\"),\n catch: (e) => new Error(`Failed to load MF runtime: ${e}`),\n });\n\n const mfCore = yield* Effect.tryPromise({\n try: () => import(\"@module-federation/runtime-core\"),\n catch: (e) => new Error(`Failed to load MF core: ${e}`),\n });\n\n let mf = mfRuntime.getInstance();\n if (!mf) {\n mf = mfRuntime.createInstance({ name: \"cli-host\", remotes: [] });\n mfCore.setGlobalFederationInstance(mf);\n }\n patchManifestFetchForSsrPublicPath(mf as any);\n\n const baseUrl = remoteUrl\n .replace(/\\/remoteEntry\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\")\n .replace(/\\/$/, \"\");\n const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n\n const entryUrl = yield* Effect.tryPromise({\n try: async () => {\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n let res: Response;\n try {\n res = await fetch(manifestUrl, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n if (!res.ok) return remoteEntryUrl;\n const json = (await res.json()) as Record<string, unknown>;\n if (\n json &&\n typeof json === \"object\" &&\n \"metaData\" in json &&\n \"exposes\" in json &&\n \"shared\" in json\n ) {\n return manifestUrl;\n }\n } catch (e) {\n console.warn(\n `[Orchestrator] Failed to fetch or parse manifest from ${manifestUrl}, falling back to remoteEntryUrl: ${e}`,\n );\n }\n return remoteEntryUrl;\n },\n catch: () => remoteEntryUrl,\n });\n\n (mf as any).registerRemotes([{ name: \"host\", entry: entryUrl }]);\n callbacks.onLog(descriptor.key, `Loading host from ${entryUrl}...`);\n\n const hostModule = yield* Effect.tryPromise({\n try: () =>\n (mf as any).loadRemote(\"host/Server\") as Promise<{\n runServer: (input: ServerInput) => ServerHandle;\n }>,\n catch: (e) => new Error(`Failed to load host module: ${e}`),\n });\n\n if (!hostModule?.runServer) {\n return yield* Effect.fail(new Error(\"Host module does not export runServer function\"));\n }\n\n callbacks.onLog(descriptor.key, \"Starting server...\");\n const hostPort = runtimeConfig.host?.port;\n const hostEnv: Record<string, string> | undefined = hostPort\n ? { PORT: String(hostPort) }\n : undefined;\n const serverHandle = hostModule.runServer({\n config: runtimeConfig,\n port: hostPort,\n env: hostEnv,\n });\n yield* Effect.tryPromise({\n try: () => serverHandle.ready,\n catch: (e) => new Error(`Server failed to start: ${e}`),\n });\n\n callbacks.onStatus(descriptor.key, \"ready\");\n\n return {\n name: descriptor.key,\n pid: process.pid,\n kill: Effect.gen(function* () {\n callbacks.onLog(descriptor.key, \"Shutting down remote host...\");\n restoreConsole();\n yield* Effect.tryPromise({\n try: () => serverHandle.shutdown(),\n catch: () => {},\n }).pipe(Effect.ignore);\n }),\n waitForReady: Effect.succeed(undefined),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nconst spawnDevProcess = (descriptor: ServiceDescriptor, callbacks: ProcessCallbacks) =>\n Effect.gen(function* () {\n const runtimeConfig = yield* DevRuntimeConfig;\n\n if (!descriptor.localPath) {\n return yield* Effect.fail(new Error(`No localPath for local service: ${descriptor.key}`));\n }\n\n const fullCwd = descriptor.localPath;\n const command = descriptor.command ?? \"bun\";\n const args = descriptor.args ?? [\"run\", \"dev\"];\n const port = descriptor.port ?? descriptor.defaultPort;\n const name = descriptor.key;\n\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n callbacks.onStatus(name, \"starting\");\n\n const envVars: Record<string, string> = {\n ...(process.env as Record<string, string>),\n FORCE_COLOR: \"1\",\n ...(port > 0 ? { PORT: String(port) } : {}),\n };\n\n if (name === \"host\") {\n envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);\n }\n\n const cmd = Command.make(command, ...args).pipe(\n Command.workingDirectory(fullCwd),\n Command.env(envVars),\n );\n\n const proc = yield* Command.start(cmd);\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n callbacks.onStatus(name, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n });\n\n const markError = (message: string) =>\n Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n callbacks.onStatus(name, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(message)).pipe(Effect.ignore);\n });\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;\n\n if (port > 0) {\n const readinessPath = descriptor.readinessPath;\n const url = `http://127.0.0.1:${port}${readinessPath}`;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n const ok = yield* probeHttpOk(url);\n if (ok) {\n yield* markReady;\n return;\n }\n yield* Effect.sleep(`${LOCAL_PROBE_INTERVAL_MS} millis`);\n }\n } else {\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n yield* Effect.sleep(\"500 millis\");\n }\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\" && status !== \"error\") {\n callbacks.onLog(name, \"Probe deadline exceeded after 90s\", true);\n yield* markError(`Probe deadline exceeded: ${name}`);\n }\n }),\n );\n\n const pid = Number(proc.pid);\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const exitCode = yield* proc.exitCode;\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n callbacks.onLog(name, `Process exited before ready (exit code: ${exitCode})`, true);\n yield* markError(`Process exited before ready: ${name}`);\n }),\n );\n\n const handleLine = (line: string, isStderr: boolean) =>\n Effect.gen(function* () {\n if (!line.trim()) return;\n\n const cleanLine = stripAnsi(line);\n const looksLikeError =\n isStderr &&\n /^(error|fail|fatal|exception|unhandled|reject)/i.test(cleanLine) &&\n !/^\\$/.test(cleanLine);\n callbacks.onLog(name, line, looksLikeError);\n\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n\n const detected = detectStatus(line, descriptor);\n if (detected) {\n if (detected.status === \"ready\") {\n yield* markReady;\n } else {\n yield* markError(`Process failed: ${name}`);\n }\n }\n });\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, false))(\n Stream.splitLines(Stream.decodeText(proc.stdout, \"utf-8\")),\n ),\n );\n\n yield* Effect.forkScoped(\n Stream.runForEach((line: string) => handleLine(line, true))(\n Stream.splitLines(Stream.decodeText(proc.stderr, \"utf-8\")),\n ),\n );\n\n return {\n name,\n pid,\n kill: Effect.gen(function* () {\n const result = yield* proc.kill(\"SIGTERM\").pipe(Effect.timeout(\"3 seconds\"), Effect.option);\n if (Option.isNone(result)) {\n const pid = Number(proc.pid);\n yield* Effect.try(() => process.kill(-pid, \"SIGKILL\")).pipe(Effect.ignore);\n yield* Effect.sleep(\"250 millis\");\n }\n }).pipe(Effect.ignore),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: proc.exitCode,\n } satisfies ProcessHandle;\n });\n\nconst spawnRemoteProbe = (\n pkg: string,\n descriptor: ServiceDescriptor,\n callbacks: ProcessCallbacks,\n) =>\n Effect.gen(function* () {\n callbacks.onStatus(pkg, \"starting\");\n const readyDeferred = yield* Deferred.make<void, Error>();\n const statusRef = yield* Ref.make<ProcessStatus>(\"starting\");\n\n const markReady = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"ready\");\n yield* Deferred.succeed(readyDeferred, undefined).pipe(Effect.ignore);\n callbacks.onStatus(pkg, \"ready\", \"loaded\");\n });\n\n const markError = Effect.gen(function* () {\n const currentStatus = yield* Ref.get(statusRef);\n if (currentStatus === \"ready\" || currentStatus === \"error\") return;\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(`Remote ${pkg} unreachable`)).pipe(\n Effect.ignore,\n );\n callbacks.onStatus(pkg, \"error\", \"unreachable\");\n });\n\n const baseUrl = descriptor.url.replace(/\\/$/, \"\");\n const manifestUrl = `${baseUrl}/mf-manifest.json`;\n const entryUrl = `${baseUrl}${descriptor.readinessPath}`;\n const probeUrl = descriptor.readinessPath === \"/health\" ? `${baseUrl}/health` : manifestUrl;\n\n yield* Effect.forkScoped(\n Effect.gen(function* () {\n const deadline = Date.now() + REMOTE_PROBE_DEADLINE_MS;\n let delay = REMOTE_PROBE_BACKOFF_INITIAL_MS;\n while (Date.now() < deadline) {\n const status = yield* Ref.get(statusRef);\n if (status === \"ready\" || status === \"error\") return;\n\n const ok = yield* probeHttpOk(probeUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (ok) {\n yield* markReady;\n return;\n }\n\n const fallbackOk = yield* probeHttpOk(entryUrl, REMOTE_PROBE_TIMEOUT_MS);\n\n if (fallbackOk) {\n yield* markReady;\n return;\n }\n\n yield* Effect.sleep(`${delay} millis`);\n delay = Math.min(Math.round(delay * 1.5), REMOTE_PROBE_BACKOFF_MAX_MS);\n }\n\n const status = yield* Ref.get(statusRef);\n if (status !== \"ready\") {\n yield* markError;\n }\n }),\n );\n\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.gen(function* () {\n yield* Ref.set(statusRef, \"error\");\n yield* Deferred.fail(readyDeferred, new Error(\"Killed\")).pipe(Effect.ignore);\n }),\n waitForReady: Deferred.await(readyDeferred),\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n });\n\nexport const makeDevProcess = (pkg: string, callbacks: ProcessCallbacks, portOverride?: number) =>\n Effect.gen(function* () {\n const services = yield* ServiceDescriptorMap;\n const descriptor = services.get(pkg);\n\n if (!descriptor) {\n callbacks.onStatus(pkg, \"ready\", \"Remote\");\n return {\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle;\n }\n\n if (pkg === \"host\" && descriptor.source === \"remote\") {\n return yield* spawnRemoteHost(descriptor, callbacks);\n }\n\n if (descriptor.source === \"remote\" || !descriptor.localPath) {\n return yield* spawnRemoteProbe(pkg, descriptor, callbacks);\n }\n\n const resolvedDescriptor = portOverride ? { ...descriptor, port: portOverride } : descriptor;\n\n return yield* spawnDevProcess(resolvedDescriptor, callbacks);\n });\n\nexport function getProcessStates(\n packages: string[],\n services: Map<string, ServiceDescriptor>,\n portOverride?: number,\n): ProcessState[] {\n return packages.map((pkg) => {\n const descriptor = services.get(pkg);\n return {\n name: pkg,\n status: \"pending\" as const,\n port:\n portOverride && pkg === \"host\"\n ? portOverride\n : (descriptor?.port ?? descriptor?.defaultPort ?? 0),\n source: descriptor?.source,\n };\n });\n}\n"],"mappings":"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"}
@@ -208,7 +208,8 @@ const spawnDevProcess = (descriptor, callbacks) => Effect.gen(function* () {
208
208
  yield* Effect.forkScoped(Effect.gen(function* () {
209
209
  const deadline = Date.now() + LOCAL_PROBE_DEADLINE_MS;
210
210
  if (port > 0) {
211
- const url = `http://127.0.0.1:${port}${descriptor.readinessPath}`;
211
+ const readinessPath = descriptor.readinessPath;
212
+ const url = `http://127.0.0.1:${port}${readinessPath}`;
212
213
  while (Date.now() < deadline) {
213
214
  const status = yield* Ref.get(statusRef);
214
215
  if (status === "ready" || status === "error") return;
@@ -331,10 +332,11 @@ const makeDevProcess = (pkg, callbacks, portOverride) => Effect.gen(function* ()
331
332
  }
332
333
  if (pkg === "host" && descriptor.source === "remote") return yield* spawnRemoteHost(descriptor, callbacks);
333
334
  if (descriptor.source === "remote" || !descriptor.localPath) return yield* spawnRemoteProbe(pkg, descriptor, callbacks);
334
- return yield* spawnDevProcess(portOverride ? {
335
+ const resolvedDescriptor = portOverride ? {
335
336
  ...descriptor,
336
337
  port: portOverride
337
- } : descriptor, callbacks);
338
+ } : descriptor;
339
+ return yield* spawnDevProcess(resolvedDescriptor, callbacks);
338
340
  });
339
341
  function getProcessStates(packages, services, portOverride) {
340
342
  return packages.map((pkg) => {