handoff-app 1.2.2-7 → 2.0.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/Changelog.md +37 -15
  2. package/README.md +372 -118
  3. package/dist/app-builder/build.d.ts +41 -2
  4. package/dist/app-builder/build.js +455 -18
  5. package/dist/app-builder/client-config.d.ts +15 -2
  6. package/dist/app-builder/client-config.js +43 -4
  7. package/dist/app-builder/config-diff/snapshot.d.ts +1 -6
  8. package/dist/app-builder/config-diff/snapshot.js +2 -9
  9. package/dist/app-builder/index.d.ts +1 -1
  10. package/dist/app-builder/index.js +3 -1
  11. package/dist/app-builder/nav-shell.d.ts +23 -0
  12. package/dist/app-builder/nav-shell.js +80 -0
  13. package/dist/app-builder/static-export.d.ts +17 -0
  14. package/dist/app-builder/static-export.js +181 -0
  15. package/dist/app-builder/vercel-output.d.ts +39 -0
  16. package/dist/app-builder/vercel-output.js +259 -0
  17. package/dist/app-builder/watchers/utils.d.ts +2 -0
  18. package/dist/app-builder/watchers.d.ts +14 -4
  19. package/dist/app-builder/watchers.js +123 -28
  20. package/dist/app-builder/websocket.js +1 -1
  21. package/dist/artifacts/index.d.ts +2 -0
  22. package/dist/artifacts/index.js +13 -0
  23. package/dist/artifacts/types.d.ts +136 -0
  24. package/dist/artifacts/types.js +24 -0
  25. package/dist/artifacts/url.d.ts +49 -0
  26. package/dist/artifacts/url.js +86 -0
  27. package/dist/cache/build-cache.js +48 -4
  28. package/dist/cli.js +0 -0
  29. package/dist/commands/build/app.js +1 -2
  30. package/dist/commands/build/index.d.ts +17 -0
  31. package/dist/commands/build/index.js +66 -0
  32. package/dist/commands/checkout/index.d.ts +24 -0
  33. package/dist/commands/checkout/index.js +71 -0
  34. package/dist/commands/db/migrate.d.ts +11 -0
  35. package/dist/commands/db/migrate.js +33 -0
  36. package/dist/commands/index.js +8 -0
  37. package/dist/commands/publish/index.d.ts +21 -0
  38. package/dist/commands/publish/index.js +68 -0
  39. package/dist/config/defaults.js +15 -1
  40. package/dist/config/loader.js +6 -1
  41. package/dist/config/normalizers/declaration.js +4 -1
  42. package/dist/config/normalizers/page.d.ts +18 -0
  43. package/dist/config/normalizers/page.js +34 -0
  44. package/dist/config/normalizers/pattern.js +7 -1
  45. package/dist/config/runtime.d.ts +4 -0
  46. package/dist/config/runtime.js +53 -5
  47. package/dist/index.d.ts +65 -1
  48. package/dist/index.js +123 -3
  49. package/dist/nav/index.d.ts +83 -0
  50. package/dist/nav/index.js +9 -0
  51. package/dist/nav/registry.d.ts +15 -0
  52. package/dist/nav/registry.js +42 -0
  53. package/dist/nav/resolver.d.ts +8 -0
  54. package/dist/nav/resolver.js +192 -0
  55. package/dist/nav/workspace.d.ts +18 -0
  56. package/dist/nav/workspace.js +103 -0
  57. package/dist/pipeline/styles.js +7 -35
  58. package/dist/pipeline/token-transformers.d.ts +45 -0
  59. package/dist/pipeline/token-transformers.js +71 -0
  60. package/dist/registry/asset-storage/adapters/vercel-blob.d.ts +17 -0
  61. package/dist/registry/asset-storage/adapters/vercel-blob.js +87 -0
  62. package/dist/registry/asset-storage/define.d.ts +10 -0
  63. package/dist/registry/asset-storage/define.js +13 -0
  64. package/dist/registry/asset-storage/resolve.d.ts +45 -0
  65. package/dist/registry/asset-storage/resolve.js +36 -0
  66. package/dist/registry/asset-storage/types.d.ts +51 -0
  67. package/dist/registry/asset-storage/types.js +9 -0
  68. package/dist/registry/assets/layout.d.ts +22 -0
  69. package/dist/registry/assets/layout.js +30 -0
  70. package/dist/registry/assets/sets.d.ts +18 -0
  71. package/dist/registry/assets/sets.js +44 -0
  72. package/dist/registry/assets/transfer.d.ts +45 -0
  73. package/dist/registry/assets/transfer.js +11 -0
  74. package/dist/registry/checkout/assets.d.ts +16 -0
  75. package/dist/registry/checkout/assets.js +150 -0
  76. package/dist/registry/checkout/index.d.ts +33 -0
  77. package/dist/registry/checkout/index.js +610 -0
  78. package/dist/registry/checkout/tokens.d.ts +15 -0
  79. package/dist/registry/checkout/tokens.js +171 -0
  80. package/dist/registry/client.d.ts +61 -0
  81. package/dist/registry/client.js +211 -0
  82. package/dist/registry/connection.d.ts +30 -0
  83. package/dist/registry/connection.js +36 -0
  84. package/dist/registry/db/adapter.d.ts +43 -0
  85. package/dist/registry/db/adapter.js +59 -0
  86. package/dist/registry/db/client.d.ts +35 -0
  87. package/dist/registry/db/client.js +94 -0
  88. package/dist/registry/db/index.d.ts +5 -0
  89. package/dist/registry/db/index.js +24 -0
  90. package/dist/registry/db/migrate.d.ts +23 -0
  91. package/dist/registry/db/migrate.js +64 -0
  92. package/dist/registry/db/schema.d.ts +4869 -0
  93. package/dist/registry/db/schema.js +347 -0
  94. package/dist/registry/path.d.ts +4 -0
  95. package/dist/registry/path.js +31 -0
  96. package/dist/registry/publish/artifacts.d.ts +16 -0
  97. package/dist/registry/publish/artifacts.js +132 -0
  98. package/dist/registry/publish/assets.d.ts +16 -0
  99. package/dist/registry/publish/assets.js +129 -0
  100. package/dist/registry/publish/errors.d.ts +5 -0
  101. package/dist/registry/publish/errors.js +26 -0
  102. package/dist/registry/publish/index.d.ts +27 -0
  103. package/dist/registry/publish/index.js +126 -0
  104. package/dist/registry/publish/package.d.ts +27 -0
  105. package/dist/registry/publish/package.js +257 -0
  106. package/dist/registry/publish/publish-build.d.ts +12 -0
  107. package/dist/registry/publish/publish-build.js +43 -0
  108. package/dist/registry/publish/tokens.d.ts +18 -0
  109. package/dist/registry/publish/tokens.js +112 -0
  110. package/dist/registry/tokens/sets.d.ts +59 -0
  111. package/dist/registry/tokens/sets.js +109 -0
  112. package/dist/registry/tokens/transfer.d.ts +48 -0
  113. package/dist/registry/tokens/transfer.js +10 -0
  114. package/dist/registry/transfer.d.ts +75 -0
  115. package/dist/registry/transfer.js +11 -0
  116. package/dist/store/filesystem-assets.d.ts +17 -0
  117. package/dist/store/filesystem-assets.js +147 -0
  118. package/dist/store/filesystem.d.ts +76 -0
  119. package/dist/store/filesystem.js +208 -0
  120. package/dist/store/index.d.ts +20 -0
  121. package/dist/store/index.js +38 -0
  122. package/dist/store/registry.d.ts +77 -0
  123. package/dist/store/registry.js +350 -0
  124. package/dist/store/source-files.d.ts +24 -0
  125. package/dist/store/source-files.js +147 -0
  126. package/dist/store/types.d.ts +185 -0
  127. package/dist/store/types.js +12 -0
  128. package/dist/transformers/plugins/csf-render.js +17 -8
  129. package/dist/transformers/plugins/handlebars-previews.js +10 -3
  130. package/dist/transformers/plugins/ssr-render.js +116 -49
  131. package/dist/transformers/preview/component/api.js +3 -1
  132. package/dist/transformers/preview/component/artifacts.js +8 -1
  133. package/dist/transformers/preview/component/builder.js +13 -5
  134. package/dist/transformers/preview/component/css.js +9 -1
  135. package/dist/transformers/preview/component/javascript.d.ts +9 -3
  136. package/dist/transformers/preview/component/javascript.js +45 -17
  137. package/dist/transformers/preview/component/shared-artifacts.d.ts +83 -0
  138. package/dist/transformers/preview/component/shared-artifacts.js +92 -0
  139. package/dist/transformers/preview/component.js +5 -2
  140. package/dist/transformers/preview/pattern/builder.js +28 -9
  141. package/dist/transformers/preview/pattern/html.d.ts +13 -10
  142. package/dist/transformers/preview/pattern/html.js +62 -27
  143. package/dist/transformers/preview/types.d.ts +38 -0
  144. package/dist/transformers/utils/handlebars.d.ts +3 -0
  145. package/dist/transformers/utils/handlebars.js +19 -5
  146. package/dist/types/config.d.ts +118 -25
  147. package/dist/utils/menu-shell.d.ts +60 -0
  148. package/dist/utils/menu-shell.js +221 -0
  149. package/dist/utils/stable-stringify.d.ts +2 -0
  150. package/dist/utils/stable-stringify.js +8 -0
  151. package/docs/cli.md +4 -2
  152. package/drizzle/0000_init_registry_storage.sql +95 -0
  153. package/drizzle/0001_add_review_metadata.sql +2 -0
  154. package/drizzle/0002_add_pages.sql +28 -0
  155. package/drizzle/0003_add_tokens.sql +29 -0
  156. package/drizzle/0004_add_assets.sql +37 -0
  157. package/drizzle/meta/0000_snapshot.json +642 -0
  158. package/drizzle/meta/0001_snapshot.json +654 -0
  159. package/drizzle/meta/0002_snapshot.json +835 -0
  160. package/drizzle/meta/0003_snapshot.json +1023 -0
  161. package/drizzle/meta/0004_snapshot.json +1252 -0
  162. package/drizzle/meta/_journal.json +41 -0
  163. package/drizzle.config.ts +16 -0
  164. package/package.json +10 -1
  165. package/src/app/components/Component/Preview.tsx +3 -2
  166. package/src/app/components/Component/RegistryActions.tsx +150 -0
  167. package/src/app/components/Foundations/DisplayLogo.tsx +5 -3
  168. package/src/app/components/Layout/Header.tsx +21 -3
  169. package/src/app/components/Layout/Main.tsx +11 -3
  170. package/src/app/components/Navigation/MainNav.tsx +4 -2
  171. package/src/app/components/Navigation/MobileNav.tsx +4 -2
  172. package/src/app/components/Navigation/SideNav.tsx +46 -11
  173. package/src/app/components/NotFound.tsx +24 -0
  174. package/src/app/components/context/NavProvider.tsx +71 -0
  175. package/src/app/components/old/Header.tsx +3 -3
  176. package/src/app/components/util/index.ts +203 -380
  177. package/src/app/components/util/useCollectionAssets.ts +125 -0
  178. package/src/app/components/util/useFoundationTokens.ts +67 -0
  179. package/src/app/generated/default-pages.json +1 -0
  180. package/src/app/generated/nav-shell.json +1 -0
  181. package/src/app/lib/api/query.ts +6 -0
  182. package/src/app/lib/api/redact.ts +46 -0
  183. package/src/app/lib/asset-storage.ts +81 -0
  184. package/src/app/lib/docs-api/artifacts.ts +116 -0
  185. package/src/app/lib/docs-api/backend.ts +151 -0
  186. package/src/app/lib/docs-api/errors.ts +52 -0
  187. package/src/app/lib/docs-api/handler.ts +34 -0
  188. package/src/app/lib/docs-api/index.ts +7 -0
  189. package/src/app/lib/docs-api/records.ts +189 -0
  190. package/src/app/lib/docs-api/registry.ts +130 -0
  191. package/src/app/lib/docs-api/runtime-config.ts +173 -0
  192. package/src/app/lib/docs-api/serve.ts +37 -0
  193. package/src/app/lib/docs-api/token-detail.ts +19 -0
  194. package/src/app/lib/registry-api/allowlist.ts +163 -0
  195. package/src/app/lib/registry-api/asset-transfer.ts +363 -0
  196. package/src/app/lib/registry-api/auth.ts +68 -0
  197. package/src/app/lib/registry-api/entity-routes.ts +197 -0
  198. package/src/app/lib/registry-api/errors.ts +51 -0
  199. package/src/app/lib/registry-api/files.ts +135 -0
  200. package/src/app/lib/registry-api/handler.ts +96 -0
  201. package/src/app/lib/registry-api/index.ts +4 -0
  202. package/src/app/lib/registry-api/meta.ts +87 -0
  203. package/src/app/lib/registry-api/revalidate.ts +36 -0
  204. package/src/app/lib/registry-api/store.ts +348 -0
  205. package/src/app/lib/registry-api/token-transfer.ts +231 -0
  206. package/src/app/lib/registry-api/transfer.ts +513 -0
  207. package/src/app/lib/registry-api/validation.ts +74 -0
  208. package/src/app/lib/registry-connection.ts +58 -0
  209. package/src/app/lib/utils.ts +14 -0
  210. package/src/app/next.config.mjs +72 -13
  211. package/src/app/pages/[...slug]/index.tsx +74 -20
  212. package/src/app/pages/_app.tsx +5 -2
  213. package/src/app/pages/api/docs/artifacts/[...artifactPath].ts +16 -0
  214. package/src/app/pages/api/docs/assets/[collection]/[...path].ts +50 -0
  215. package/src/app/pages/api/docs/assets/[collection]/index.ts +22 -0
  216. package/src/app/pages/api/docs/components/[id]/assets/[asset].ts +33 -0
  217. package/src/app/pages/api/docs/components/[id]/inspect/[previewId].ts +20 -0
  218. package/src/app/pages/api/docs/components/[id]/previews/[previewId].ts +21 -0
  219. package/src/app/pages/api/docs/components/[id].ts +24 -0
  220. package/src/app/pages/api/docs/components.json.ts +12 -0
  221. package/src/app/pages/api/docs/nav.json.ts +48 -0
  222. package/src/app/pages/api/docs/patterns/[id]/preview.ts +19 -0
  223. package/src/app/pages/api/docs/patterns/[id].ts +24 -0
  224. package/src/app/pages/api/docs/patterns.json.ts +12 -0
  225. package/src/app/pages/api/docs/tokens/components/[id].ts +30 -0
  226. package/src/app/pages/api/docs/tokens/foundations/[type].ts +32 -0
  227. package/src/app/pages/api/registry/components/[id]/files/[...filePath].ts +19 -0
  228. package/src/app/pages/api/registry/components/[id]/files/index.ts +19 -0
  229. package/src/app/pages/api/registry/components/[id].ts +20 -0
  230. package/src/app/pages/api/registry/components/index.ts +19 -0
  231. package/src/app/pages/api/registry/health.ts +20 -0
  232. package/src/app/pages/api/registry/patterns/[id]/files/[...filePath].ts +19 -0
  233. package/src/app/pages/api/registry/patterns/[id]/files/index.ts +19 -0
  234. package/src/app/pages/api/registry/patterns/[id].ts +20 -0
  235. package/src/app/pages/api/registry/patterns/index.ts +19 -0
  236. package/src/app/pages/api/registry/transfer/[kind]/[id].ts +39 -0
  237. package/src/app/pages/api/registry/transfer/assets/[collection].ts +24 -0
  238. package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +23 -0
  239. package/src/app/pages/api/registry/transfer/assets/blobs/have.ts +11 -0
  240. package/src/app/pages/api/registry/transfer/assets/index.ts +10 -0
  241. package/src/app/pages/api/registry/transfer/tokens/[...setId].ts +26 -0
  242. package/src/app/pages/api/registry/transfer/tokens/index.ts +11 -0
  243. package/src/app/pages/assets/fonts.tsx +41 -17
  244. package/src/app/pages/assets/index.tsx +2 -2
  245. package/src/app/pages/assets/logos.tsx +2 -2
  246. package/src/app/pages/foundations/colors.tsx +18 -8
  247. package/src/app/pages/foundations/effects.tsx +18 -8
  248. package/src/app/pages/foundations/icons/[name]/index.tsx +26 -14
  249. package/src/app/pages/foundations/icons/index.tsx +13 -9
  250. package/src/app/pages/foundations/index.tsx +1 -1
  251. package/src/app/pages/foundations/logo.tsx +7 -4
  252. package/src/app/pages/foundations/typography.tsx +19 -9
  253. package/src/app/pages/index.tsx +1 -1
  254. package/src/app/pages/system/component/[component]/index.tsx +87 -17
  255. package/src/app/pages/system/index.tsx +13 -4
  256. package/src/app/pages/system/pattern/[pattern]/index.tsx +70 -14
  257. package/src/app/pages/system/tokens/components/[component]/index.tsx +42 -14
  258. package/src/app/pages/system/tokens/foundations/colors.tsx +7 -5
  259. package/src/app/pages/system/tokens/foundations/effects.tsx +7 -5
  260. package/src/app/pages/system/tokens/foundations/typography.tsx +8 -4
  261. package/src/app/tsconfig.json +2 -3
  262. package/src/app-builder/build.ts +555 -11
  263. package/src/app-builder/client-config.ts +61 -4
  264. package/src/app-builder/config-diff/snapshot.ts +1 -11
  265. package/src/app-builder/index.ts +1 -1
  266. package/src/app-builder/nav-shell.ts +74 -0
  267. package/src/app-builder/static-export.ts +215 -0
  268. package/src/app-builder/vercel-output.ts +297 -0
  269. package/src/app-builder/watchers/utils.ts +2 -0
  270. package/src/app-builder/watchers.ts +149 -25
  271. package/src/app-builder/websocket.ts +2 -2
  272. package/src/artifacts/README.md +14 -0
  273. package/src/artifacts/index.ts +17 -0
  274. package/src/artifacts/types.ts +146 -0
  275. package/src/artifacts/url.ts +90 -0
  276. package/src/cache/build-cache.ts +47 -2
  277. package/src/commands/build/app.ts +1 -2
  278. package/src/commands/build/index.ts +61 -0
  279. package/src/commands/checkout/index.ts +66 -0
  280. package/src/commands/db/migrate.ts +25 -0
  281. package/src/commands/index.ts +8 -0
  282. package/src/commands/publish/index.ts +63 -0
  283. package/src/config/defaults.ts +15 -0
  284. package/src/config/loader.ts +10 -1
  285. package/src/config/normalizers/declaration.ts +3 -0
  286. package/src/config/normalizers/page.ts +45 -0
  287. package/src/config/normalizers/pattern.ts +4 -1
  288. package/src/config/runtime.ts +48 -2
  289. package/src/index.ts +126 -3
  290. package/src/nav/index.ts +94 -0
  291. package/src/nav/registry.ts +54 -0
  292. package/src/nav/resolver.ts +217 -0
  293. package/src/nav/workspace.ts +87 -0
  294. package/src/pipeline/styles.ts +4 -35
  295. package/src/pipeline/token-transformers.ts +97 -0
  296. package/src/registry/asset-storage/adapters/vercel-blob.ts +51 -0
  297. package/src/registry/asset-storage/define.ts +15 -0
  298. package/src/registry/asset-storage/resolve.ts +72 -0
  299. package/src/registry/asset-storage/types.ts +46 -0
  300. package/src/registry/assets/layout.ts +38 -0
  301. package/src/registry/assets/sets.ts +48 -0
  302. package/src/registry/assets/transfer.ts +50 -0
  303. package/src/registry/checkout/assets.ts +126 -0
  304. package/src/registry/checkout/index.ts +596 -0
  305. package/src/registry/checkout/tokens.ts +152 -0
  306. package/src/registry/client.ts +234 -0
  307. package/src/registry/connection.ts +50 -0
  308. package/src/registry/db/adapter.ts +74 -0
  309. package/src/registry/db/client.ts +88 -0
  310. package/src/registry/db/index.ts +35 -0
  311. package/src/registry/db/migrate.ts +56 -0
  312. package/src/registry/db/schema.ts +444 -0
  313. package/src/registry/path.ts +26 -0
  314. package/src/registry/publish/artifacts.ts +147 -0
  315. package/src/registry/publish/assets.ts +129 -0
  316. package/src/registry/publish/errors.ts +34 -0
  317. package/src/registry/publish/index.ts +128 -0
  318. package/src/registry/publish/package.ts +272 -0
  319. package/src/registry/publish/publish-build.ts +51 -0
  320. package/src/registry/publish/tokens.ts +119 -0
  321. package/src/registry/tokens/sets.ts +132 -0
  322. package/src/registry/tokens/transfer.ts +53 -0
  323. package/src/registry/transfer.ts +82 -0
  324. package/src/store/filesystem-assets.ts +152 -0
  325. package/src/store/filesystem.ts +237 -0
  326. package/src/store/index.ts +62 -0
  327. package/src/store/registry.ts +334 -0
  328. package/src/store/source-files.ts +155 -0
  329. package/src/store/types.ts +210 -0
  330. package/src/transformers/plugins/csf-render.ts +31 -7
  331. package/src/transformers/plugins/handlebars-previews.ts +22 -3
  332. package/src/transformers/plugins/ssr-render.ts +145 -57
  333. package/src/transformers/preview/component/api.ts +2 -1
  334. package/src/transformers/preview/component/artifacts.ts +10 -1
  335. package/src/transformers/preview/component/builder.ts +9 -2
  336. package/src/transformers/preview/component/css.ts +10 -1
  337. package/src/transformers/preview/component/javascript.ts +55 -20
  338. package/src/transformers/preview/component/shared-artifacts.ts +146 -0
  339. package/src/transformers/preview/component.ts +5 -2
  340. package/src/transformers/preview/pattern/builder.ts +33 -7
  341. package/src/transformers/preview/pattern/html.ts +71 -27
  342. package/src/transformers/preview/types.ts +42 -0
  343. package/src/transformers/utils/handlebars.ts +31 -5
  344. package/src/types/config.ts +123 -25
  345. package/src/utils/menu-shell.ts +241 -0
  346. package/src/utils/stable-stringify.ts +7 -0
  347. package/templates/default/package.json.tpl +1 -1
  348. package/handoff.config.js +0 -90
  349. package/src/app/components/ComponentSearch.tsx +0 -93
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ /**
3
+ * Connected-workspace token checkout orchestration.
4
+ *
5
+ * `checkout tokens [setId]` pulls published token sets from the connected registry into this
6
+ * workspace: it reconstructs the canonical local `tokens.json` (splicing each set's record into the
7
+ * document) and restores the generated token files (CSS/SCSS/Style Dictionary/types/custom) to their
8
+ * standard configured output paths under `getVariablesFilePath()`. Overwriting changed local token
9
+ * data requires `--force` or an interactive confirmation. Available only from a connected workspace.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
35
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
36
+ return new (P || (P = Promise))(function (resolve, reject) {
37
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
38
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
39
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
40
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
41
+ });
42
+ };
43
+ var __importDefault = (this && this.__importDefault) || function (mod) {
44
+ return (mod && mod.__esModule) ? mod : { "default": mod };
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.checkoutTokens = void 0;
48
+ const p = __importStar(require("@clack/prompts"));
49
+ const fs_extra_1 = __importDefault(require("fs-extra"));
50
+ const path_1 = __importDefault(require("path"));
51
+ const logger_1 = require("../../utils/logger");
52
+ const client_1 = require("../client");
53
+ const path_2 = require("../path");
54
+ const sets_1 = require("../tokens/sets");
55
+ const index_1 = require("./index");
56
+ /** Map a registry client error to an actionable checkout message. */
57
+ const describeFetchFailure = (error, target, registryUrl) => {
58
+ switch (error.code) {
59
+ case 'not_found':
60
+ return `No token set "${target}" exists in the registry at ${registryUrl}.`;
61
+ case 'runtime_mode_conflict':
62
+ return `The registry at ${registryUrl} is not running in registry mode, so it cannot serve a checkout: ${error.message}`;
63
+ case 'unauthorized':
64
+ return `The registry rejected the access token (401). Check the configured access token matches the registry's token.`;
65
+ default:
66
+ return error.message;
67
+ }
68
+ };
69
+ /** Read the existing local token document, or `null` when none exists yet. */
70
+ const readExistingDocument = (handoff) => {
71
+ const tokensFilePath = handoff.getTokensFilePath();
72
+ if (!fs_extra_1.default.existsSync(tokensFilePath)) {
73
+ return null;
74
+ }
75
+ try {
76
+ return JSON.parse(fs_extra_1.default.readFileSync(tokensFilePath, 'utf8'));
77
+ }
78
+ catch (_a) {
79
+ return null;
80
+ }
81
+ };
82
+ /** Whether writing `content` to `absolutePath` would change (or create) the file. */
83
+ const wouldChange = (absolutePath, content) => {
84
+ if (!fs_extra_1.default.existsSync(absolutePath)) {
85
+ return true;
86
+ }
87
+ try {
88
+ return fs_extra_1.default.readFileSync(absolutePath, 'utf8') !== content;
89
+ }
90
+ catch (_a) {
91
+ return true;
92
+ }
93
+ };
94
+ /**
95
+ * Checkout all published token sets, or a single set when `setId` is given. Reconstructs `tokens.json`
96
+ * and restores generated files; prompts before overwriting changed local files unless `--force`.
97
+ */
98
+ const checkoutTokens = (handoff, setId) => __awaiter(void 0, void 0, void 0, function* () {
99
+ if (setId && !(0, sets_1.isTokenSetId)(setId)) {
100
+ throw new index_1.CheckoutError(`Unknown or unsafe token set id "${setId}".`);
101
+ }
102
+ const connection = (0, index_1.resolveConnectionOrThrow)(handoff);
103
+ const client = (0, client_1.createRegistryClient)({ baseUrl: connection.url, accessToken: connection.accessToken });
104
+ let ids;
105
+ if (setId) {
106
+ ids = [setId];
107
+ }
108
+ else {
109
+ const summaries = yield client.listTokenSets();
110
+ ids = summaries.map((summary) => summary.id);
111
+ if (ids.length === 0) {
112
+ logger_1.Logger.info('No token sets are published to the registry; nothing to checkout.');
113
+ return;
114
+ }
115
+ }
116
+ const payloads = [];
117
+ for (const id of ids) {
118
+ if (!(0, sets_1.isTokenSetId)(id)) {
119
+ throw new index_1.CheckoutError(`Registry returned an unknown or unsafe token set id "${id}".`);
120
+ }
121
+ try {
122
+ payloads.push(yield client.checkoutTokens(id));
123
+ }
124
+ catch (error) {
125
+ if (error instanceof client_1.RegistryClientError) {
126
+ throw new index_1.CheckoutError(describeFetchFailure(error, id, connection.url));
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+ const existingDoc = readExistingDocument(handoff);
132
+ const sets = payloads.map((payload) => ({ id: payload.id, kind: payload.kind, record: payload.record }));
133
+ const mergedDoc = (0, sets_1.mergeTokenSetsIntoDocument)(existingDoc, sets);
134
+ const mergedDocContent = `${JSON.stringify(mergedDoc, null, 2)}\n`;
135
+ const variablesDir = handoff.getVariablesFilePath();
136
+ const artifactWrites = payloads.flatMap((payload) => payload.artifacts.map((artifact) => {
137
+ const absolutePath = (0, path_2.resolvePathWithin)(variablesDir, artifact.path);
138
+ if (!absolutePath) {
139
+ throw new index_1.CheckoutError(`Registry returned an unsafe token artifact path "${artifact.path}".`);
140
+ }
141
+ return { absolutePath, content: artifact.content };
142
+ }));
143
+ const tokensFilePath = handoff.getTokensFilePath();
144
+ const changed = [];
145
+ if (wouldChange(tokensFilePath, mergedDocContent)) {
146
+ changed.push(tokensFilePath);
147
+ }
148
+ for (const write of artifactWrites) {
149
+ if (wouldChange(write.absolutePath, write.content)) {
150
+ changed.push(write.absolutePath);
151
+ }
152
+ }
153
+ const existingChanges = changed.filter((filePath) => fs_extra_1.default.existsSync(filePath));
154
+ if (existingChanges.length > 0 && !handoff.force) {
155
+ const proceed = yield p.confirm({
156
+ message: `Checkout will overwrite ${existingChanges.length} changed local token file(s). Continue?`,
157
+ });
158
+ if (p.isCancel(proceed) || proceed !== true) {
159
+ logger_1.Logger.info('Token checkout cancelled; no files were written.');
160
+ return;
161
+ }
162
+ }
163
+ yield fs_extra_1.default.ensureDir(path_1.default.dirname(tokensFilePath));
164
+ yield fs_extra_1.default.writeFile(tokensFilePath, mergedDocContent);
165
+ for (const write of artifactWrites) {
166
+ yield fs_extra_1.default.ensureDir(path_1.default.dirname(write.absolutePath));
167
+ yield fs_extra_1.default.writeFile(write.absolutePath, write.content);
168
+ }
169
+ logger_1.Logger.success(`Checked out ${ids.length} token set(s) into ${tokensFilePath} (${artifactWrites.length} generated file(s) restored).`);
170
+ });
171
+ exports.checkoutTokens = checkoutTokens;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared registry HTTP client.
3
+ *
4
+ * One client both the CLI and the app use to talk to a remote registry over its HTTP API. It owns
5
+ * the transfer endpoint URL shape, bearer-token auth, and the `{ data | error, meta }` envelope
6
+ * decoding, mapping registry error responses to an actionable {@link RegistryClientError} so callers
7
+ * surface a clear message instead of a raw fetch failure. Transport is the global `fetch` (Node 18+
8
+ * and the browser both provide it), so this module stays runtime-agnostic.
9
+ */
10
+ import type { CheckoutPayload, TransferEntityKind, TransferPackage } from './transfer';
11
+ import type { TokenSetCheckoutPayload, TokenSetSummary, TokenSetTransferPackage } from './tokens/transfer';
12
+ import type { AssetCollectionCheckoutPayload, AssetCollectionSummary, AssetCollectionTransferPackage } from './assets/transfer';
13
+ /** Standard registry response envelope. */
14
+ export interface RegistryEnvelope<T = unknown> {
15
+ data?: T;
16
+ error?: {
17
+ code: string;
18
+ message: string;
19
+ details?: Record<string, unknown>;
20
+ };
21
+ meta?: Record<string, unknown>;
22
+ }
23
+ /**
24
+ * A failed registry request. Carries the HTTP status and (when the server returned the registry
25
+ * error envelope) the registry error `code`/`details`, so callers can tailor messaging.
26
+ */
27
+ export declare class RegistryClientError extends Error {
28
+ status?: number;
29
+ code?: string;
30
+ details?: Record<string, unknown>;
31
+ constructor(message: string, options?: {
32
+ status?: number;
33
+ code?: string;
34
+ details?: Record<string, unknown>;
35
+ });
36
+ }
37
+ export interface RegistryClientOptions {
38
+ /** Remote registry base URL (may include a configured basePath). */
39
+ baseUrl: string;
40
+ /** Bearer token sent on mutating requests. */
41
+ accessToken: string;
42
+ }
43
+ /** HTTP operations used by connected workspace publish and checkout workflows. */
44
+ export interface RegistryClient {
45
+ publish(kind: TransferEntityKind, id: string, pkg: TransferPackage): Promise<RegistryEnvelope>;
46
+ checkout(kind: TransferEntityKind, id: string): Promise<CheckoutPayload>;
47
+ listTokenSets(): Promise<TokenSetSummary[]>;
48
+ publishTokens(pkg: TokenSetTransferPackage): Promise<RegistryEnvelope>;
49
+ checkoutTokens(id: string): Promise<TokenSetCheckoutPayload>;
50
+ listAssetCollections(): Promise<AssetCollectionSummary[]>;
51
+ assetBlobHaveCheck(hashes: string[]): Promise<string[]>;
52
+ uploadAssetBlob(hash: string, contentType: string, bytes: Buffer): Promise<void>;
53
+ downloadAssetBlob(hash: string): Promise<Buffer>;
54
+ publishAssetManifest(pkg: AssetCollectionTransferPackage): Promise<RegistryEnvelope>;
55
+ checkoutAssetCollection(collection: string): Promise<AssetCollectionCheckoutPayload>;
56
+ }
57
+ /**
58
+ * Build a registry HTTP client bound to one connection. Methods reject with a
59
+ * {@link RegistryClientError} on transport failure, non-2xx responses, or an error envelope.
60
+ */
61
+ export declare const createRegistryClient: ({ baseUrl, accessToken }: RegistryClientOptions) => RegistryClient;
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ /**
3
+ * Shared registry HTTP client.
4
+ *
5
+ * One client both the CLI and the app use to talk to a remote registry over its HTTP API. It owns
6
+ * the transfer endpoint URL shape, bearer-token auth, and the `{ data | error, meta }` envelope
7
+ * decoding, mapping registry error responses to an actionable {@link RegistryClientError} so callers
8
+ * surface a clear message instead of a raw fetch failure. Transport is the global `fetch` (Node 18+
9
+ * and the browser both provide it), so this module stays runtime-agnostic.
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.createRegistryClient = exports.RegistryClientError = void 0;
22
+ /** Encode a token set id for the catch-all transfer route, preserving `/` between segments. */
23
+ const encodeSetIdPath = (id) => id
24
+ .split('/')
25
+ .map((segment) => encodeURIComponent(segment))
26
+ .join('/');
27
+ /**
28
+ * A failed registry request. Carries the HTTP status and (when the server returned the registry
29
+ * error envelope) the registry error `code`/`details`, so callers can tailor messaging.
30
+ */
31
+ class RegistryClientError extends Error {
32
+ constructor(message, options = {}) {
33
+ super(message);
34
+ this.name = 'RegistryClientError';
35
+ this.status = options.status;
36
+ this.code = options.code;
37
+ this.details = options.details;
38
+ }
39
+ }
40
+ exports.RegistryClientError = RegistryClientError;
41
+ /** Strip a single trailing slash so URL joining never doubles separators. */
42
+ const trimTrailingSlash = (value) => value.replace(/\/+$/, '');
43
+ /**
44
+ * Describe a transport-level fetch failure. `fetch` reports a generic "fetch failed"; the actionable
45
+ * detail (ECONNREFUSED / ECONNRESET / socket closed) lives on `error.cause`, so surface it.
46
+ */
47
+ const describeNetworkError = (url, error) => {
48
+ const message = error instanceof Error ? error.message : 'network error';
49
+ const cause = error === null || error === void 0 ? void 0 : error.cause;
50
+ const detail = (cause === null || cause === void 0 ? void 0 : cause.code) || (cause === null || cause === void 0 ? void 0 : cause.message);
51
+ return `Could not reach the registry at ${url}: ${message}${detail ? ` (${detail})` : ''}.`;
52
+ };
53
+ const fetchRegistry = (url, init) => __awaiter(void 0, void 0, void 0, function* () {
54
+ try {
55
+ return yield fetch(url, init);
56
+ }
57
+ catch (error) {
58
+ throw new RegistryClientError(describeNetworkError(url, error));
59
+ }
60
+ });
61
+ const readEnvelope = (response) => __awaiter(void 0, void 0, void 0, function* () {
62
+ const text = yield response.text();
63
+ if (!text) {
64
+ return {};
65
+ }
66
+ try {
67
+ return JSON.parse(text);
68
+ }
69
+ catch (_a) {
70
+ return {};
71
+ }
72
+ });
73
+ const readErrorEnvelope = (response) => __awaiter(void 0, void 0, void 0, function* () {
74
+ try {
75
+ return yield readEnvelope(response);
76
+ }
77
+ catch (_a) {
78
+ return {};
79
+ }
80
+ });
81
+ /**
82
+ * Build a registry HTTP client bound to one connection. Methods reject with a
83
+ * {@link RegistryClientError} on transport failure, non-2xx responses, or an error envelope.
84
+ */
85
+ const createRegistryClient = ({ baseUrl, accessToken }) => {
86
+ const root = trimTrailingSlash(baseUrl);
87
+ const request = (method, path, body) => __awaiter(void 0, void 0, void 0, function* () {
88
+ var _a, _b, _c;
89
+ const url = `${root}${path}`;
90
+ const response = yield fetchRegistry(url, {
91
+ method,
92
+ headers: Object.assign({ 'Content-Type': 'application/json', Accept: 'application/json' }, (accessToken ? { Authorization: `Bearer ${accessToken}` } : {})),
93
+ body: body === undefined ? undefined : JSON.stringify(body),
94
+ });
95
+ const envelope = yield readEnvelope(response);
96
+ if (!response.ok || envelope.error) {
97
+ const code = (_a = envelope.error) === null || _a === void 0 ? void 0 : _a.code;
98
+ const message = ((_b = envelope.error) === null || _b === void 0 ? void 0 : _b.message) || `Registry request failed (${response.status} ${response.statusText}).`;
99
+ throw new RegistryClientError(message, { status: response.status, code, details: (_c = envelope.error) === null || _c === void 0 ? void 0 : _c.details });
100
+ }
101
+ return envelope;
102
+ });
103
+ return {
104
+ /** Publish (`PUT`) an entity's package to the registry transfer endpoint. */
105
+ publish(kind, id, pkg) {
106
+ return request('PUT', `/api/registry/transfer/${kind}/${encodeURIComponent(id)}`, pkg);
107
+ },
108
+ /** Checkout (`GET`) an entity's normalized record + registry-safe source files. */
109
+ checkout(kind, id) {
110
+ return __awaiter(this, void 0, void 0, function* () {
111
+ const envelope = yield request('GET', `/api/registry/transfer/${kind}/${encodeURIComponent(id)}`);
112
+ if (!envelope.data) {
113
+ throw new RegistryClientError(`The registry returned no data for ${kind} "${id}".`);
114
+ }
115
+ return envelope.data;
116
+ });
117
+ },
118
+ /** List the registry's token sets (id + kind + source hash) for skip-unchanged / bulk checkout. */
119
+ listTokenSets() {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ var _a, _b;
122
+ const envelope = yield request('GET', '/api/registry/transfer/tokens');
123
+ return (_b = (_a = envelope.data) === null || _a === void 0 ? void 0 : _a.sets) !== null && _b !== void 0 ? _b : [];
124
+ });
125
+ },
126
+ /** Publish (`PUT`) one token set's package (record + generated artifacts). */
127
+ publishTokens(pkg) {
128
+ return request('PUT', `/api/registry/transfer/tokens/${encodeSetIdPath(pkg.id)}`, pkg);
129
+ },
130
+ /** Checkout (`GET`) one token set's record + generated artifacts. */
131
+ checkoutTokens(id) {
132
+ return __awaiter(this, void 0, void 0, function* () {
133
+ const envelope = yield request('GET', `/api/registry/transfer/tokens/${encodeSetIdPath(id)}`);
134
+ if (!envelope.data) {
135
+ throw new RegistryClientError(`The registry returned no data for token set "${id}".`);
136
+ }
137
+ return envelope.data;
138
+ });
139
+ },
140
+ /** List the registry's asset collections (collection + source hash) for skip-unchanged / bulk checkout. */
141
+ listAssetCollections() {
142
+ return __awaiter(this, void 0, void 0, function* () {
143
+ var _a, _b;
144
+ const envelope = yield request('GET', '/api/registry/transfer/assets');
145
+ return (_b = (_a = envelope.data) === null || _a === void 0 ? void 0 : _a.collections) !== null && _b !== void 0 ? _b : [];
146
+ });
147
+ },
148
+ /** Ask which of the given content hashes the registry does not yet have (the blobs to upload). */
149
+ assetBlobHaveCheck(hashes) {
150
+ return __awaiter(this, void 0, void 0, function* () {
151
+ var _a, _b;
152
+ const envelope = yield request('POST', '/api/registry/transfer/assets/blobs/have', { hashes });
153
+ return (_b = (_a = envelope.data) === null || _a === void 0 ? void 0 : _a.missing) !== null && _b !== void 0 ? _b : [];
154
+ });
155
+ },
156
+ /** Upload one content-addressed blob (binary-safe body). Idempotent: re-uploading an existing hash no-ops. */
157
+ uploadAssetBlob(hash, contentType, bytes) {
158
+ return __awaiter(this, void 0, void 0, function* () {
159
+ var _a, _b;
160
+ const url = `${root}/api/registry/transfer/assets/blobs/${encodeURIComponent(hash)}`;
161
+ // Send a Blob, not a Buffer/Uint8Array: under Next `trailingSlash: true` this PUT is
162
+ // 308-redirected and undici must re-send the body; a typed-array body's ArrayBuffer is detached
163
+ // after the first send ("slice on a detached ArrayBuffer"), but a Blob is re-readable.
164
+ const body = new Blob([new Uint8Array(bytes)]);
165
+ const response = yield fetchRegistry(url, {
166
+ method: 'PUT',
167
+ headers: Object.assign({ 'Content-Type': contentType || 'application/octet-stream' }, (accessToken ? { Authorization: `Bearer ${accessToken}` } : {})),
168
+ body,
169
+ });
170
+ if (!response.ok) {
171
+ let code;
172
+ let message = `Blob upload failed (${response.status} ${response.statusText}).`;
173
+ const envelope = yield readErrorEnvelope(response);
174
+ code = (_a = envelope === null || envelope === void 0 ? void 0 : envelope.error) === null || _a === void 0 ? void 0 : _a.code;
175
+ message = ((_b = envelope === null || envelope === void 0 ? void 0 : envelope.error) === null || _b === void 0 ? void 0 : _b.message) || message;
176
+ throw new RegistryClientError(message, { status: response.status, code });
177
+ }
178
+ });
179
+ },
180
+ /** Download one blob's raw bytes by hash (follows any provider redirect). */
181
+ downloadAssetBlob(hash) {
182
+ return __awaiter(this, void 0, void 0, function* () {
183
+ const url = `${root}/api/registry/transfer/assets/blobs/${encodeURIComponent(hash)}`;
184
+ const response = yield fetchRegistry(url, {
185
+ headers: Object.assign({}, (accessToken ? { Authorization: `Bearer ${accessToken}` } : {})),
186
+ });
187
+ if (!response.ok) {
188
+ throw new RegistryClientError(`Blob download failed for "${hash}" (${response.status} ${response.statusText}).`, {
189
+ status: response.status,
190
+ });
191
+ }
192
+ return Buffer.from(yield response.arrayBuffer());
193
+ });
194
+ },
195
+ /** Publish (`PUT`) one asset collection's manifest (blobs must already be uploaded). */
196
+ publishAssetManifest(pkg) {
197
+ return request('PUT', `/api/registry/transfer/assets/${encodeURIComponent(pkg.collection)}`, pkg);
198
+ },
199
+ /** Checkout (`GET`) one asset collection's manifest. */
200
+ checkoutAssetCollection(collection) {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ const envelope = yield request('GET', `/api/registry/transfer/assets/${encodeURIComponent(collection)}`);
203
+ if (!envelope.data) {
204
+ throw new RegistryClientError(`The registry returned no data for asset collection "${collection}".`);
205
+ }
206
+ return envelope.data;
207
+ });
208
+ },
209
+ };
210
+ };
211
+ exports.createRegistryClient = createRegistryClient;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Connected-workspace registry connection resolution.
3
+ *
4
+ * A connected workspace is `runtime.mode: 'workspace'` plus a `runtime.registryConnection` block
5
+ * pointing at a remote registry — it is not a third runtime mode. The connection is resolved from
6
+ * config + environment: the registry URL may be given inline or via an env-var *name*, and the
7
+ * access token is always read from an env-var name (never persisted as a value). This is the single
8
+ * source the publish (and later checkout) client reads its target + credentials from.
9
+ */
10
+ import type { Config } from '../types/config';
11
+ /** Default env-var name holding the remote registry base URL. */
12
+ export declare const DEFAULT_REGISTRY_URL_ENV = "HANDOFF_REGISTRY_URL";
13
+ /** Default env-var name holding the connected-workspace access token. */
14
+ export declare const DEFAULT_REGISTRY_ACCESS_TOKEN_ENV = "HANDOFF_REGISTRY_ACCESS_TOKEN";
15
+ /** Fully resolved connected-workspace registry connection. */
16
+ export interface ResolvedRegistryConnection {
17
+ /** Resolved registry base URL (inline config value wins, else the named env var), or `''`. */
18
+ url: string;
19
+ /** Resolved access token value (from the named env var), or `''`. */
20
+ accessToken: string;
21
+ /** Name of the env var the URL falls back to. */
22
+ urlEnv: string;
23
+ /** Name of the env var the access token is read from. */
24
+ accessTokenEnv: string;
25
+ }
26
+ /**
27
+ * Resolve the connected-workspace registry connection from config + environment. Never throws —
28
+ * Callers inspect the resolved URL and access token to surface specific configuration errors.
29
+ */
30
+ export declare const resolveRegistryConnection: (config: Config | null | undefined) => ResolvedRegistryConnection;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * Connected-workspace registry connection resolution.
4
+ *
5
+ * A connected workspace is `runtime.mode: 'workspace'` plus a `runtime.registryConnection` block
6
+ * pointing at a remote registry — it is not a third runtime mode. The connection is resolved from
7
+ * config + environment: the registry URL may be given inline or via an env-var *name*, and the
8
+ * access token is always read from an env-var name (never persisted as a value). This is the single
9
+ * source the publish (and later checkout) client reads its target + credentials from.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.resolveRegistryConnection = exports.DEFAULT_REGISTRY_ACCESS_TOKEN_ENV = exports.DEFAULT_REGISTRY_URL_ENV = void 0;
13
+ /** Default env-var name holding the remote registry base URL. */
14
+ exports.DEFAULT_REGISTRY_URL_ENV = 'HANDOFF_REGISTRY_URL';
15
+ /** Default env-var name holding the connected-workspace access token. */
16
+ exports.DEFAULT_REGISTRY_ACCESS_TOKEN_ENV = 'HANDOFF_REGISTRY_ACCESS_TOKEN';
17
+ /**
18
+ * Resolve the connected-workspace registry connection from config + environment. Never throws —
19
+ * Callers inspect the resolved URL and access token to surface specific configuration errors.
20
+ */
21
+ const resolveRegistryConnection = (config) => {
22
+ var _a, _b, _c, _d, _e, _f, _g, _h;
23
+ const connection = (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.registryConnection;
24
+ const urlEnv = ((_b = connection === null || connection === void 0 ? void 0 : connection.urlEnv) === null || _b === void 0 ? void 0 : _b.trim()) || exports.DEFAULT_REGISTRY_URL_ENV;
25
+ const accessTokenEnv = ((_c = connection === null || connection === void 0 ? void 0 : connection.accessTokenEnv) === null || _c === void 0 ? void 0 : _c.trim()) || exports.DEFAULT_REGISTRY_ACCESS_TOKEN_ENV;
26
+ const inlineUrl = (_d = connection === null || connection === void 0 ? void 0 : connection.url) === null || _d === void 0 ? void 0 : _d.trim();
27
+ const url = (_f = (inlineUrl || ((_e = process.env[urlEnv]) === null || _e === void 0 ? void 0 : _e.trim()))) !== null && _f !== void 0 ? _f : '';
28
+ const accessToken = (_h = (_g = process.env[accessTokenEnv]) === null || _g === void 0 ? void 0 : _g.trim()) !== null && _h !== void 0 ? _h : '';
29
+ return {
30
+ url,
31
+ accessToken,
32
+ urlEnv,
33
+ accessTokenEnv,
34
+ };
35
+ };
36
+ exports.resolveRegistryConnection = resolveRegistryConnection;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Registry database adapter resolution.
3
+ *
4
+ * `runtime.registry.database.adapter` selects one of two built-in adapters shipped with the
5
+ * `handoff-app` package — `pg` (default) and `neon` — both targeting the Postgres dialect.
6
+ * `build --target registry` and `db:migrate` resolve the **same** adapter so build and migration
7
+ * never diverge. Connection credentials are referenced by environment-variable name only and
8
+ * resolved to a value at runtime; the value is never stored in config.
9
+ */
10
+ import type { Config } from '../../types/config';
11
+ /** Built-in registry database adapter. Both ship with the package and target Postgres. */
12
+ export type RegistryDatabaseAdapter = 'pg' | 'neon';
13
+ /** Default env-var name holding the database connection string. */
14
+ export declare const DEFAULT_DATABASE_URL_ENV = "DATABASE_URL";
15
+ /** Default env-var name holding the registry management API bearer token. */
16
+ export declare const DEFAULT_REGISTRY_API_TOKEN_ENV = "HANDOFF_REGISTRY_API_TOKEN";
17
+ /** Default registry database adapter when none is configured. */
18
+ export declare const DEFAULT_REGISTRY_ADAPTER: RegistryDatabaseAdapter;
19
+ /** Fully resolved registry database connection inputs. */
20
+ export interface ResolvedRegistryDatabase {
21
+ /** Selected built-in adapter. */
22
+ adapter: RegistryDatabaseAdapter;
23
+ /** Name of the env var the connection string was read from. */
24
+ databaseUrlEnv: string;
25
+ /** Resolved connection string (never persisted in config). */
26
+ connectionString: string;
27
+ }
28
+ /** Resolve the env-var name holding the database URL (defaults to `DATABASE_URL`). */
29
+ export declare const resolveDatabaseUrlEnv: (config: Config | null | undefined) => string;
30
+ /**
31
+ * Resolve the env-var *name* holding the registry management API bearer token (defaults to
32
+ * `HANDOFF_REGISTRY_API_TOKEN`). Like the database URL, only the name is ever persisted — the token
33
+ * value is resolved from the environment at request time and never written to config.
34
+ */
35
+ export declare const resolveApiTokenEnv: (config: Config | null | undefined) => string;
36
+ /** Resolve the configured registry adapter (defaults to `pg`). */
37
+ export declare const resolveRegistryAdapter: (config: Config | null | undefined) => RegistryDatabaseAdapter;
38
+ /**
39
+ * Resolve the registry database connection from config + environment. Throws an actionable error
40
+ * when the configured env var is unset so the CLI can surface a clear "missing database URL"
41
+ * message instead of failing deep inside the driver.
42
+ */
43
+ export declare const resolveRegistryDatabase: (config: Config | null | undefined) => ResolvedRegistryDatabase;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * Registry database adapter resolution.
4
+ *
5
+ * `runtime.registry.database.adapter` selects one of two built-in adapters shipped with the
6
+ * `handoff-app` package — `pg` (default) and `neon` — both targeting the Postgres dialect.
7
+ * `build --target registry` and `db:migrate` resolve the **same** adapter so build and migration
8
+ * never diverge. Connection credentials are referenced by environment-variable name only and
9
+ * resolved to a value at runtime; the value is never stored in config.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.resolveRegistryDatabase = exports.resolveRegistryAdapter = exports.resolveApiTokenEnv = exports.resolveDatabaseUrlEnv = exports.DEFAULT_REGISTRY_ADAPTER = exports.DEFAULT_REGISTRY_API_TOKEN_ENV = exports.DEFAULT_DATABASE_URL_ENV = void 0;
13
+ /** Default env-var name holding the database connection string. */
14
+ exports.DEFAULT_DATABASE_URL_ENV = 'DATABASE_URL';
15
+ /** Default env-var name holding the registry management API bearer token. */
16
+ exports.DEFAULT_REGISTRY_API_TOKEN_ENV = 'HANDOFF_REGISTRY_API_TOKEN';
17
+ /** Default registry database adapter when none is configured. */
18
+ exports.DEFAULT_REGISTRY_ADAPTER = 'pg';
19
+ /** Resolve the env-var name holding the database URL (defaults to `DATABASE_URL`). */
20
+ const resolveDatabaseUrlEnv = (config) => {
21
+ var _a, _b, _c;
22
+ const configured = (_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.registry) === null || _b === void 0 ? void 0 : _b.databaseUrlEnv) === null || _c === void 0 ? void 0 : _c.trim();
23
+ return configured || exports.DEFAULT_DATABASE_URL_ENV;
24
+ };
25
+ exports.resolveDatabaseUrlEnv = resolveDatabaseUrlEnv;
26
+ /**
27
+ * Resolve the env-var *name* holding the registry management API bearer token (defaults to
28
+ * `HANDOFF_REGISTRY_API_TOKEN`). Like the database URL, only the name is ever persisted — the token
29
+ * value is resolved from the environment at request time and never written to config.
30
+ */
31
+ const resolveApiTokenEnv = (config) => {
32
+ var _a, _b, _c;
33
+ const configured = (_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.registry) === null || _b === void 0 ? void 0 : _b.apiTokenEnv) === null || _c === void 0 ? void 0 : _c.trim();
34
+ return configured || exports.DEFAULT_REGISTRY_API_TOKEN_ENV;
35
+ };
36
+ exports.resolveApiTokenEnv = resolveApiTokenEnv;
37
+ /** Resolve the configured registry adapter (defaults to `pg`). */
38
+ const resolveRegistryAdapter = (config) => {
39
+ var _a, _b, _c, _d;
40
+ return (_d = (_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.registry) === null || _b === void 0 ? void 0 : _b.database) === null || _c === void 0 ? void 0 : _c.adapter) !== null && _d !== void 0 ? _d : exports.DEFAULT_REGISTRY_ADAPTER;
41
+ };
42
+ exports.resolveRegistryAdapter = resolveRegistryAdapter;
43
+ /**
44
+ * Resolve the registry database connection from config + environment. Throws an actionable error
45
+ * when the configured env var is unset so the CLI can surface a clear "missing database URL"
46
+ * message instead of failing deep inside the driver.
47
+ */
48
+ const resolveRegistryDatabase = (config) => {
49
+ var _a;
50
+ const adapter = (0, exports.resolveRegistryAdapter)(config);
51
+ const databaseUrlEnv = (0, exports.resolveDatabaseUrlEnv)(config);
52
+ const connectionString = (_a = process.env[databaseUrlEnv]) === null || _a === void 0 ? void 0 : _a.trim();
53
+ if (!connectionString) {
54
+ throw new Error(`Registry database URL is not configured. Set the "${databaseUrlEnv}" environment variable to a ` +
55
+ `PostgreSQL connection string (or change "runtime.registry.databaseUrlEnv" to point at the env var you use).`);
56
+ }
57
+ return { adapter, databaseUrlEnv, connectionString };
58
+ };
59
+ exports.resolveRegistryDatabase = resolveRegistryDatabase;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Bundled Drizzle client + migrator for the registry database.
3
+ *
4
+ * The package ships both built-in adapters (`pg` and `neon`) and the Drizzle client/migrator, so a
5
+ * consuming project needs no global Drizzle install or separate CLI. Driver modules are loaded
6
+ * lazily (dynamic import) for the selected adapter only, so workspace dev/build never pulls the
7
+ * Postgres/Neon drivers into memory when the registry is not in use.
8
+ */
9
+ import type { NeonDatabase } from 'drizzle-orm/neon-serverless';
10
+ import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
11
+ import type { RegistryDatabaseAdapter } from './adapter';
12
+ import * as schema from './schema';
13
+ /** Typed Drizzle database over the registry schema, regardless of which adapter backs it. */
14
+ export type RegistryDatabase = NodePgDatabase<typeof schema> | NeonDatabase<typeof schema>;
15
+ /** A live registry database connection plus its lifecycle operations. */
16
+ export interface RegistryDbConnection {
17
+ /** Selected adapter that produced this connection. */
18
+ adapter: RegistryDatabaseAdapter;
19
+ /** Typed Drizzle database. */
20
+ db: RegistryDatabase;
21
+ /** Apply the package-owned migrations found in `migrationsFolder`. */
22
+ migrate(migrationsFolder: string): Promise<void>;
23
+ /** Close the underlying connection pool. */
24
+ close(): Promise<void>;
25
+ }
26
+ export interface CreateRegistryDbConnectionParams {
27
+ adapter: RegistryDatabaseAdapter;
28
+ connectionString: string;
29
+ }
30
+ /**
31
+ * Create a registry database connection for the resolved adapter. Both adapters target the
32
+ * Postgres dialect and share the same schema, so the returned connection is interchangeable for
33
+ * migration and (later) the registry store.
34
+ */
35
+ export declare const createRegistryDbConnection: ({ adapter, connectionString, }: CreateRegistryDbConnectionParams) => Promise<RegistryDbConnection>;