handoff-app 1.2.2-6 → 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/commands/build/app.js +1 -2
  29. package/dist/commands/build/index.d.ts +17 -0
  30. package/dist/commands/build/index.js +66 -0
  31. package/dist/commands/checkout/index.d.ts +24 -0
  32. package/dist/commands/checkout/index.js +71 -0
  33. package/dist/commands/db/migrate.d.ts +11 -0
  34. package/dist/commands/db/migrate.js +33 -0
  35. package/dist/commands/index.js +8 -0
  36. package/dist/commands/publish/index.d.ts +21 -0
  37. package/dist/commands/publish/index.js +68 -0
  38. package/dist/config/defaults.js +15 -1
  39. package/dist/config/loader.js +6 -1
  40. package/dist/config/normalizers/declaration.js +4 -1
  41. package/dist/config/normalizers/page.d.ts +18 -0
  42. package/dist/config/normalizers/page.js +34 -0
  43. package/dist/config/normalizers/pattern.js +7 -1
  44. package/dist/config/runtime.d.ts +4 -0
  45. package/dist/config/runtime.js +53 -5
  46. package/dist/index.d.ts +65 -1
  47. package/dist/index.js +123 -3
  48. package/dist/nav/index.d.ts +83 -0
  49. package/dist/nav/index.js +9 -0
  50. package/dist/nav/registry.d.ts +15 -0
  51. package/dist/nav/registry.js +42 -0
  52. package/dist/nav/resolver.d.ts +8 -0
  53. package/dist/nav/resolver.js +192 -0
  54. package/dist/nav/workspace.d.ts +18 -0
  55. package/dist/nav/workspace.js +103 -0
  56. package/dist/pipeline/styles.js +7 -35
  57. package/dist/pipeline/token-transformers.d.ts +45 -0
  58. package/dist/pipeline/token-transformers.js +71 -0
  59. package/dist/registry/asset-storage/adapters/vercel-blob.d.ts +17 -0
  60. package/dist/registry/asset-storage/adapters/vercel-blob.js +87 -0
  61. package/dist/registry/asset-storage/define.d.ts +10 -0
  62. package/dist/registry/asset-storage/define.js +13 -0
  63. package/dist/registry/asset-storage/resolve.d.ts +45 -0
  64. package/dist/registry/asset-storage/resolve.js +36 -0
  65. package/dist/registry/asset-storage/types.d.ts +51 -0
  66. package/dist/registry/asset-storage/types.js +9 -0
  67. package/dist/registry/assets/layout.d.ts +22 -0
  68. package/dist/registry/assets/layout.js +30 -0
  69. package/dist/registry/assets/sets.d.ts +18 -0
  70. package/dist/registry/assets/sets.js +44 -0
  71. package/dist/registry/assets/transfer.d.ts +45 -0
  72. package/dist/registry/assets/transfer.js +11 -0
  73. package/dist/registry/checkout/assets.d.ts +16 -0
  74. package/dist/registry/checkout/assets.js +150 -0
  75. package/dist/registry/checkout/index.d.ts +33 -0
  76. package/dist/registry/checkout/index.js +610 -0
  77. package/dist/registry/checkout/tokens.d.ts +15 -0
  78. package/dist/registry/checkout/tokens.js +171 -0
  79. package/dist/registry/client.d.ts +61 -0
  80. package/dist/registry/client.js +211 -0
  81. package/dist/registry/connection.d.ts +30 -0
  82. package/dist/registry/connection.js +36 -0
  83. package/dist/registry/db/adapter.d.ts +43 -0
  84. package/dist/registry/db/adapter.js +59 -0
  85. package/dist/registry/db/client.d.ts +35 -0
  86. package/dist/registry/db/client.js +94 -0
  87. package/dist/registry/db/index.d.ts +5 -0
  88. package/dist/registry/db/index.js +24 -0
  89. package/dist/registry/db/migrate.d.ts +23 -0
  90. package/dist/registry/db/migrate.js +64 -0
  91. package/dist/registry/db/schema.d.ts +4869 -0
  92. package/dist/registry/db/schema.js +347 -0
  93. package/dist/registry/path.d.ts +4 -0
  94. package/dist/registry/path.js +31 -0
  95. package/dist/registry/publish/artifacts.d.ts +16 -0
  96. package/dist/registry/publish/artifacts.js +132 -0
  97. package/dist/registry/publish/assets.d.ts +16 -0
  98. package/dist/registry/publish/assets.js +129 -0
  99. package/dist/registry/publish/errors.d.ts +5 -0
  100. package/dist/registry/publish/errors.js +26 -0
  101. package/dist/registry/publish/index.d.ts +27 -0
  102. package/dist/registry/publish/index.js +126 -0
  103. package/dist/registry/publish/package.d.ts +27 -0
  104. package/dist/registry/publish/package.js +257 -0
  105. package/dist/registry/publish/publish-build.d.ts +12 -0
  106. package/dist/registry/publish/publish-build.js +43 -0
  107. package/dist/registry/publish/tokens.d.ts +18 -0
  108. package/dist/registry/publish/tokens.js +112 -0
  109. package/dist/registry/tokens/sets.d.ts +59 -0
  110. package/dist/registry/tokens/sets.js +109 -0
  111. package/dist/registry/tokens/transfer.d.ts +48 -0
  112. package/dist/registry/tokens/transfer.js +10 -0
  113. package/dist/registry/transfer.d.ts +75 -0
  114. package/dist/registry/transfer.js +11 -0
  115. package/dist/store/filesystem-assets.d.ts +17 -0
  116. package/dist/store/filesystem-assets.js +147 -0
  117. package/dist/store/filesystem.d.ts +76 -0
  118. package/dist/store/filesystem.js +208 -0
  119. package/dist/store/index.d.ts +20 -0
  120. package/dist/store/index.js +38 -0
  121. package/dist/store/registry.d.ts +77 -0
  122. package/dist/store/registry.js +350 -0
  123. package/dist/store/source-files.d.ts +24 -0
  124. package/dist/store/source-files.js +147 -0
  125. package/dist/store/types.d.ts +185 -0
  126. package/dist/store/types.js +12 -0
  127. package/dist/transformers/plugins/csf-render.js +17 -8
  128. package/dist/transformers/plugins/handlebars-previews.js +10 -3
  129. package/dist/transformers/plugins/ssr-render.js +116 -49
  130. package/dist/transformers/preview/component/api.js +3 -1
  131. package/dist/transformers/preview/component/artifacts.js +8 -1
  132. package/dist/transformers/preview/component/builder.js +13 -5
  133. package/dist/transformers/preview/component/css.js +9 -1
  134. package/dist/transformers/preview/component/javascript.d.ts +9 -3
  135. package/dist/transformers/preview/component/javascript.js +45 -17
  136. package/dist/transformers/preview/component/shared-artifacts.d.ts +83 -0
  137. package/dist/transformers/preview/component/shared-artifacts.js +92 -0
  138. package/dist/transformers/preview/component.js +5 -2
  139. package/dist/transformers/preview/pattern/builder.js +28 -9
  140. package/dist/transformers/preview/pattern/html.d.ts +13 -10
  141. package/dist/transformers/preview/pattern/html.js +62 -27
  142. package/dist/transformers/preview/types.d.ts +38 -0
  143. package/dist/transformers/utils/handlebars.d.ts +3 -0
  144. package/dist/transformers/utils/handlebars.js +19 -5
  145. package/dist/types/config.d.ts +118 -25
  146. package/dist/utils/menu-shell.d.ts +60 -0
  147. package/dist/utils/menu-shell.js +221 -0
  148. package/dist/utils/stable-stringify.d.ts +2 -0
  149. package/dist/utils/stable-stringify.js +8 -0
  150. package/docs/cli.md +4 -2
  151. package/drizzle/0000_init_registry_storage.sql +95 -0
  152. package/drizzle/0001_add_review_metadata.sql +2 -0
  153. package/drizzle/0002_add_pages.sql +28 -0
  154. package/drizzle/0003_add_tokens.sql +29 -0
  155. package/drizzle/0004_add_assets.sql +37 -0
  156. package/drizzle/meta/0000_snapshot.json +642 -0
  157. package/drizzle/meta/0001_snapshot.json +654 -0
  158. package/drizzle/meta/0002_snapshot.json +835 -0
  159. package/drizzle/meta/0003_snapshot.json +1023 -0
  160. package/drizzle/meta/0004_snapshot.json +1252 -0
  161. package/drizzle/meta/_journal.json +41 -0
  162. package/drizzle.config.ts +16 -0
  163. package/package.json +10 -1
  164. package/src/app/components/Component/ComponentLists.tsx +102 -102
  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,83 @@
1
+ /** A mode-aware placeholder retained in the serialized navigation shell. */
2
+ export interface NavDynamicSlot {
3
+ kind: 'components' | 'patterns' | 'token-components';
4
+ type?: string;
5
+ }
6
+ /** A link nested within a navigation subsection. */
7
+ export interface NavMenuItem {
8
+ title: string;
9
+ path?: string;
10
+ image?: string;
11
+ menu?: NavMenuItem[];
12
+ }
13
+ /** A group or direct link beneath a top-level navigation section. */
14
+ export interface NavSubSection {
15
+ title: string;
16
+ path?: string;
17
+ image?: string;
18
+ menu?: NavMenuItem[];
19
+ dynamic?: NavDynamicSlot;
20
+ }
21
+ /** The canonical top-level navigation section shared by the build pipeline and docs app. */
22
+ export interface SectionLink {
23
+ title: string;
24
+ weight: number;
25
+ external?: string | boolean;
26
+ path: string;
27
+ subSections: NavSubSection[];
28
+ }
29
+ /** Minimal navigation entity served by the docs navigation endpoint. */
30
+ export interface NavEntity {
31
+ id: string;
32
+ title?: string;
33
+ group?: string;
34
+ type?: string;
35
+ }
36
+ /** A navigation token-set record. Only component sets are rendered in the component-token slot. */
37
+ export interface NavTokenSet extends NavEntity {
38
+ kind: 'foundation' | 'component';
39
+ }
40
+ /** A declarative submenu entry carried by a page record. */
41
+ export interface NavPageMenuDeclaration {
42
+ title?: string;
43
+ enabled?: boolean;
44
+ components?: boolean | string;
45
+ patterns?: boolean;
46
+ tokens?: boolean;
47
+ path?: string;
48
+ image?: string;
49
+ menu?: NavMenuItem[];
50
+ }
51
+ /** The page fields needed to compose page-authored navigation sections. */
52
+ export interface NavPageRecord {
53
+ id: string;
54
+ path?: string;
55
+ title?: string;
56
+ menuTitle?: string;
57
+ weight?: number;
58
+ enabled?: boolean;
59
+ external?: string | boolean;
60
+ menu?: Record<string, NavPageMenuDeclaration> | NavPageMenuDeclaration[];
61
+ }
62
+ /** Eager, already-resolved inputs to the pure navigation resolver. */
63
+ export interface NavSources {
64
+ shell: SectionLink[];
65
+ components: NavEntity[];
66
+ patterns: NavEntity[];
67
+ pages: NavPageRecord[];
68
+ tokenSets: NavTokenSet[];
69
+ tokenFoundations: NavMenuItem[];
70
+ basePath?: string;
71
+ }
72
+ export type NavMode = 'workspace' | 'registry';
73
+ export type NavLoad = 'initial' | 'refresh';
74
+ /** The render-ready navigation payload. */
75
+ export interface NavData {
76
+ shell: SectionLink[];
77
+ }
78
+ export { getNavData } from './resolver';
79
+ export type { GetNavDataInput } from './resolver';
80
+ export { getWorkspaceNavData } from './workspace';
81
+ export type { WorkspaceNavAdapterOptions, WorkspaceNavLoaders } from './workspace';
82
+ export { getRegistryNavData } from './registry';
83
+ export type { RegistryNavAdapterOptions, RegistryNavRecords } from './registry';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRegistryNavData = exports.getWorkspaceNavData = exports.getNavData = void 0;
4
+ var resolver_1 = require("./resolver");
5
+ Object.defineProperty(exports, "getNavData", { enumerable: true, get: function () { return resolver_1.getNavData; } });
6
+ var workspace_1 = require("./workspace");
7
+ Object.defineProperty(exports, "getWorkspaceNavData", { enumerable: true, get: function () { return workspace_1.getWorkspaceNavData; } });
8
+ var registry_1 = require("./registry");
9
+ Object.defineProperty(exports, "getRegistryNavData", { enumerable: true, get: function () { return registry_1.getRegistryNavData; } });
@@ -0,0 +1,15 @@
1
+ import type { NavData, NavEntity, NavLoad, NavPageRecord, NavTokenSet, SectionLink } from '.';
2
+ export interface RegistryNavRecords {
3
+ components: NavEntity[];
4
+ patterns: NavEntity[];
5
+ pages: NavPageRecord[];
6
+ tokenSets: NavTokenSet[];
7
+ }
8
+ export interface RegistryNavAdapterOptions {
9
+ shell: SectionLink[];
10
+ load: NavLoad;
11
+ basePath?: string;
12
+ fetchRecords: () => Promise<RegistryNavRecords>;
13
+ }
14
+ /** Registry adapter: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
15
+ export declare const getRegistryNavData: (options: RegistryNavAdapterOptions) => Promise<NavData>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getRegistryNavData = void 0;
13
+ const menu_shell_1 = require("../utils/menu-shell");
14
+ const resolver_1 = require("./resolver");
15
+ const emptyRecords = () => ({ components: [], patterns: [], pages: [], tokenSets: [] });
16
+ /** Registry adapter: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
17
+ const getRegistryNavData = (options) => __awaiter(void 0, void 0, void 0, function* () {
18
+ var _a;
19
+ let records = emptyRecords();
20
+ if (options.load === 'refresh') {
21
+ try {
22
+ records = (_a = (yield options.fetchRecords())) !== null && _a !== void 0 ? _a : records;
23
+ }
24
+ catch (_b) {
25
+ // Fall back to the baked navigation shell when the registry backend is unavailable.
26
+ }
27
+ }
28
+ const componentById = new Map(records.components.map((component) => [component.id, component]));
29
+ const tokenSets = records.tokenSets.map((set) => {
30
+ var _a;
31
+ const id = set.id.startsWith('component/') ? set.id.slice('component/'.length) : set.id;
32
+ const component = componentById.get(id);
33
+ return Object.assign(Object.assign({}, set), { title: set.title || (component === null || component === void 0 ? void 0 : component.title), group: (_a = set.group) !== null && _a !== void 0 ? _a : component === null || component === void 0 ? void 0 : component.group });
34
+ });
35
+ const normalizedBasePath = options.basePath ? `${options.basePath.replace(/^\/+|\/+$/g, '')}/` : '';
36
+ return (0, resolver_1.getNavData)({
37
+ mode: 'registry',
38
+ load: options.load,
39
+ sources: Object.assign(Object.assign({ shell: options.shell }, records), { tokenSets, tokenFoundations: (0, menu_shell_1.buildTokensFoundationsMenu)(normalizedBasePath), basePath: options.basePath }),
40
+ });
41
+ });
42
+ exports.getRegistryNavData = getRegistryNavData;
@@ -0,0 +1,8 @@
1
+ import type { NavData, NavLoad, NavMode, NavSources } from '.';
2
+ export interface GetNavDataInput {
3
+ mode: NavMode;
4
+ load: NavLoad;
5
+ sources: NavSources;
6
+ }
7
+ /** Resolve an eager navigation snapshot without fetching, mutation, or asynchronous work. */
8
+ export declare const getNavData: ({ mode, load, sources }: GetNavDataInput) => NavData;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.getNavData = void 0;
15
+ const lodash_1 = require("lodash");
16
+ const normalizeBasePath = (basePath) => {
17
+ if (!basePath)
18
+ return '';
19
+ return `${basePath.replace(/^\/+|\/+$/g, '')}/`;
20
+ };
21
+ const cloneMenu = (menu = []) => menu.map((item) => (Object.assign(Object.assign({}, item), (item.menu ? { menu: cloneMenu(item.menu) } : {}))));
22
+ const cloneSubSection = (section) => (Object.assign(Object.assign(Object.assign({}, section), (section.dynamic ? { dynamic: Object.assign({}, section.dynamic) } : {})), (section.menu ? { menu: cloneMenu(section.menu) } : {})));
23
+ const cloneSection = (section) => (Object.assign(Object.assign({}, section), { subSections: section.subSections.map(cloneSubSection) }));
24
+ const entityTitle = (entity) => entity.title || (0, lodash_1.startCase)(entity.id);
25
+ const buildEntityMenu = (entities, segment, basePath) => {
26
+ var _a, _b;
27
+ const grouped = new Map();
28
+ for (const entity of entities) {
29
+ const group = (_a = entity.group) !== null && _a !== void 0 ? _a : '';
30
+ grouped.set(group, [...((_b = grouped.get(group)) !== null && _b !== void 0 ? _b : []), entity]);
31
+ }
32
+ return Array.from(grouped.entries())
33
+ .map(([group, records]) => ({
34
+ title: group || 'Uncategorized',
35
+ path: '',
36
+ menu: records
37
+ .map((record) => ({
38
+ title: entityTitle(record),
39
+ path: `${basePath}system/${segment}/${record.id}`,
40
+ }))
41
+ .sort((a, b) => a.title.localeCompare(b.title)),
42
+ }))
43
+ .map((_a) => {
44
+ var { path: _path } = _a, group = __rest(_a, ["path"]);
45
+ return group;
46
+ })
47
+ .sort((a, b) => a.title.localeCompare(b.title));
48
+ };
49
+ const buildTokensMenu = (sources, basePath) => {
50
+ const foundations = cloneMenu(sources.tokenFoundations);
51
+ const componentSets = sources.tokenSets
52
+ .filter((set) => set.kind === 'component')
53
+ .map((set) => {
54
+ const id = set.id.startsWith('component/') ? set.id.slice('component/'.length) : set.id;
55
+ return {
56
+ title: set.title || (0, lodash_1.startCase)(id),
57
+ path: `${basePath}system/tokens/components/${id}`,
58
+ };
59
+ })
60
+ .sort((a, b) => a.title.localeCompare(b.title));
61
+ if (componentSets.length > 0) {
62
+ foundations.push({
63
+ title: 'Components',
64
+ path: `${basePath}system/tokens/components`,
65
+ menu: componentSets,
66
+ });
67
+ }
68
+ return foundations;
69
+ };
70
+ const fillSubSections = (subSections, sources, keepEmpty) => {
71
+ var _a, _b, _c, _d, _e;
72
+ const basePath = normalizeBasePath(sources.basePath);
73
+ const resolved = [];
74
+ for (const original of subSections) {
75
+ const section = cloneSubSection(original);
76
+ if (((_a = section.dynamic) === null || _a === void 0 ? void 0 : _a.kind) === 'components') {
77
+ const entities = section.dynamic.type
78
+ ? sources.components.filter((component) => { var _a; return component.type === ((_a = section.dynamic) === null || _a === void 0 ? void 0 : _a.type); })
79
+ : sources.components;
80
+ section.menu = buildEntityMenu(entities, 'component', basePath);
81
+ }
82
+ else if (((_b = section.dynamic) === null || _b === void 0 ? void 0 : _b.kind) === 'patterns') {
83
+ section.menu = buildEntityMenu(sources.patterns, 'pattern', basePath);
84
+ }
85
+ else if (((_c = section.dynamic) === null || _c === void 0 ? void 0 : _c.kind) === 'token-components') {
86
+ section.menu = buildTokensMenu(sources, basePath);
87
+ }
88
+ if (!section.dynamic || keepEmpty || ((_e = (_d = section.menu) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0) > 0) {
89
+ resolved.push(section);
90
+ }
91
+ }
92
+ return resolved;
93
+ };
94
+ const pageMenuEntries = (menu) => (Array.isArray(menu) ? menu : Object.values(menu !== null && menu !== void 0 ? menu : {}));
95
+ const declarationToSubSection = (declaration, sources) => {
96
+ var _a, _b, _c;
97
+ if (declaration.components) {
98
+ return {
99
+ title: (_a = declaration.title) !== null && _a !== void 0 ? _a : 'Components',
100
+ menu: [],
101
+ dynamic: typeof declaration.components === 'string' ? { kind: 'components', type: declaration.components } : { kind: 'components' },
102
+ };
103
+ }
104
+ if (declaration.patterns) {
105
+ return { title: (_b = declaration.title) !== null && _b !== void 0 ? _b : 'Patterns', menu: [], dynamic: { kind: 'patterns' } };
106
+ }
107
+ if (declaration.tokens) {
108
+ return {
109
+ title: 'Tokens',
110
+ menu: cloneMenu(sources.tokenFoundations),
111
+ dynamic: { kind: 'token-components' },
112
+ };
113
+ }
114
+ if (declaration.enabled === false)
115
+ return undefined;
116
+ return Object.assign(Object.assign(Object.assign({ title: (_c = declaration.title) !== null && _c !== void 0 ? _c : '' }, (declaration.path !== undefined ? { path: declaration.path } : {})), (declaration.image !== undefined ? { image: declaration.image } : {})), (declaration.menu !== undefined ? { menu: cloneMenu(declaration.menu) } : {}));
117
+ };
118
+ const buildChildPageItems = (parentId, pages) => {
119
+ const prefix = `${parentId}/`;
120
+ const segments = Array.from(new Set(pages.filter((page) => page.id.startsWith(prefix)).map((page) => page.id.slice(prefix.length).split('/')[0])));
121
+ return segments
122
+ .map((segment) => {
123
+ var _a, _b;
124
+ const id = `${parentId}/${segment}`;
125
+ const record = pages.find((page) => page.id === id);
126
+ const nested = buildChildPageItems(id, pages);
127
+ const item = {
128
+ title: (record === null || record === void 0 ? void 0 : record.menuTitle) || (record === null || record === void 0 ? void 0 : record.title) || (0, lodash_1.startCase)(segment),
129
+ path: (_a = record === null || record === void 0 ? void 0 : record.path) !== null && _a !== void 0 ? _a : `/${id}`,
130
+ weight: (_b = record === null || record === void 0 ? void 0 : record.weight) !== null && _b !== void 0 ? _b : 0,
131
+ };
132
+ if (nested.length > 0)
133
+ item.menu = nested;
134
+ return item;
135
+ })
136
+ .sort((a, b) => a.weight - b.weight || a.title.localeCompare(b.title))
137
+ .map((_a) => {
138
+ var { weight: _weight } = _a, item = __rest(_a, ["weight"]);
139
+ return item;
140
+ });
141
+ };
142
+ const buildPageSections = (sources, keepEmpty) => {
143
+ const pages = sources.pages.filter((page) => page.enabled !== false);
144
+ return pages
145
+ .filter((page) => !page.id.includes('/'))
146
+ .map((page) => {
147
+ var _a, _b;
148
+ const declared = page.menu
149
+ ? pageMenuEntries(page.menu)
150
+ .map((entry) => declarationToSubSection(entry, sources))
151
+ .filter((entry) => entry !== undefined)
152
+ : [];
153
+ const children = page.menu ? [] : buildChildPageItems(page.id, pages);
154
+ const subSections = page.menu
155
+ ? fillSubSections(declared, sources, keepEmpty)
156
+ : children.length > 0
157
+ ? [{ title: page.menuTitle || page.title || (0, lodash_1.startCase)(page.id), menu: children }]
158
+ : [];
159
+ const external = typeof page.external === 'string' &&
160
+ (page.external.startsWith('http://') || page.external.startsWith('https://') || page.external.startsWith('/'))
161
+ ? page.external
162
+ : false;
163
+ return {
164
+ title: page.menuTitle || page.title || (0, lodash_1.startCase)(page.id),
165
+ external,
166
+ weight: (_a = page.weight) !== null && _a !== void 0 ? _a : 0,
167
+ path: (_b = page.path) !== null && _b !== void 0 ? _b : `/${page.id}`,
168
+ subSections,
169
+ };
170
+ });
171
+ };
172
+ const resolveCompleteTree = (sources, keepEmpty) => {
173
+ const byPath = new Map(sources.shell.map((section) => [
174
+ section.path,
175
+ Object.assign(Object.assign({}, cloneSection(section)), { subSections: fillSubSections(section.subSections, sources, keepEmpty) }),
176
+ ]));
177
+ for (const section of buildPageSections(sources, keepEmpty)) {
178
+ byPath.set(section.path, section);
179
+ }
180
+ return Array.from(byPath.values()).sort((a, b) => a.weight - b.weight);
181
+ };
182
+ /** Resolve an eager navigation snapshot without fetching, mutation, or asynchronous work. */
183
+ const getNavData = ({ mode, load, sources }) => {
184
+ if (mode === 'workspace') {
185
+ return { shell: resolveCompleteTree(sources, false) };
186
+ }
187
+ if (load === 'initial') {
188
+ return { shell: sources.shell.map(cloneSection) };
189
+ }
190
+ return { shell: resolveCompleteTree(sources, true) };
191
+ };
192
+ exports.getNavData = getNavData;
@@ -0,0 +1,18 @@
1
+ import type { NavData, NavEntity, NavLoad, NavPageRecord, NavTokenSet } from '.';
2
+ type Awaitable<T> = T | Promise<T>;
3
+ export interface WorkspaceNavLoaders {
4
+ components: () => Awaitable<NavEntity[]>;
5
+ patterns: () => Awaitable<NavEntity[]>;
6
+ pages: () => Awaitable<NavPageRecord[]>;
7
+ tokenSets: () => Awaitable<NavTokenSet[]>;
8
+ }
9
+ export interface WorkspaceNavAdapterOptions {
10
+ docRoot: string;
11
+ workingPagesDir?: string;
12
+ basePath?: string;
13
+ load?: NavLoad;
14
+ loaders: WorkspaceNavLoaders;
15
+ }
16
+ /** Workspace/static adapter: live filesystem shell plus best-effort local snapshot loaders. */
17
+ export declare const getWorkspaceNavData: (options: WorkspaceNavAdapterOptions) => Promise<NavData>;
18
+ export {};
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.getWorkspaceNavData = void 0;
39
+ const fs = __importStar(require("fs"));
40
+ const gray_matter_1 = __importDefault(require("gray-matter"));
41
+ const path_1 = __importDefault(require("path"));
42
+ const menu_shell_1 = require("../utils/menu-shell");
43
+ const resolver_1 = require("./resolver");
44
+ const safeLoad = (load) => __awaiter(void 0, void 0, void 0, function* () {
45
+ var _a;
46
+ try {
47
+ return (_a = (yield load())) !== null && _a !== void 0 ? _a : [];
48
+ }
49
+ catch (_b) {
50
+ return [];
51
+ }
52
+ });
53
+ const markdownTitle = (id, docRoot, workingPagesDir) => {
54
+ const candidates = [
55
+ workingPagesDir ? path_1.default.resolve(workingPagesDir, 'system', `${id}.md`) : '',
56
+ path_1.default.resolve(docRoot, 'system', `${id}.md`),
57
+ ];
58
+ for (const candidate of candidates) {
59
+ if (!candidate || !fs.existsSync(candidate))
60
+ continue;
61
+ const title = (0, gray_matter_1.default)(fs.readFileSync(candidate, 'utf8')).data.title;
62
+ if (typeof title === 'string' && title.trim())
63
+ return title;
64
+ }
65
+ return undefined;
66
+ };
67
+ /** Workspace/static adapter: live filesystem shell plus best-effort local snapshot loaders. */
68
+ const getWorkspaceNavData = (options) => __awaiter(void 0, void 0, void 0, function* () {
69
+ var _a;
70
+ const [loadedComponents, patterns, pages, loadedTokenSets] = yield Promise.all([
71
+ safeLoad(options.loaders.components),
72
+ safeLoad(options.loaders.patterns),
73
+ safeLoad(options.loaders.pages),
74
+ safeLoad(options.loaders.tokenSets),
75
+ ]);
76
+ const components = loadedComponents.map((component) => (Object.assign(Object.assign({}, component), { title: component.title || markdownTitle(component.id, options.docRoot, options.workingPagesDir) })));
77
+ const componentById = new Map(components.map((component) => [component.id, component]));
78
+ const tokenSets = loadedTokenSets.map((set) => {
79
+ var _a;
80
+ const id = set.id.startsWith('component/') ? set.id.slice('component/'.length) : set.id;
81
+ const component = componentById.get(id);
82
+ return Object.assign(Object.assign({}, set), { title: set.title || (component === null || component === void 0 ? void 0 : component.title) || markdownTitle(id, options.docRoot, options.workingPagesDir), group: (_a = set.group) !== null && _a !== void 0 ? _a : component === null || component === void 0 ? void 0 : component.group });
83
+ });
84
+ const normalizedBasePath = options.basePath ? `${options.basePath.replace(/^\/+|\/+$/g, '')}/` : '';
85
+ return (0, resolver_1.getNavData)({
86
+ mode: 'workspace',
87
+ load: (_a = options.load) !== null && _a !== void 0 ? _a : 'refresh',
88
+ sources: {
89
+ shell: (0, menu_shell_1.buildMenuShell)({
90
+ docRoot: options.docRoot,
91
+ workingPagesDir: options.workingPagesDir,
92
+ basePath: options.basePath,
93
+ }),
94
+ components,
95
+ patterns,
96
+ pages,
97
+ tokenSets,
98
+ tokenFoundations: (0, menu_shell_1.buildTokensFoundationsMenu)(normalizedBasePath),
99
+ basePath: options.basePath,
100
+ },
101
+ });
102
+ });
103
+ exports.getWorkspaceNavData = getWorkspaceNavData;
@@ -18,6 +18,7 @@ const handoff_core_1 = require("handoff-core");
18
18
  const lodash_1 = require("lodash");
19
19
  const path_1 = __importDefault(require("path"));
20
20
  const archive_1 = require("./archive");
21
+ const token_transformers_1 = require("./token-transformers");
21
22
  /**
22
23
  * Build just the custom fonts — zips font directories and copies them to the export folder.
23
24
  */
@@ -49,39 +50,10 @@ exports.buildCustomFonts = buildCustomFonts;
49
50
  * Builds design token style files using core and user-configured transformers.
50
51
  */
51
52
  const buildStyles = (handoff, documentationObject) => __awaiter(void 0, void 0, void 0, function* () {
52
- var _a, _b, _c, _d;
53
- // Core transformers that should always be included
54
- const coreTransformers = [
55
- {
56
- transformer: handoff_core_1.Transformers.ScssTransformer,
57
- outDir: 'sass',
58
- format: 'scss',
59
- },
60
- {
61
- transformer: handoff_core_1.Transformers.ScssTypesTransformer,
62
- outDir: 'types',
63
- format: 'scss',
64
- },
65
- {
66
- transformer: handoff_core_1.Transformers.CssTransformer,
67
- outDir: 'css',
68
- format: 'css',
69
- },
70
- ];
71
- // Get user-configured transformers
72
- const userTransformers = ((_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.pipeline) === null || _b === void 0 ? void 0 : _b.transformers) || [];
73
- // Merge core transformers with user transformers
74
- // If a user transformer matches a core transformer, use user's outDir and format
75
- const transformers = coreTransformers.map((coreTransformer) => {
76
- const userTransformer = userTransformers.find((t) => t.transformer === coreTransformer.transformer);
77
- return userTransformer ? Object.assign(Object.assign({}, coreTransformer), { outDir: userTransformer.outDir, format: userTransformer.format }) : coreTransformer;
78
- });
79
- // Add any additional user transformers that aren't core transformers
80
- userTransformers.forEach((userTransformer) => {
81
- if (!coreTransformers.some((core) => core.transformer === userTransformer.transformer)) {
82
- transformers.push(userTransformer);
83
- }
84
- });
53
+ var _a, _b;
54
+ // Resolve the merged core + user-configured transformer list (single source of truth, shared with
55
+ // the registry publish packaging so the on-disk layout never drifts).
56
+ const transformers = (0, token_transformers_1.resolveTokenTransformers)(handoff);
85
57
  const baseDir = handoff.getVariablesFilePath();
86
58
  const runner = yield handoff.getRunner();
87
59
  // Create transformer instances and transform documentation object
@@ -100,7 +72,7 @@ const buildStyles = (handoff, documentationObject) => __awaiter(void 0, void 0,
100
72
  // Special case for SD tokens components directory
101
73
  const sdTransformer = transformers.find((t) => t.transformer === handoff_core_1.Transformers.StyleDictionaryTransformer);
102
74
  if (sdTransformer) {
103
- const sdFiles = (_c = transformedFiles.find((t) => t.transformer === handoff_core_1.Transformers.StyleDictionaryTransformer)) === null || _c === void 0 ? void 0 : _c.files;
75
+ const sdFiles = (_a = transformedFiles.find((t) => t.transformer === handoff_core_1.Transformers.StyleDictionaryTransformer)) === null || _a === void 0 ? void 0 : _a.files;
104
76
  if (sdFiles === null || sdFiles === void 0 ? void 0 : sdFiles.components) {
105
77
  yield Promise.all(Object.keys(sdFiles.components).map((name) => fs_extra_1.default.ensureDir(path_1.default.join(baseDir, sdTransformer.outDir, name))));
106
78
  }
@@ -125,7 +97,7 @@ const buildStyles = (handoff, documentationObject) => __awaiter(void 0, void 0,
125
97
  return [...componentPromises, ...designPromises];
126
98
  });
127
99
  // Generate tokens-map.json
128
- const mapFiles = (_d = transformedFiles.find((t) => t.transformer === handoff_core_1.Transformers.MapTransformer)) === null || _d === void 0 ? void 0 : _d.files;
100
+ const mapFiles = (_b = transformedFiles.find((t) => t.transformer === handoff_core_1.Transformers.MapTransformer)) === null || _b === void 0 ? void 0 : _b.files;
129
101
  if (mapFiles) {
130
102
  const tokensMapContent = JSON.stringify(Object.entries(mapFiles.components || {}).reduce((acc, [_, data]) => (Object.assign(Object.assign({}, acc), JSON.parse(data))), Object.assign(Object.assign(Object.assign({}, JSON.parse(mapFiles.design.colors)), JSON.parse(mapFiles.design.typography)), JSON.parse(mapFiles.design.effects))), null, 2);
131
103
  writePromises.push(fs_extra_1.default.writeFile(path_1.default.join(handoff.getOutputPath(), 'tokens-map.json'), tokensMapContent));
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared resolution of the design-token style transformers and their on-disk layout.
3
+ *
4
+ * Both {@link import('./styles').buildStyles} (which writes the generated token files) and the
5
+ * registry publish packaging (which reads them back byte-for-byte) must agree on exactly which
6
+ * transformers run, their output directories/formats, and the path each set's files land at. This
7
+ * module is the single source of that layout so the two never drift.
8
+ */
9
+ import type { TransformerConfig } from '../types/config';
10
+ /** Minimal shape needed to resolve transformers: just the pipeline transformer config. */
11
+ export interface TokenTransformerContext {
12
+ config?: {
13
+ pipeline?: {
14
+ transformers?: TransformerConfig[];
15
+ } | null;
16
+ } | null;
17
+ }
18
+ /** A resolved token transformer: the factory plus its output directory, file format, and logical label. */
19
+ export interface ResolvedTokenTransformer {
20
+ transformer: any;
21
+ outDir: string;
22
+ format: string;
23
+ /** Stable logical label for the output (`css`|`scss`|`types`|`styleDictionary`|custom `outDir`). */
24
+ label: string;
25
+ }
26
+ /**
27
+ * Resolve the merged transformer list (core + user-configured). A user transformer matching a core
28
+ * transformer overrides its `outDir`/`format`; other user transformers (e.g. Style Dictionary or a
29
+ * fully custom transformer) are appended. Mirrors the historical inline logic in `buildStyles`.
30
+ */
31
+ export declare const resolveTokenTransformers: (context: TokenTransformerContext) => ResolvedTokenTransformer[];
32
+ /** A generated token artifact expected for a set: its registry-safe relative path + logical label. */
33
+ export interface TokenArtifactLayout {
34
+ /** Path relative to `getVariablesFilePath()`, e.g. `css/colors.css` or `sd/button/button.tokens.json`. */
35
+ path: string;
36
+ /** Logical format label (`css`|`scss`|`types`|`styleDictionary`|custom). */
37
+ format: string;
38
+ }
39
+ /**
40
+ * Compute the registry-safe relative paths (under `getVariablesFilePath()`) a single set's generated
41
+ * files land at, across every resolved transformer. Honors the Style Dictionary nesting special-case
42
+ * (`buildStyles`): SD component tokens go to `<outDir>/<name>/<name>.tokens.json`, SD foundation
43
+ * tokens to `<outDir>/<name>.tokens.json`; every other transformer writes `<outDir>/<name>.<format>`.
44
+ */
45
+ export declare const tokenArtifactPathsForSet: (transformers: ResolvedTokenTransformer[], setName: string, isComponent: boolean) => TokenArtifactLayout[];