handoff-app 1.2.2-7 → 2.0.0-1

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 (351) 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/paths.js +25 -1
  14. package/dist/app-builder/static-export.d.ts +17 -0
  15. package/dist/app-builder/static-export.js +206 -0
  16. package/dist/app-builder/vercel-output.d.ts +39 -0
  17. package/dist/app-builder/vercel-output.js +259 -0
  18. package/dist/app-builder/watchers/utils.d.ts +2 -0
  19. package/dist/app-builder/watchers.d.ts +14 -4
  20. package/dist/app-builder/watchers.js +123 -28
  21. package/dist/app-builder/websocket.js +1 -1
  22. package/dist/artifacts/index.d.ts +2 -0
  23. package/dist/artifacts/index.js +16 -0
  24. package/dist/artifacts/types.d.ts +136 -0
  25. package/dist/artifacts/types.js +24 -0
  26. package/dist/artifacts/url.d.ts +67 -0
  27. package/dist/artifacts/url.js +116 -0
  28. package/dist/cache/build-cache.js +48 -4
  29. package/dist/cli.js +0 -0
  30. package/dist/commands/build/app.js +1 -2
  31. package/dist/commands/build/index.d.ts +17 -0
  32. package/dist/commands/build/index.js +66 -0
  33. package/dist/commands/checkout/index.d.ts +24 -0
  34. package/dist/commands/checkout/index.js +71 -0
  35. package/dist/commands/db/migrate.d.ts +11 -0
  36. package/dist/commands/db/migrate.js +33 -0
  37. package/dist/commands/index.js +8 -0
  38. package/dist/commands/publish/index.d.ts +21 -0
  39. package/dist/commands/publish/index.js +68 -0
  40. package/dist/config/defaults.js +15 -1
  41. package/dist/config/loader.js +6 -1
  42. package/dist/config/normalizers/declaration.js +4 -1
  43. package/dist/config/normalizers/page.d.ts +18 -0
  44. package/dist/config/normalizers/page.js +34 -0
  45. package/dist/config/normalizers/pattern.js +7 -1
  46. package/dist/config/runtime.d.ts +4 -0
  47. package/dist/config/runtime.js +53 -5
  48. package/dist/index.d.ts +65 -1
  49. package/dist/index.js +123 -3
  50. package/dist/nav/index.d.ts +83 -0
  51. package/dist/nav/index.js +9 -0
  52. package/dist/nav/registry.d.ts +15 -0
  53. package/dist/nav/registry.js +42 -0
  54. package/dist/nav/resolver.d.ts +8 -0
  55. package/dist/nav/resolver.js +192 -0
  56. package/dist/nav/workspace.d.ts +18 -0
  57. package/dist/nav/workspace.js +103 -0
  58. package/dist/pipeline/styles.js +7 -35
  59. package/dist/pipeline/token-transformers.d.ts +45 -0
  60. package/dist/pipeline/token-transformers.js +71 -0
  61. package/dist/registry/asset-storage/adapters/vercel-blob.d.ts +17 -0
  62. package/dist/registry/asset-storage/adapters/vercel-blob.js +87 -0
  63. package/dist/registry/asset-storage/define.d.ts +10 -0
  64. package/dist/registry/asset-storage/define.js +13 -0
  65. package/dist/registry/asset-storage/resolve.d.ts +45 -0
  66. package/dist/registry/asset-storage/resolve.js +36 -0
  67. package/dist/registry/asset-storage/types.d.ts +51 -0
  68. package/dist/registry/asset-storage/types.js +9 -0
  69. package/dist/registry/assets/layout.d.ts +22 -0
  70. package/dist/registry/assets/layout.js +30 -0
  71. package/dist/registry/assets/sets.d.ts +18 -0
  72. package/dist/registry/assets/sets.js +44 -0
  73. package/dist/registry/assets/transfer.d.ts +45 -0
  74. package/dist/registry/assets/transfer.js +11 -0
  75. package/dist/registry/checkout/assets.d.ts +16 -0
  76. package/dist/registry/checkout/assets.js +150 -0
  77. package/dist/registry/checkout/index.d.ts +33 -0
  78. package/dist/registry/checkout/index.js +610 -0
  79. package/dist/registry/checkout/tokens.d.ts +15 -0
  80. package/dist/registry/checkout/tokens.js +171 -0
  81. package/dist/registry/client.d.ts +61 -0
  82. package/dist/registry/client.js +211 -0
  83. package/dist/registry/connection.d.ts +30 -0
  84. package/dist/registry/connection.js +36 -0
  85. package/dist/registry/db/adapter.d.ts +43 -0
  86. package/dist/registry/db/adapter.js +59 -0
  87. package/dist/registry/db/client.d.ts +35 -0
  88. package/dist/registry/db/client.js +94 -0
  89. package/dist/registry/db/index.d.ts +5 -0
  90. package/dist/registry/db/index.js +24 -0
  91. package/dist/registry/db/migrate.d.ts +23 -0
  92. package/dist/registry/db/migrate.js +64 -0
  93. package/dist/registry/db/schema.d.ts +4869 -0
  94. package/dist/registry/db/schema.js +347 -0
  95. package/dist/registry/path.d.ts +4 -0
  96. package/dist/registry/path.js +31 -0
  97. package/dist/registry/publish/artifacts.d.ts +16 -0
  98. package/dist/registry/publish/artifacts.js +132 -0
  99. package/dist/registry/publish/assets.d.ts +16 -0
  100. package/dist/registry/publish/assets.js +129 -0
  101. package/dist/registry/publish/errors.d.ts +5 -0
  102. package/dist/registry/publish/errors.js +26 -0
  103. package/dist/registry/publish/index.d.ts +27 -0
  104. package/dist/registry/publish/index.js +126 -0
  105. package/dist/registry/publish/package.d.ts +27 -0
  106. package/dist/registry/publish/package.js +257 -0
  107. package/dist/registry/publish/publish-build.d.ts +12 -0
  108. package/dist/registry/publish/publish-build.js +43 -0
  109. package/dist/registry/publish/tokens.d.ts +18 -0
  110. package/dist/registry/publish/tokens.js +112 -0
  111. package/dist/registry/tokens/sets.d.ts +59 -0
  112. package/dist/registry/tokens/sets.js +109 -0
  113. package/dist/registry/tokens/transfer.d.ts +48 -0
  114. package/dist/registry/tokens/transfer.js +10 -0
  115. package/dist/registry/transfer.d.ts +75 -0
  116. package/dist/registry/transfer.js +11 -0
  117. package/dist/store/filesystem-assets.d.ts +17 -0
  118. package/dist/store/filesystem-assets.js +147 -0
  119. package/dist/store/filesystem.d.ts +76 -0
  120. package/dist/store/filesystem.js +208 -0
  121. package/dist/store/index.d.ts +20 -0
  122. package/dist/store/index.js +38 -0
  123. package/dist/store/registry.d.ts +77 -0
  124. package/dist/store/registry.js +350 -0
  125. package/dist/store/source-files.d.ts +24 -0
  126. package/dist/store/source-files.js +147 -0
  127. package/dist/store/types.d.ts +185 -0
  128. package/dist/store/types.js +12 -0
  129. package/dist/transformers/plugins/csf-render.js +17 -8
  130. package/dist/transformers/plugins/handlebars-previews.js +10 -3
  131. package/dist/transformers/plugins/ssr-render.js +116 -49
  132. package/dist/transformers/preview/component/api.js +3 -1
  133. package/dist/transformers/preview/component/artifacts.js +8 -1
  134. package/dist/transformers/preview/component/builder.js +13 -5
  135. package/dist/transformers/preview/component/css.js +9 -1
  136. package/dist/transformers/preview/component/javascript.d.ts +9 -3
  137. package/dist/transformers/preview/component/javascript.js +45 -17
  138. package/dist/transformers/preview/component/shared-artifacts.d.ts +83 -0
  139. package/dist/transformers/preview/component/shared-artifacts.js +92 -0
  140. package/dist/transformers/preview/component.js +5 -2
  141. package/dist/transformers/preview/pattern/builder.js +28 -9
  142. package/dist/transformers/preview/pattern/html.d.ts +13 -10
  143. package/dist/transformers/preview/pattern/html.js +62 -27
  144. package/dist/transformers/preview/types.d.ts +38 -0
  145. package/dist/transformers/utils/handlebars.d.ts +3 -0
  146. package/dist/transformers/utils/handlebars.js +19 -5
  147. package/dist/types/config.d.ts +124 -31
  148. package/dist/utils/menu-shell.d.ts +60 -0
  149. package/dist/utils/menu-shell.js +221 -0
  150. package/dist/utils/stable-stringify.d.ts +2 -0
  151. package/dist/utils/stable-stringify.js +8 -0
  152. package/docs/cli.md +4 -2
  153. package/drizzle/0000_init_registry_storage.sql +95 -0
  154. package/drizzle/0001_add_review_metadata.sql +2 -0
  155. package/drizzle/0002_add_pages.sql +28 -0
  156. package/drizzle/0003_add_tokens.sql +29 -0
  157. package/drizzle/0004_add_assets.sql +37 -0
  158. package/drizzle/meta/0000_snapshot.json +642 -0
  159. package/drizzle/meta/0001_snapshot.json +654 -0
  160. package/drizzle/meta/0002_snapshot.json +835 -0
  161. package/drizzle/meta/0003_snapshot.json +1023 -0
  162. package/drizzle/meta/0004_snapshot.json +1252 -0
  163. package/drizzle/meta/_journal.json +41 -0
  164. package/drizzle.config.ts +16 -0
  165. package/package.json +10 -1
  166. package/src/app/components/Component/Preview.tsx +3 -2
  167. package/src/app/components/Component/RegistryActions.tsx +150 -0
  168. package/src/app/components/Foundations/DisplayLogo.tsx +11 -3
  169. package/src/app/components/Layout/Header.tsx +21 -3
  170. package/src/app/components/Layout/Main.tsx +11 -3
  171. package/src/app/components/Navigation/MainNav.tsx +4 -2
  172. package/src/app/components/Navigation/MobileNav.tsx +4 -2
  173. package/src/app/components/Navigation/SideNav.tsx +46 -11
  174. package/src/app/components/NotFound.tsx +24 -0
  175. package/src/app/components/context/NavProvider.tsx +71 -0
  176. package/src/app/components/old/Header.tsx +3 -3
  177. package/src/app/components/util/index.ts +203 -380
  178. package/src/app/components/util/useCollectionAssets.ts +125 -0
  179. package/src/app/components/util/useFoundationTokens.ts +67 -0
  180. package/src/app/generated/default-pages.json +1 -0
  181. package/src/app/generated/nav-shell.json +1 -0
  182. package/src/app/lib/api/query.ts +6 -0
  183. package/src/app/lib/api/redact.ts +46 -0
  184. package/src/app/lib/asset-storage.ts +81 -0
  185. package/src/app/lib/docs-api/artifacts.ts +116 -0
  186. package/src/app/lib/docs-api/backend.ts +151 -0
  187. package/src/app/lib/docs-api/errors.ts +52 -0
  188. package/src/app/lib/docs-api/handler.ts +34 -0
  189. package/src/app/lib/docs-api/index.ts +7 -0
  190. package/src/app/lib/docs-api/records.ts +189 -0
  191. package/src/app/lib/docs-api/registry.ts +130 -0
  192. package/src/app/lib/docs-api/runtime-config.ts +173 -0
  193. package/src/app/lib/docs-api/serve.ts +37 -0
  194. package/src/app/lib/docs-api/token-detail.ts +19 -0
  195. package/src/app/lib/registry-api/allowlist.ts +163 -0
  196. package/src/app/lib/registry-api/asset-transfer.ts +363 -0
  197. package/src/app/lib/registry-api/auth.ts +68 -0
  198. package/src/app/lib/registry-api/entity-routes.ts +197 -0
  199. package/src/app/lib/registry-api/errors.ts +51 -0
  200. package/src/app/lib/registry-api/files.ts +135 -0
  201. package/src/app/lib/registry-api/handler.ts +96 -0
  202. package/src/app/lib/registry-api/index.ts +4 -0
  203. package/src/app/lib/registry-api/meta.ts +87 -0
  204. package/src/app/lib/registry-api/revalidate.ts +36 -0
  205. package/src/app/lib/registry-api/store.ts +348 -0
  206. package/src/app/lib/registry-api/token-transfer.ts +231 -0
  207. package/src/app/lib/registry-api/transfer.ts +513 -0
  208. package/src/app/lib/registry-api/validation.ts +74 -0
  209. package/src/app/lib/registry-connection.ts +58 -0
  210. package/src/app/lib/utils.ts +14 -0
  211. package/src/app/next.config.mjs +72 -13
  212. package/src/app/pages/[...slug]/index.tsx +74 -20
  213. package/src/app/pages/_app.tsx +5 -2
  214. package/src/app/pages/api/docs/artifacts/[...artifactPath].ts +16 -0
  215. package/src/app/pages/api/docs/assets/[collection]/[...path].ts +50 -0
  216. package/src/app/pages/api/docs/assets/[collection]/index.ts +22 -0
  217. package/src/app/pages/api/docs/components/[id]/assets/[asset].ts +33 -0
  218. package/src/app/pages/api/docs/components/[id]/inspect/[previewId].ts +20 -0
  219. package/src/app/pages/api/docs/components/[id]/previews/[previewId].ts +21 -0
  220. package/src/app/pages/api/docs/components/[id].ts +24 -0
  221. package/src/app/pages/api/docs/components.json.ts +12 -0
  222. package/src/app/pages/api/docs/nav.json.ts +48 -0
  223. package/src/app/pages/api/docs/patterns/[id]/preview.ts +19 -0
  224. package/src/app/pages/api/docs/patterns/[id].ts +24 -0
  225. package/src/app/pages/api/docs/patterns.json.ts +12 -0
  226. package/src/app/pages/api/docs/tokens/components/[id].ts +30 -0
  227. package/src/app/pages/api/docs/tokens/foundations/[type].ts +32 -0
  228. package/src/app/pages/api/registry/components/[id]/files/[...filePath].ts +19 -0
  229. package/src/app/pages/api/registry/components/[id]/files/index.ts +19 -0
  230. package/src/app/pages/api/registry/components/[id].ts +20 -0
  231. package/src/app/pages/api/registry/components/index.ts +19 -0
  232. package/src/app/pages/api/registry/health.ts +20 -0
  233. package/src/app/pages/api/registry/patterns/[id]/files/[...filePath].ts +19 -0
  234. package/src/app/pages/api/registry/patterns/[id]/files/index.ts +19 -0
  235. package/src/app/pages/api/registry/patterns/[id].ts +20 -0
  236. package/src/app/pages/api/registry/patterns/index.ts +19 -0
  237. package/src/app/pages/api/registry/transfer/[kind]/[id].ts +39 -0
  238. package/src/app/pages/api/registry/transfer/assets/[collection].ts +24 -0
  239. package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +23 -0
  240. package/src/app/pages/api/registry/transfer/assets/blobs/have.ts +11 -0
  241. package/src/app/pages/api/registry/transfer/assets/index.ts +10 -0
  242. package/src/app/pages/api/registry/transfer/tokens/[...setId].ts +26 -0
  243. package/src/app/pages/api/registry/transfer/tokens/index.ts +11 -0
  244. package/src/app/pages/assets/fonts.tsx +41 -17
  245. package/src/app/pages/assets/index.tsx +2 -2
  246. package/src/app/pages/assets/logos.tsx +6 -3
  247. package/src/app/pages/foundations/colors.tsx +18 -8
  248. package/src/app/pages/foundations/effects.tsx +18 -8
  249. package/src/app/pages/foundations/icons/[name]/index.tsx +28 -16
  250. package/src/app/pages/foundations/icons/index.tsx +18 -12
  251. package/src/app/pages/foundations/index.tsx +1 -1
  252. package/src/app/pages/foundations/logo.tsx +12 -8
  253. package/src/app/pages/foundations/typography.tsx +19 -9
  254. package/src/app/pages/index.tsx +1 -1
  255. package/src/app/pages/system/component/[component]/index.tsx +87 -17
  256. package/src/app/pages/system/index.tsx +13 -4
  257. package/src/app/pages/system/pattern/[pattern]/index.tsx +70 -14
  258. package/src/app/pages/system/tokens/components/[component]/index.tsx +42 -14
  259. package/src/app/pages/system/tokens/foundations/colors.tsx +7 -5
  260. package/src/app/pages/system/tokens/foundations/effects.tsx +7 -5
  261. package/src/app/pages/system/tokens/foundations/typography.tsx +8 -4
  262. package/src/app/tsconfig.json +2 -3
  263. package/src/app-builder/build.ts +555 -11
  264. package/src/app-builder/client-config.ts +61 -4
  265. package/src/app-builder/config-diff/snapshot.ts +1 -11
  266. package/src/app-builder/index.ts +1 -1
  267. package/src/app-builder/nav-shell.ts +74 -0
  268. package/src/app-builder/paths.ts +27 -1
  269. package/src/app-builder/static-export.ts +242 -0
  270. package/src/app-builder/vercel-output.ts +297 -0
  271. package/src/app-builder/watchers/utils.ts +2 -0
  272. package/src/app-builder/watchers.ts +149 -25
  273. package/src/app-builder/websocket.ts +2 -2
  274. package/src/artifacts/README.md +14 -0
  275. package/src/artifacts/index.ts +24 -0
  276. package/src/artifacts/types.ts +146 -0
  277. package/src/artifacts/url.ts +122 -0
  278. package/src/cache/build-cache.ts +47 -2
  279. package/src/commands/build/app.ts +1 -2
  280. package/src/commands/build/index.ts +61 -0
  281. package/src/commands/checkout/index.ts +66 -0
  282. package/src/commands/db/migrate.ts +25 -0
  283. package/src/commands/index.ts +8 -0
  284. package/src/commands/publish/index.ts +63 -0
  285. package/src/config/defaults.ts +15 -0
  286. package/src/config/loader.ts +10 -1
  287. package/src/config/normalizers/declaration.ts +3 -0
  288. package/src/config/normalizers/page.ts +45 -0
  289. package/src/config/normalizers/pattern.ts +4 -1
  290. package/src/config/runtime.ts +48 -2
  291. package/src/index.ts +126 -3
  292. package/src/nav/index.ts +94 -0
  293. package/src/nav/registry.ts +54 -0
  294. package/src/nav/resolver.ts +217 -0
  295. package/src/nav/workspace.ts +87 -0
  296. package/src/pipeline/styles.ts +4 -35
  297. package/src/pipeline/token-transformers.ts +97 -0
  298. package/src/registry/asset-storage/adapters/vercel-blob.ts +51 -0
  299. package/src/registry/asset-storage/define.ts +15 -0
  300. package/src/registry/asset-storage/resolve.ts +72 -0
  301. package/src/registry/asset-storage/types.ts +46 -0
  302. package/src/registry/assets/layout.ts +38 -0
  303. package/src/registry/assets/sets.ts +48 -0
  304. package/src/registry/assets/transfer.ts +50 -0
  305. package/src/registry/checkout/assets.ts +126 -0
  306. package/src/registry/checkout/index.ts +596 -0
  307. package/src/registry/checkout/tokens.ts +152 -0
  308. package/src/registry/client.ts +234 -0
  309. package/src/registry/connection.ts +50 -0
  310. package/src/registry/db/adapter.ts +74 -0
  311. package/src/registry/db/client.ts +88 -0
  312. package/src/registry/db/index.ts +35 -0
  313. package/src/registry/db/migrate.ts +56 -0
  314. package/src/registry/db/schema.ts +444 -0
  315. package/src/registry/path.ts +26 -0
  316. package/src/registry/publish/artifacts.ts +147 -0
  317. package/src/registry/publish/assets.ts +129 -0
  318. package/src/registry/publish/errors.ts +34 -0
  319. package/src/registry/publish/index.ts +128 -0
  320. package/src/registry/publish/package.ts +272 -0
  321. package/src/registry/publish/publish-build.ts +51 -0
  322. package/src/registry/publish/tokens.ts +119 -0
  323. package/src/registry/tokens/sets.ts +132 -0
  324. package/src/registry/tokens/transfer.ts +53 -0
  325. package/src/registry/transfer.ts +82 -0
  326. package/src/store/filesystem-assets.ts +152 -0
  327. package/src/store/filesystem.ts +237 -0
  328. package/src/store/index.ts +62 -0
  329. package/src/store/registry.ts +334 -0
  330. package/src/store/source-files.ts +155 -0
  331. package/src/store/types.ts +210 -0
  332. package/src/transformers/plugins/csf-render.ts +31 -7
  333. package/src/transformers/plugins/handlebars-previews.ts +22 -3
  334. package/src/transformers/plugins/ssr-render.ts +145 -57
  335. package/src/transformers/preview/component/api.ts +2 -1
  336. package/src/transformers/preview/component/artifacts.ts +10 -1
  337. package/src/transformers/preview/component/builder.ts +9 -2
  338. package/src/transformers/preview/component/css.ts +10 -1
  339. package/src/transformers/preview/component/javascript.ts +55 -20
  340. package/src/transformers/preview/component/shared-artifacts.ts +146 -0
  341. package/src/transformers/preview/component.ts +5 -2
  342. package/src/transformers/preview/pattern/builder.ts +33 -7
  343. package/src/transformers/preview/pattern/html.ts +71 -27
  344. package/src/transformers/preview/types.ts +42 -0
  345. package/src/transformers/utils/handlebars.ts +31 -5
  346. package/src/types/config.ts +129 -31
  347. package/src/utils/menu-shell.ts +241 -0
  348. package/src/utils/stable-stringify.ts +7 -0
  349. package/templates/default/package.json.tpl +1 -1
  350. package/handoff.config.js +0 -90
  351. package/src/app/components/ComponentSearch.tsx +0 -93
@@ -0,0 +1,610 @@
1
+ "use strict";
2
+ /**
3
+ * Connected-workspace checkout orchestration.
4
+ *
5
+ * `checkout <component|pattern> <id>` reads a normalized registry record and its registry-safe
6
+ * source files from the connected registry through the shared registry client, then writes them
7
+ * into the local workspace in standard authoring form. The local **declaration is synthesized
8
+ * locally** in the configured `runtime.workspace.declarationFormat` — declarations are never read
9
+ * from the registry (they are workspace-only). Identity is matched by stable `id`, so a checked-out
10
+ * entity maps to the correct logical component/pattern and can be re-authored and re-published.
11
+ *
12
+ * Available only from a connected workspace (`runtime.mode: workspace` + a configured
13
+ * `registryConnection`). Overwriting existing local files is explicit: a `--force` flag or an
14
+ * interactive confirmation.
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
40
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
41
+ return new (P || (P = Promise))(function (resolve, reject) {
42
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
43
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
44
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
45
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
46
+ });
47
+ };
48
+ var __rest = (this && this.__rest) || function (s, e) {
49
+ var t = {};
50
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
51
+ t[p] = s[p];
52
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
53
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
54
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
55
+ t[p[i]] = s[p[i]];
56
+ }
57
+ return t;
58
+ };
59
+ var __importDefault = (this && this.__importDefault) || function (mod) {
60
+ return (mod && mod.__esModule) ? mod : { "default": mod };
61
+ };
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.checkoutEntity = exports.resolveConnectionOrThrow = exports.CheckoutError = void 0;
64
+ const p = __importStar(require("@clack/prompts"));
65
+ const fs_extra_1 = __importDefault(require("fs-extra"));
66
+ const path_1 = __importDefault(require("path"));
67
+ const runtime_1 = require("../../config/runtime");
68
+ const logger_1 = require("../../utils/logger");
69
+ const client_1 = require("../client");
70
+ const connection_1 = require("../connection");
71
+ const path_2 = require("../path");
72
+ /** A connected-workspace configuration or precondition failure surfaced to the CLI. */
73
+ class CheckoutError extends Error {
74
+ constructor(message) {
75
+ super(message);
76
+ this.name = 'CheckoutError';
77
+ }
78
+ }
79
+ exports.CheckoutError = CheckoutError;
80
+ /** Default authoring format synthesized when no existing file or configured preference applies. */
81
+ const DEFAULT_DECLARATION_FORMAT = 'ts';
82
+ /** Default workspace subdirectory an entity is written into when none is configured. */
83
+ const DEFAULT_ENTITY_DIR = {
84
+ component: 'components',
85
+ pattern: 'patterns',
86
+ page: 'pages',
87
+ };
88
+ /** Source-file extensions stripped to form a module specifier for a React component import. */
89
+ const COMPONENT_EXTENSION = /\.(tsx|jsx|ts|js|cjs|mjs)$/i;
90
+ /**
91
+ * Ensure the workspace is a connected workspace able to checkout: workspace runtime mode (a registry
92
+ * host has no local workspace to write into) and a resolved registry URL + access token. Throws an
93
+ * actionable {@link CheckoutError} naming the exact misconfiguration.
94
+ */
95
+ const resolveConnectionOrThrow = (handoff) => {
96
+ var _a, _b, _c;
97
+ const mode = (_c = (_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.runtime) === null || _b === void 0 ? void 0 : _b.mode) !== null && _c !== void 0 ? _c : 'workspace';
98
+ if (mode !== 'workspace') {
99
+ throw new CheckoutError(`checkout is only available from a connected workspace (runtime.mode: "workspace"); this project is "${mode}". ` +
100
+ 'A registry host stores and serves entities; it has no local workspace to check them out into.');
101
+ }
102
+ const connection = (0, connection_1.resolveRegistryConnection)(handoff.config);
103
+ if (!connection.url) {
104
+ throw new CheckoutError(`No registry URL is configured. Set runtime.registryConnection.url, or the "${connection.urlEnv}" environment variable, ` +
105
+ 'to the base URL of the registry to checkout from.');
106
+ }
107
+ if (!connection.accessToken) {
108
+ throw new CheckoutError(`No registry access token is configured. Set the "${connection.accessTokenEnv}" environment variable to the ` +
109
+ "registry's bearer token to authorize checkout.");
110
+ }
111
+ return connection;
112
+ };
113
+ exports.resolveConnectionOrThrow = resolveConnectionOrThrow;
114
+ /** Map a registry client error to an actionable checkout message. */
115
+ const describeFetchFailure = (error, kind, id, registryUrl) => {
116
+ switch (error.code) {
117
+ case 'not_found':
118
+ return `No ${kind} "${id}" exists in the registry at ${registryUrl}.`;
119
+ case 'runtime_mode_conflict':
120
+ return `The registry at ${registryUrl} is not running in registry mode, so it cannot serve a checkout: ${error.message}`;
121
+ case 'unauthorized':
122
+ return `The registry rejected the access token (401). Check the configured access token matches the registry's token.`;
123
+ default:
124
+ return error.message;
125
+ }
126
+ };
127
+ /**
128
+ * Resolve the local directory the entity is written into: an already-checked-out / locally-declared
129
+ * entity keeps its existing source directory (matched by stable `id`); otherwise it lands under the
130
+ * first configured `entries.{components|patterns}` root (falling back to `components`/`patterns`).
131
+ */
132
+ const resolveTargetDir = (handoff, kind, id) => __awaiter(void 0, void 0, void 0, function* () {
133
+ var _a, _b, _c, _d;
134
+ const store = kind === 'component' ? handoff.store.components : handoff.store.patterns;
135
+ const existing = yield store.get(id);
136
+ const existingDir = existing === null || existing === void 0 ? void 0 : existing.path;
137
+ if (existingDir) {
138
+ return existingDir;
139
+ }
140
+ const configuredRoots = kind === 'component' ? (_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.components : (_d = (_c = handoff.config) === null || _c === void 0 ? void 0 : _c.entries) === null || _d === void 0 ? void 0 : _d.patterns;
141
+ const root = (configuredRoots === null || configuredRoots === void 0 ? void 0 : configuredRoots.length)
142
+ ? path_1.default.resolve(handoff.workingPath, configuredRoots[0])
143
+ : path_1.default.resolve(handoff.workingPath, DEFAULT_ENTITY_DIR[kind]);
144
+ const targetDir = (0, path_2.resolvePathWithin)(root, id);
145
+ if (!targetDir) {
146
+ throw new CheckoutError(`Cannot checkout ${kind} with unsafe id "${id}".`);
147
+ }
148
+ return targetDir;
149
+ });
150
+ /** Read the extension of an existing local declaration in `dir`, if any maps to a known format. */
151
+ const existingDeclarationFormat = (dir) => {
152
+ if (!fs_extra_1.default.existsSync(dir)) {
153
+ return undefined;
154
+ }
155
+ const declaration = (0, runtime_1.resolveComponentDeclaration)(dir, path_1.default.basename(dir));
156
+ if (!declaration) {
157
+ return undefined;
158
+ }
159
+ const ext = path_1.default.extname(declaration.fileName).slice(1).toLowerCase();
160
+ return ['ts', 'js', 'cjs', 'json'].includes(ext) ? ext : undefined;
161
+ };
162
+ /**
163
+ * Resolve the declaration format: an existing local declaration's extension wins, else the
164
+ * configured `runtime.workspace.declarationFormat`, else {@link DEFAULT_DECLARATION_FORMAT}.
165
+ */
166
+ const resolveDeclarationFormat = (handoff, dir) => {
167
+ var _a, _b, _c, _d, _e;
168
+ const configured = (_c = (_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.runtime) === null || _b === void 0 ? void 0 : _b.workspace) === null || _c === void 0 ? void 0 : _c.declarationFormat;
169
+ return (_e = (_d = existingDeclarationFormat(dir)) !== null && _d !== void 0 ? _d : configured) !== null && _e !== void 0 ? _e : DEFAULT_DECLARATION_FORMAT;
170
+ };
171
+ /** The declaration filename to write: reuse an existing local declaration, else `<id>.handoff.<format>`. */
172
+ const resolveDeclarationFileName = (dir, id, format) => {
173
+ if (fs_extra_1.default.existsSync(dir)) {
174
+ const existing = (0, runtime_1.resolveComponentDeclaration)(dir, path_1.default.basename(dir));
175
+ if (existing) {
176
+ return existing.fileName;
177
+ }
178
+ }
179
+ return `${id}.handoff.${format}`;
180
+ };
181
+ const isPlainObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
182
+ /**
183
+ * The single authored "primary" entry key per renderer. The normalizer derives the others (e.g. it
184
+ * mirrors a React `component` into `template`, and a CSF `story` into `template`), so the stored
185
+ * record carries duplicates that must not be re-authored. React authors `component`; handlebars and
186
+ * CSF author `template` (a `.stories.*` template is what marks a CSF component).
187
+ */
188
+ const PRIMARY_ENTRY_BY_RENDERER = {
189
+ react: 'component',
190
+ handlebars: 'template',
191
+ csf: 'template',
192
+ };
193
+ /** Primary entry keys, in preference order, for an unknown renderer. */
194
+ const PRIMARY_ENTRY_KEYS = ['component', 'template', 'story'];
195
+ /** Supporting entry keys kept verbatim regardless of renderer. */
196
+ const SUPPORTING_ENTRY_KEYS = ['js', 'scss', 'schema', 'templates'];
197
+ const asString = (value) => (typeof value === 'string' && value ? value : undefined);
198
+ const asStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === 'string') ? value : undefined;
199
+ /**
200
+ * Rebuild the authored `entries` for a renderer: keep only the renderer's primary entry key (so the
201
+ * normalizer-duplicated keys are dropped) plus the supporting source entries (`js`/`scss`/`schema`/
202
+ * `templates`). An unknown renderer keeps the first available primary key by preference order.
203
+ */
204
+ const buildEntries = (entries, renderer) => {
205
+ if (!isPlainObject(entries)) {
206
+ return undefined;
207
+ }
208
+ const result = {};
209
+ const primaryKey = renderer ? PRIMARY_ENTRY_BY_RENDERER[renderer] : undefined;
210
+ if (primaryKey && typeof entries[primaryKey] === 'string') {
211
+ result[primaryKey] = entries[primaryKey];
212
+ }
213
+ else if (!primaryKey) {
214
+ const fallback = PRIMARY_ENTRY_KEYS.find((key) => typeof entries[key] === 'string');
215
+ if (fallback) {
216
+ result[fallback] = entries[fallback];
217
+ }
218
+ }
219
+ for (const key of SUPPORTING_ENTRY_KEYS) {
220
+ if (entries[key] !== undefined) {
221
+ result[key] = entries[key];
222
+ }
223
+ }
224
+ return Object.keys(result).length > 0 ? result : undefined;
225
+ };
226
+ /**
227
+ * Rebuild the authored `previews` map (`DeclarationPreview`) from the stored previews, keeping only
228
+ * authored fields (`title`, `args`) and dropping build-derived ones (rendered `url`, `usage`,
229
+ * `sourcePreview`). The component normalizer maps authored `args` to `values`, so the stored record
230
+ * carries `values`; checkout re-emits it as `args` to match the authoring convention (the form
231
+ * `make`/`scaffold` generate). Both rebuild identically.
232
+ */
233
+ const buildPreviews = (previews) => {
234
+ if (!isPlainObject(previews)) {
235
+ return undefined;
236
+ }
237
+ const result = {};
238
+ for (const [key, raw] of Object.entries(previews)) {
239
+ if (!isPlainObject(raw)) {
240
+ continue;
241
+ }
242
+ const preview = {};
243
+ if (typeof raw.title === 'string')
244
+ preview.title = raw.title;
245
+ const args = raw.args !== undefined ? raw.args : raw.values;
246
+ if (args !== undefined)
247
+ preview.args = args;
248
+ result[key] = preview;
249
+ }
250
+ return Object.keys(result).length > 0 ? result : undefined;
251
+ };
252
+ /**
253
+ * Synthesize an authored component declaration (`GenericDeclarationConfig`) from the normalized
254
+ * record. Only authored fields are kept; registry-/build-derived data (`path`, `image`,
255
+ * `properties`/docgen, rendered preview URLs, `internalPatternPreviews`, `validations`, `variant`,
256
+ * review `metadata`) is dropped so the local build regenerates it. `name` carries the record title
257
+ * (the authored contract uses `name`; normalization maps it back to `title`); `shouldDo`/
258
+ * `shouldNotDo` are emitted in their camelCase authored form.
259
+ */
260
+ const buildComponentDeclaration = (item) => {
261
+ var _a, _b, _c, _d, _e;
262
+ const declaration = {};
263
+ const id = asString(item.id);
264
+ if (id)
265
+ declaration.id = id;
266
+ declaration.name = (_c = (_b = (_a = asString(item.title)) !== null && _a !== void 0 ? _a : asString(item.name)) !== null && _b !== void 0 ? _b : id) !== null && _c !== void 0 ? _c : '';
267
+ const description = asString(item.description);
268
+ if (description)
269
+ declaration.description = description;
270
+ const group = asString(item.group);
271
+ if (group)
272
+ declaration.group = group;
273
+ const type = asString(item.type);
274
+ if (type)
275
+ declaration.type = type;
276
+ const renderer = asString(item.renderer);
277
+ if (renderer)
278
+ declaration.renderer = renderer;
279
+ const entries = buildEntries(item.entries, renderer);
280
+ if (entries)
281
+ declaration.entries = entries;
282
+ const previews = buildPreviews(item.previews);
283
+ if (previews)
284
+ declaration.previews = previews;
285
+ const categories = asStringArray(item.categories);
286
+ if (categories)
287
+ declaration.categories = categories;
288
+ const tags = asStringArray(item.tags);
289
+ if (tags)
290
+ declaration.tags = tags;
291
+ const shouldDo = (_d = asStringArray(item.shouldDo)) !== null && _d !== void 0 ? _d : asStringArray(item.should_do);
292
+ if (shouldDo)
293
+ declaration.shouldDo = shouldDo;
294
+ const shouldNotDo = (_e = asStringArray(item.shouldNotDo)) !== null && _e !== void 0 ? _e : asStringArray(item.should_not_do);
295
+ if (shouldNotDo)
296
+ declaration.shouldNotDo = shouldNotDo;
297
+ const figma = asString(item.figma);
298
+ if (figma)
299
+ declaration.figma = figma;
300
+ const figmaComponentId = asString(item.figmaComponentId);
301
+ if (figmaComponentId)
302
+ declaration.figmaComponentId = figmaComponentId;
303
+ if (isPlainObject(item.page))
304
+ declaration.page = item.page;
305
+ if (isPlainObject(item.options))
306
+ declaration.options = item.options;
307
+ return declaration;
308
+ };
309
+ /**
310
+ * Rebuild the authored pattern component refs (`PatternComponentRef`) from the stored entries,
311
+ * keeping only `id`/`preview`/`args` and dropping build-time resolution fields (`resolvedPreview`,
312
+ * `resolved`).
313
+ */
314
+ const buildPatternComponents = (components) => {
315
+ if (!Array.isArray(components)) {
316
+ return [];
317
+ }
318
+ return components.filter(isPlainObject).map((entry) => {
319
+ const ref = {};
320
+ const id = asString(entry.id);
321
+ if (id)
322
+ ref.id = id;
323
+ const preview = asString(entry.preview);
324
+ if (preview)
325
+ ref.preview = preview;
326
+ if (isPlainObject(entry.args))
327
+ ref.args = entry.args;
328
+ return ref;
329
+ });
330
+ };
331
+ /**
332
+ * Synthesize an authored pattern declaration (`GenericPatternDeclarationConfig`) from the normalized
333
+ * record. Only the authored fields (`id`, `name`, `description`, `group`, `tags`, `components`) are
334
+ * kept; derived fields (`path`, rendered `url`, review `metadata`) are dropped.
335
+ */
336
+ const buildPatternDeclaration = (item) => {
337
+ var _a, _b, _c;
338
+ const declaration = {};
339
+ const id = asString(item.id);
340
+ if (id)
341
+ declaration.id = id;
342
+ declaration.name = (_c = (_b = (_a = asString(item.title)) !== null && _a !== void 0 ? _a : asString(item.name)) !== null && _b !== void 0 ? _b : id) !== null && _c !== void 0 ? _c : '';
343
+ const description = asString(item.description);
344
+ if (description)
345
+ declaration.description = description;
346
+ const group = asString(item.group);
347
+ if (group)
348
+ declaration.group = group;
349
+ const tags = asStringArray(item.tags);
350
+ if (tags)
351
+ declaration.tags = tags;
352
+ declaration.components = buildPatternComponents(item.components);
353
+ return declaration;
354
+ };
355
+ /**
356
+ * Pick the renderer-specific `handoff-app` component factory from the record's renderer so the
357
+ * synthesized declaration matches the authored contract for that renderer. `react`/`handlebars`/`csf`
358
+ * each have a dedicated factory that stamps the renderer itself (so the renderer is dropped from the
359
+ * authored config); an unknown/absent renderer falls back to the generic `defineComponent`, which
360
+ * keeps `renderer` in the config.
361
+ */
362
+ const resolveComponentFactory = (renderer) => {
363
+ switch (renderer) {
364
+ case 'react':
365
+ return { name: 'defineReactComponent', stampsRenderer: true };
366
+ case 'handlebars':
367
+ return { name: 'defineHandlebarsComponent', stampsRenderer: true };
368
+ case 'csf':
369
+ return { name: 'defineCsfComponent', stampsRenderer: true };
370
+ default:
371
+ return { name: 'defineComponent', stampsRenderer: false };
372
+ }
373
+ };
374
+ /** Drop a key from an object without mutating it. */
375
+ const omit = (object, key) => {
376
+ const _a = object, _b = key, _removed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
377
+ return rest;
378
+ };
379
+ /** Turn a relative entry path into a module specifier (extension stripped, `./`-prefixed). */
380
+ const toImportSpecifier = (entryPath) => {
381
+ const withoutExt = entryPath.replace(COMPONENT_EXTENSION, '').split(path_1.default.sep).join('/');
382
+ return withoutExt.startsWith('.') ? withoutExt : `./${withoutExt}`;
383
+ };
384
+ /** Derive a safe PascalCase identifier for the imported React component. */
385
+ const toComponentIdentifier = (entryPath, fallback) => {
386
+ const base = path_1.default.basename(entryPath).replace(COMPONENT_EXTENSION, '');
387
+ const pascal = (base || fallback)
388
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
389
+ .trim()
390
+ .split(/\s+/)
391
+ .filter(Boolean)
392
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
393
+ .join('');
394
+ return /^[A-Za-z_$]/.test(pascal) ? pascal : `Component${pascal}`;
395
+ };
396
+ /** Keys matching this are emitted unquoted in JS/TS object literals; others are single-quoted. */
397
+ const JS_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
398
+ /** Serialize a string as a single-quoted JS literal (repo style), escaping safely. */
399
+ const singleQuote = (value) => {
400
+ var _a;
401
+ let out = "'";
402
+ for (const char of value) {
403
+ const code = (_a = char.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
404
+ if (char === '\\')
405
+ out += '\\\\';
406
+ else if (char === "'")
407
+ out += "\\'";
408
+ else if (char === '\n')
409
+ out += '\\n';
410
+ else if (char === '\r')
411
+ out += '\\r';
412
+ else if (char === '\t')
413
+ out += '\\t';
414
+ else if (code < 0x20)
415
+ out += `\\u${code.toString(16).padStart(4, '0')}`;
416
+ else
417
+ out += char;
418
+ }
419
+ return `${out}'`;
420
+ };
421
+ /**
422
+ * Serialize a value as a JS/TS object literal mirroring `JSON.stringify(value, null, 2)` formatting,
423
+ * except identifier-safe object keys are emitted unquoted (`id: 'button'` rather than
424
+ * `"id": "button"`) and strings are single-quoted to match the repo's authoring style. `undefined`
425
+ * entries are dropped.
426
+ */
427
+ const toJsLiteral = (value, indentLevel = 0) => {
428
+ const pad = ' '.repeat(indentLevel);
429
+ const padInner = ' '.repeat(indentLevel + 1);
430
+ if (value === null) {
431
+ return 'null';
432
+ }
433
+ if (typeof value === 'string') {
434
+ return singleQuote(value);
435
+ }
436
+ if (typeof value !== 'object') {
437
+ return JSON.stringify(value);
438
+ }
439
+ if (Array.isArray(value)) {
440
+ if (value.length === 0) {
441
+ return '[]';
442
+ }
443
+ const items = value.map((item) => `${padInner}${toJsLiteral(item, indentLevel + 1)}`);
444
+ return `[\n${items.join(',\n')}\n${pad}]`;
445
+ }
446
+ const entries = Object.entries(value).filter(([, v]) => v !== undefined);
447
+ if (entries.length === 0) {
448
+ return '{}';
449
+ }
450
+ const lines = entries.map(([key, v]) => {
451
+ const renderedKey = JS_IDENTIFIER.test(key) ? key : singleQuote(key);
452
+ return `${padInner}${renderedKey}: ${toJsLiteral(v, indentLevel + 1)}`;
453
+ });
454
+ return `{\n${lines.join(',\n')}\n${pad}}`;
455
+ };
456
+ /** Wrap a config object in a factory call for the given code format (unquoted identifier keys). */
457
+ const wrapFactory = (factory, config, format) => {
458
+ const literal = toJsLiteral(config);
459
+ return format === 'ts'
460
+ ? `import { ${factory} } from 'handoff-app';\n\nexport default ${factory}(${literal});\n`
461
+ : `const { ${factory} } = require('handoff-app');\n\nmodule.exports = ${factory}(${literal});\n`;
462
+ };
463
+ /**
464
+ * Synthesize the component declaration file. JSON declarations are the bare object (carrying
465
+ * `renderer`/`entries`, which the loader reads directly). Code declarations use the renderer-specific
466
+ * factory; React additionally imports the component from its `entries.component` source and passes it
467
+ * as the factory's first argument (matching the authored `defineReactComponent` contract). When the
468
+ * renderer is `react` but no component entry is available, it falls back to the generic factory.
469
+ */
470
+ const renderComponentDeclaration = (declaration, format) => {
471
+ var _a;
472
+ if (format === 'json') {
473
+ return `${JSON.stringify(declaration, null, 2)}\n`;
474
+ }
475
+ const renderer = asString(declaration.renderer);
476
+ const factory = resolveComponentFactory(renderer);
477
+ const componentEntry = isPlainObject(declaration.entries) ? asString(declaration.entries.component) : undefined;
478
+ if (factory.name === 'defineReactComponent' && componentEntry) {
479
+ const specifier = toImportSpecifier(componentEntry);
480
+ const identifier = toComponentIdentifier(componentEntry, (_a = asString(declaration.id)) !== null && _a !== void 0 ? _a : 'Component');
481
+ const literal = toJsLiteral(omit(declaration, 'renderer'));
482
+ return format === 'ts'
483
+ ? `import { defineReactComponent } from 'handoff-app';\nimport ${identifier} from '${specifier}';\n\nexport default defineReactComponent(${identifier}, ${literal});\n`
484
+ : `const { defineReactComponent } = require('handoff-app');\nconst ${identifier} = require('${specifier}').default;\n\nmodule.exports = defineReactComponent(${identifier}, ${literal});\n`;
485
+ }
486
+ // React without a resolvable component entry can't use defineReactComponent; keep renderer and use
487
+ // the generic factory so the build still infers the renderer.
488
+ const effective = factory.name === 'defineReactComponent' ? { name: 'defineComponent', stampsRenderer: false } : factory;
489
+ const config = effective.stampsRenderer ? omit(declaration, 'renderer') : declaration;
490
+ return wrapFactory(effective.name, config, format);
491
+ };
492
+ /** Synthesize the pattern declaration file via `definePattern` (or a bare object for JSON). */
493
+ const renderPatternDeclaration = (declaration, format) => {
494
+ if (format === 'json') {
495
+ return `${JSON.stringify(declaration, null, 2)}\n`;
496
+ }
497
+ return wrapFactory('definePattern', declaration, format);
498
+ };
499
+ /** Synthesize the declaration file contents for an entity, faithful to its renderer/kind contract. */
500
+ const synthesizeDeclaration = (kind, item, format) => kind === 'component'
501
+ ? renderComponentDeclaration(buildComponentDeclaration(item), format)
502
+ : renderPatternDeclaration(buildPatternDeclaration(item), format);
503
+ /**
504
+ * Confirm overwriting any local files the checkout would replace. Returns `true` to proceed. With
505
+ * `--force` (or when nothing would be overwritten) it proceeds without prompting; otherwise it asks
506
+ * for explicit confirmation and treats a cancel/decline as an abort.
507
+ */
508
+ const confirmOverwrite = (handoff, conflicts) => __awaiter(void 0, void 0, void 0, function* () {
509
+ if (conflicts.length === 0 || handoff.force) {
510
+ return true;
511
+ }
512
+ const relative = conflicts.map((file) => ` - ${path_1.default.relative(handoff.workingPath, file)}`).join('\n');
513
+ const proceed = yield p.confirm({
514
+ message: `Checkout will overwrite ${conflicts.length} existing local file(s):\n${relative}\nOverwrite?`,
515
+ initialValue: false,
516
+ });
517
+ return !p.isCancel(proceed) && proceed === true;
518
+ });
519
+ /** Write a registry source file at its relative path under the target directory. */
520
+ const writeSourceFile = (targetDir, file) => __awaiter(void 0, void 0, void 0, function* () {
521
+ const absolutePath = (0, path_2.resolvePathWithin)(targetDir, file.path);
522
+ if (!absolutePath) {
523
+ throw new CheckoutError(`Registry returned an unsafe source file path "${file.path}".`);
524
+ }
525
+ yield fs_extra_1.default.ensureDir(path_1.default.dirname(absolutePath));
526
+ yield fs_extra_1.default.writeFile(absolutePath, file.content, 'utf8');
527
+ return absolutePath;
528
+ });
529
+ /**
530
+ * Checkout a page: write its single verbatim `.md` (transfer path `<id>.md`) back under
531
+ * `<workingPath>/pages/`. Unlike components/patterns there is no declaration to synthesize — the
532
+ * markdown file is itself the authored source — so the page round-trips byte-for-byte.
533
+ */
534
+ const checkoutPage = (handoff, id, payload) => __awaiter(void 0, void 0, void 0, function* () {
535
+ const pagesRoot = path_1.default.resolve(handoff.workingPath, DEFAULT_ENTITY_DIR.page);
536
+ const targets = payload.files.map((file) => {
537
+ const target = (0, path_2.resolvePathWithin)(pagesRoot, file.path);
538
+ if (!target) {
539
+ throw new CheckoutError(`Registry returned an unsafe page source path "${file.path}".`);
540
+ }
541
+ return target;
542
+ });
543
+ const conflicts = targets.filter((file) => fs_extra_1.default.existsSync(file));
544
+ if (!(yield confirmOverwrite(handoff, conflicts))) {
545
+ logger_1.Logger.warn(`Checkout of page "${id}" cancelled; no files were written.`);
546
+ return;
547
+ }
548
+ for (const file of payload.files) {
549
+ yield writeSourceFile(pagesRoot, file);
550
+ }
551
+ logger_1.Logger.success(`Checked out page "${id}" into ${path_1.default.relative(handoff.workingPath, pagesRoot) || '.'} ` + `(${payload.files.length} markdown file(s)).`);
552
+ });
553
+ /**
554
+ * Checkout a single component or pattern from a connected workspace: precondition checks → fetch the
555
+ * normalized record + source files → resolve the local target → explicit-overwrite guard → write
556
+ * source files and synthesize the local declaration. Throws {@link CheckoutError} with actionable
557
+ * messaging on any precondition or fetch failure.
558
+ */
559
+ const checkoutEntity = (handoff, kind, id) => __awaiter(void 0, void 0, void 0, function* () {
560
+ const validId = kind === 'page' ? (0, path_2.isSafeRelativePath)(id) : (0, path_2.isSafePathSegment)(id);
561
+ if (!validId) {
562
+ throw new CheckoutError(`Cannot checkout ${kind} with unsafe id "${id}".`);
563
+ }
564
+ const connection = (0, exports.resolveConnectionOrThrow)(handoff);
565
+ logger_1.Logger.info(`Fetching ${kind} "${id}" from ${connection.url}…`);
566
+ const client = (0, client_1.createRegistryClient)({ baseUrl: connection.url, accessToken: connection.accessToken });
567
+ let payload;
568
+ try {
569
+ payload = yield client.checkout(kind, id);
570
+ }
571
+ catch (error) {
572
+ if (error instanceof client_1.RegistryClientError) {
573
+ throw new CheckoutError(describeFetchFailure(error, kind, id, connection.url));
574
+ }
575
+ throw error;
576
+ }
577
+ // Pages round-trip as a single verbatim `.md` with no declaration synthesis.
578
+ if (kind === 'page') {
579
+ yield checkoutPage(handoff, id, payload);
580
+ return;
581
+ }
582
+ const targetDir = yield resolveTargetDir(handoff, kind, id);
583
+ const format = resolveDeclarationFormat(handoff, targetDir);
584
+ const declarationFileName = resolveDeclarationFileName(targetDir, id, format);
585
+ const declarationPath = path_1.default.join(targetDir, declarationFileName);
586
+ // Compute everything that would be written, then gate overwrite of any pre-existing file.
587
+ const sourceTargets = payload.files.map((file) => {
588
+ const absolutePath = (0, path_2.resolvePathWithin)(targetDir, file.path);
589
+ if (!absolutePath) {
590
+ throw new CheckoutError(`Registry returned an unsafe source file path "${file.path}".`);
591
+ }
592
+ return { file, absolutePath };
593
+ });
594
+ const conflicts = [...sourceTargets.map((entry) => entry.absolutePath), declarationPath].filter((file) => fs_extra_1.default.existsSync(file));
595
+ if (!(yield confirmOverwrite(handoff, conflicts))) {
596
+ logger_1.Logger.warn(`Checkout of ${kind} "${id}" cancelled; no files were written.`);
597
+ return;
598
+ }
599
+ yield fs_extra_1.default.ensureDir(targetDir);
600
+ const written = [];
601
+ for (const { file } of sourceTargets) {
602
+ written.push(yield writeSourceFile(targetDir, file));
603
+ }
604
+ const declaration = synthesizeDeclaration(kind, payload.item, format);
605
+ yield fs_extra_1.default.writeFile(declarationPath, declaration, 'utf8');
606
+ written.push(declarationPath);
607
+ logger_1.Logger.success(`Checked out ${kind} "${id}" into ${path_1.default.relative(handoff.workingPath, targetDir) || '.'} ` +
608
+ `(${payload.files.length} source file(s) + ${declarationFileName}).`);
609
+ });
610
+ exports.checkoutEntity = checkoutEntity;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Connected-workspace token checkout orchestration.
3
+ *
4
+ * `checkout tokens [setId]` pulls published token sets from the connected registry into this
5
+ * workspace: it reconstructs the canonical local `tokens.json` (splicing each set's record into the
6
+ * document) and restores the generated token files (CSS/SCSS/Style Dictionary/types/custom) to their
7
+ * standard configured output paths under `getVariablesFilePath()`. Overwriting changed local token
8
+ * data requires `--force` or an interactive confirmation. Available only from a connected workspace.
9
+ */
10
+ import Handoff from '../../index';
11
+ /**
12
+ * Checkout all published token sets, or a single set when `setId` is given. Reconstructs `tokens.json`
13
+ * and restores generated files; prompts before overwriting changed local files unless `--force`.
14
+ */
15
+ export declare const checkoutTokens: (handoff: Handoff, setId?: string) => Promise<void>;