@pie-element/cli 0.1.1 → 0.1.2-next.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 (281) hide show
  1. package/README.md +48 -10
  2. package/dist/commands/dev/demo/index.d.ts +1 -1
  3. package/dist/commands/dev/demo/index.js +21 -0
  4. package/dist/commands/dev/demo/index.js.map +1 -1
  5. package/dist/commands/dev/test-bundler.d.ts +0 -1
  6. package/dist/commands/dev/test-bundler.js +2 -10
  7. package/dist/commands/dev/test-bundler.js.map +1 -1
  8. package/dist/commands/docs/generate.d.ts +16 -0
  9. package/dist/commands/docs/generate.js +150 -0
  10. package/dist/commands/docs/generate.js.map +1 -0
  11. package/dist/commands/docs/verify.d.ts +12 -0
  12. package/dist/commands/docs/verify.js +40 -0
  13. package/dist/commands/docs/verify.js.map +1 -0
  14. package/dist/commands/packages/create-controllers.d.ts +0 -1
  15. package/dist/commands/packages/create-controllers.js.map +1 -1
  16. package/dist/commands/packages/create-lib-react.d.ts +0 -1
  17. package/dist/commands/packages/create-lib-react.js +1 -3
  18. package/dist/commands/packages/create-lib-react.js.map +1 -1
  19. package/dist/commands/packages/create-react-elements.d.ts +0 -1
  20. package/dist/commands/packages/create-react-elements.js +2 -3
  21. package/dist/commands/packages/create-react-elements.js.map +1 -1
  22. package/dist/commands/packages/enable-publishing.d.ts +0 -1
  23. package/dist/commands/packages/enable-publishing.js +26 -23
  24. package/dist/commands/packages/enable-publishing.js.map +1 -1
  25. package/dist/commands/packages/init-synced-elements.d.ts +0 -1
  26. package/dist/commands/packages/init-synced-elements.js +1 -1
  27. package/dist/commands/packages/init-synced-elements.js.map +1 -1
  28. package/dist/commands/upstream/analyze-esm.d.ts +0 -1
  29. package/dist/commands/upstream/analyze-esm.js +5 -1
  30. package/dist/commands/upstream/analyze-esm.js.map +1 -1
  31. package/dist/commands/upstream/check.d.ts +0 -1
  32. package/dist/commands/upstream/check.js.map +1 -1
  33. package/dist/commands/upstream/deps.d.ts +0 -1
  34. package/dist/commands/upstream/deps.js.map +1 -1
  35. package/dist/commands/upstream/sync.d.ts +11 -2
  36. package/dist/commands/upstream/sync.js +364 -25
  37. package/dist/commands/upstream/sync.js.map +1 -1
  38. package/dist/commands/upstream/track.d.ts +0 -1
  39. package/dist/commands/upstream/track.js.map +1 -1
  40. package/dist/commands/upstream/update.d.ts +0 -1
  41. package/dist/commands/upstream/update.js +37 -7
  42. package/dist/commands/upstream/update.js.map +1 -1
  43. package/dist/commands/verify/controllers.d.ts +0 -1
  44. package/dist/commands/verify/controllers.js +213 -59
  45. package/dist/commands/verify/controllers.js.map +1 -1
  46. package/dist/commands/verify/dependency-integrity.d.ts +18 -0
  47. package/dist/commands/verify/dependency-integrity.js +147 -0
  48. package/dist/commands/verify/dependency-integrity.js.map +1 -0
  49. package/dist/commands/verify/react-build.d.ts +0 -1
  50. package/dist/commands/verify/react-build.js.map +1 -1
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/lib/docs/contract-validator.d.ts +12 -0
  54. package/dist/lib/docs/contract-validator.js +38 -0
  55. package/dist/lib/docs/contract-validator.js.map +1 -0
  56. package/dist/lib/docs/contracts.d.ts +11 -0
  57. package/dist/lib/docs/contracts.js +241 -0
  58. package/dist/lib/docs/contracts.js.map +1 -0
  59. package/dist/lib/docs/discovery.d.ts +10 -0
  60. package/dist/lib/docs/discovery.js +91 -0
  61. package/dist/lib/docs/discovery.js.map +1 -0
  62. package/dist/lib/docs/generator.d.ts +14 -0
  63. package/dist/lib/docs/generator.js +450 -0
  64. package/dist/lib/docs/generator.js.map +1 -0
  65. package/dist/lib/docs/source-extractor.d.ts +2 -0
  66. package/dist/lib/docs/source-extractor.js +209 -0
  67. package/dist/lib/docs/source-extractor.js.map +1 -0
  68. package/dist/lib/docs/types.d.ts +77 -0
  69. package/dist/lib/docs/types.js +2 -0
  70. package/dist/lib/docs/types.js.map +1 -0
  71. package/dist/lib/upstream/repo-utils.d.ts +0 -1
  72. package/dist/lib/upstream/repo-utils.js.map +1 -1
  73. package/dist/lib/upstream/sync-compatibility.d.ts +0 -1
  74. package/dist/lib/upstream/sync-compatibility.js.map +1 -1
  75. package/dist/lib/upstream/sync-constants.d.ts +35 -7
  76. package/dist/lib/upstream/sync-constants.js +40 -11
  77. package/dist/lib/upstream/sync-constants.js.map +1 -1
  78. package/dist/lib/upstream/sync-controllers-strategy.d.ts +0 -1
  79. package/dist/lib/upstream/sync-controllers-strategy.js +14 -4
  80. package/dist/lib/upstream/sync-controllers-strategy.js.map +1 -1
  81. package/dist/lib/upstream/sync-demo-metadata.d.ts +0 -1
  82. package/dist/lib/upstream/sync-demo-metadata.js +1 -1
  83. package/dist/lib/upstream/sync-demo-metadata.js.map +1 -1
  84. package/dist/lib/upstream/sync-entry-discovery.d.ts +3 -0
  85. package/dist/lib/upstream/sync-entry-discovery.js +23 -0
  86. package/dist/lib/upstream/sync-entry-discovery.js.map +1 -0
  87. package/dist/lib/upstream/sync-externals.d.ts +7 -7
  88. package/dist/lib/upstream/sync-externals.js +51 -35
  89. package/dist/lib/upstream/sync-externals.js.map +1 -1
  90. package/dist/lib/upstream/sync-filesystem.d.ts +0 -1
  91. package/dist/lib/upstream/sync-filesystem.js.map +1 -1
  92. package/dist/lib/upstream/sync-imports.d.ts +82 -62
  93. package/dist/lib/upstream/sync-imports.js +658 -185
  94. package/dist/lib/upstream/sync-imports.js.map +1 -1
  95. package/dist/lib/upstream/sync-package-json.d.ts +0 -1
  96. package/dist/lib/upstream/sync-package-json.js +7 -0
  97. package/dist/lib/upstream/sync-package-json.js.map +1 -1
  98. package/dist/lib/upstream/sync-package-manager.d.ts +14 -4
  99. package/dist/lib/upstream/sync-package-manager.js +405 -72
  100. package/dist/lib/upstream/sync-package-manager.js.map +1 -1
  101. package/dist/lib/upstream/sync-pielib-strategy.d.ts +2 -1
  102. package/dist/lib/upstream/sync-pielib-strategy.js +228 -110
  103. package/dist/lib/upstream/sync-pielib-strategy.js.map +1 -1
  104. package/dist/lib/upstream/sync-presets.d.ts +52 -0
  105. package/dist/lib/upstream/sync-presets.js +175 -0
  106. package/dist/lib/upstream/sync-presets.js.map +1 -0
  107. package/dist/lib/upstream/sync-react-strategy.d.ts +6 -1
  108. package/dist/lib/upstream/sync-react-strategy.js +342 -134
  109. package/dist/lib/upstream/sync-react-strategy.js.map +1 -1
  110. package/dist/lib/upstream/sync-source-edit.d.ts +14 -0
  111. package/dist/lib/upstream/sync-source-edit.js +89 -0
  112. package/dist/lib/upstream/sync-source-edit.js.map +1 -0
  113. package/dist/lib/upstream/sync-source-tree.d.ts +22 -0
  114. package/dist/lib/upstream/sync-source-tree.js +99 -0
  115. package/dist/lib/upstream/sync-source-tree.js.map +1 -0
  116. package/dist/lib/upstream/sync-strategy.d.ts +1 -1
  117. package/dist/lib/upstream/sync-strategy.js.map +1 -1
  118. package/dist/lib/upstream/sync-summary.d.ts +0 -1
  119. package/dist/lib/upstream/sync-summary.js.map +1 -1
  120. package/dist/lib/upstream/sync-transforms.d.ts +13 -11
  121. package/dist/lib/upstream/sync-transforms.js +23 -17
  122. package/dist/lib/upstream/sync-transforms.js.map +1 -1
  123. package/dist/lib/upstream/sync-vite-config.d.ts +13 -1
  124. package/dist/lib/upstream/sync-vite-config.js +65 -46
  125. package/dist/lib/upstream/sync-vite-config.js.map +1 -1
  126. package/dist/utils/compatibility.d.ts +13 -1
  127. package/dist/utils/compatibility.js +143 -2
  128. package/dist/utils/compatibility.js.map +1 -1
  129. package/dist/utils/conversion.d.ts +0 -1
  130. package/dist/utils/conversion.js.map +1 -1
  131. package/dist/utils/dependency-integrity.d.ts +37 -0
  132. package/dist/utils/dependency-integrity.js +557 -0
  133. package/dist/utils/dependency-integrity.js.map +1 -0
  134. package/dist/utils/git.d.ts +0 -1
  135. package/dist/utils/git.js.map +1 -1
  136. package/dist/utils/logger.d.ts +0 -1
  137. package/dist/utils/logger.js.map +1 -1
  138. package/dist/utils/package-json.d.ts +0 -1
  139. package/dist/utils/package-json.js.map +1 -1
  140. package/package.json +25 -8
  141. package/.compatibility/report.json +0 -2491
  142. package/.turbo/turbo-build.log +0 -1
  143. package/CHANGELOG.md +0 -8
  144. package/REFACTORING.md +0 -131
  145. package/bin/dev.js +0 -5
  146. package/dist/commands/dev/demo/index.d.ts.map +0 -1
  147. package/dist/commands/dev/test-bundler.d.ts.map +0 -1
  148. package/dist/commands/mathquill/migrate.d.ts +0 -20
  149. package/dist/commands/mathquill/migrate.d.ts.map +0 -1
  150. package/dist/commands/mathquill/migrate.js +0 -240
  151. package/dist/commands/mathquill/migrate.js.map +0 -1
  152. package/dist/commands/mathquill/status.d.ts +0 -20
  153. package/dist/commands/mathquill/status.d.ts.map +0 -1
  154. package/dist/commands/mathquill/status.js +0 -231
  155. package/dist/commands/mathquill/status.js.map +0 -1
  156. package/dist/commands/packages/create-controllers.d.ts.map +0 -1
  157. package/dist/commands/packages/create-lib-react.d.ts.map +0 -1
  158. package/dist/commands/packages/create-react-elements.d.ts.map +0 -1
  159. package/dist/commands/packages/enable-publishing.d.ts.map +0 -1
  160. package/dist/commands/packages/init-synced-elements.d.ts.map +0 -1
  161. package/dist/commands/upstream/analyze-esm.d.ts.map +0 -1
  162. package/dist/commands/upstream/check.d.ts.map +0 -1
  163. package/dist/commands/upstream/deps.d.ts.map +0 -1
  164. package/dist/commands/upstream/sync-mathquill.d.ts +0 -12
  165. package/dist/commands/upstream/sync-mathquill.d.ts.map +0 -1
  166. package/dist/commands/upstream/sync-mathquill.js +0 -97
  167. package/dist/commands/upstream/sync-mathquill.js.map +0 -1
  168. package/dist/commands/upstream/sync.d.ts.map +0 -1
  169. package/dist/commands/upstream/track.d.ts.map +0 -1
  170. package/dist/commands/upstream/update.d.ts.map +0 -1
  171. package/dist/commands/verify/controllers.d.ts.map +0 -1
  172. package/dist/commands/verify/react-build.d.ts.map +0 -1
  173. package/dist/index.d.ts.map +0 -1
  174. package/dist/lib/mathquill/extension-generator.d.ts +0 -9
  175. package/dist/lib/mathquill/extension-generator.d.ts.map +0 -1
  176. package/dist/lib/mathquill/extension-generator.js +0 -107
  177. package/dist/lib/mathquill/extension-generator.js.map +0 -1
  178. package/dist/lib/mathquill/khan-extractor.d.ts +0 -16
  179. package/dist/lib/mathquill/khan-extractor.d.ts.map +0 -1
  180. package/dist/lib/mathquill/khan-extractor.js +0 -148
  181. package/dist/lib/mathquill/khan-extractor.js.map +0 -1
  182. package/dist/lib/mathquill/learnosity-extractor.d.ts +0 -15
  183. package/dist/lib/mathquill/learnosity-extractor.d.ts.map +0 -1
  184. package/dist/lib/mathquill/learnosity-extractor.js +0 -170
  185. package/dist/lib/mathquill/learnosity-extractor.js.map +0 -1
  186. package/dist/lib/mathquill/migration-orchestrator.d.ts +0 -77
  187. package/dist/lib/mathquill/migration-orchestrator.d.ts.map +0 -1
  188. package/dist/lib/mathquill/migration-orchestrator.js +0 -391
  189. package/dist/lib/mathquill/migration-orchestrator.js.map +0 -1
  190. package/dist/lib/mathquill/package-updater.d.ts +0 -9
  191. package/dist/lib/mathquill/package-updater.d.ts.map +0 -1
  192. package/dist/lib/mathquill/package-updater.js +0 -103
  193. package/dist/lib/mathquill/package-updater.js.map +0 -1
  194. package/dist/lib/mathquill/pie-extractor.d.ts +0 -14
  195. package/dist/lib/mathquill/pie-extractor.d.ts.map +0 -1
  196. package/dist/lib/mathquill/pie-extractor.js +0 -167
  197. package/dist/lib/mathquill/pie-extractor.js.map +0 -1
  198. package/dist/lib/upstream/repo-utils.d.ts.map +0 -1
  199. package/dist/lib/upstream/sync-compatibility.d.ts.map +0 -1
  200. package/dist/lib/upstream/sync-constants.d.ts.map +0 -1
  201. package/dist/lib/upstream/sync-controllers-strategy.d.ts.map +0 -1
  202. package/dist/lib/upstream/sync-demo-metadata.d.ts.map +0 -1
  203. package/dist/lib/upstream/sync-dev-exports.d.ts +0 -13
  204. package/dist/lib/upstream/sync-dev-exports.d.ts.map +0 -1
  205. package/dist/lib/upstream/sync-dev-exports.js +0 -115
  206. package/dist/lib/upstream/sync-dev-exports.js.map +0 -1
  207. package/dist/lib/upstream/sync-externals.d.ts.map +0 -1
  208. package/dist/lib/upstream/sync-filesystem.d.ts.map +0 -1
  209. package/dist/lib/upstream/sync-imports.d.ts.map +0 -1
  210. package/dist/lib/upstream/sync-mathquill.d.ts +0 -19
  211. package/dist/lib/upstream/sync-mathquill.d.ts.map +0 -1
  212. package/dist/lib/upstream/sync-mathquill.js +0 -160
  213. package/dist/lib/upstream/sync-mathquill.js.map +0 -1
  214. package/dist/lib/upstream/sync-package-json.d.ts.map +0 -1
  215. package/dist/lib/upstream/sync-package-manager.d.ts.map +0 -1
  216. package/dist/lib/upstream/sync-pielib-strategy.d.ts.map +0 -1
  217. package/dist/lib/upstream/sync-react-strategy.d.ts.map +0 -1
  218. package/dist/lib/upstream/sync-strategy.d.ts.map +0 -1
  219. package/dist/lib/upstream/sync-summary.d.ts.map +0 -1
  220. package/dist/lib/upstream/sync-transforms.d.ts.map +0 -1
  221. package/dist/lib/upstream/sync-vite-config.d.ts.map +0 -1
  222. package/dist/utils/compatibility.d.ts.map +0 -1
  223. package/dist/utils/conversion.d.ts.map +0 -1
  224. package/dist/utils/git.d.ts.map +0 -1
  225. package/dist/utils/logger.d.ts.map +0 -1
  226. package/dist/utils/package-json.d.ts.map +0 -1
  227. package/packages/cli/bin/dev.js +0 -5
  228. package/packages/cli/bin/run.js +0 -5
  229. package/src/commands/dev/demo/index.ts +0 -313
  230. package/src/commands/dev/test-bundler.ts +0 -345
  231. package/src/commands/mathquill/migrate.ts +0 -269
  232. package/src/commands/mathquill/status.ts +0 -267
  233. package/src/commands/packages/create-controllers.ts +0 -127
  234. package/src/commands/packages/create-lib-react.ts +0 -279
  235. package/src/commands/packages/create-react-elements.ts +0 -306
  236. package/src/commands/packages/enable-publishing.ts +0 -161
  237. package/src/commands/packages/init-synced-elements.ts +0 -259
  238. package/src/commands/upstream/README.md +0 -444
  239. package/src/commands/upstream/analyze-esm.ts +0 -1973
  240. package/src/commands/upstream/check.ts +0 -228
  241. package/src/commands/upstream/deps.ts +0 -222
  242. package/src/commands/upstream/sync-mathquill.ts +0 -108
  243. package/src/commands/upstream/sync.ts +0 -687
  244. package/src/commands/upstream/track.ts +0 -145
  245. package/src/commands/upstream/update.ts +0 -110
  246. package/src/commands/verify/controllers.ts +0 -166
  247. package/src/commands/verify/react-build.ts +0 -171
  248. package/src/index.ts +0 -1
  249. package/src/lib/mathquill/extension-generator.ts +0 -111
  250. package/src/lib/mathquill/khan-extractor.ts +0 -175
  251. package/src/lib/mathquill/learnosity-extractor.ts +0 -198
  252. package/src/lib/mathquill/migration-orchestrator.ts +0 -513
  253. package/src/lib/mathquill/package-updater.ts +0 -120
  254. package/src/lib/mathquill/pie-extractor.ts +0 -194
  255. package/src/lib/upstream/repo-utils.ts +0 -18
  256. package/src/lib/upstream/sync-compatibility.ts +0 -89
  257. package/src/lib/upstream/sync-constants.ts +0 -77
  258. package/src/lib/upstream/sync-controllers-strategy.ts +0 -291
  259. package/src/lib/upstream/sync-demo-metadata.ts +0 -199
  260. package/src/lib/upstream/sync-dev-exports.ts +0 -151
  261. package/src/lib/upstream/sync-externals.ts +0 -159
  262. package/src/lib/upstream/sync-filesystem.ts +0 -87
  263. package/src/lib/upstream/sync-imports.ts +0 -992
  264. package/src/lib/upstream/sync-mathquill.ts +0 -194
  265. package/src/lib/upstream/sync-package-json.ts +0 -86
  266. package/src/lib/upstream/sync-package-manager.ts +0 -694
  267. package/src/lib/upstream/sync-pielib-strategy.ts +0 -441
  268. package/src/lib/upstream/sync-react-strategy.ts +0 -945
  269. package/src/lib/upstream/sync-strategy.ts +0 -61
  270. package/src/lib/upstream/sync-summary.ts +0 -194
  271. package/src/lib/upstream/sync-transforms.ts +0 -154
  272. package/src/lib/upstream/sync-vite-config.ts +0 -243
  273. package/src/types/es-module-lexer.d.ts +0 -4
  274. package/src/utils/compatibility.ts +0 -182
  275. package/src/utils/conversion.ts +0 -153
  276. package/src/utils/git.ts +0 -63
  277. package/src/utils/logger.ts +0 -69
  278. package/src/utils/package-json.ts +0 -43
  279. package/tests/sync-package-manager.test.ts +0 -112
  280. package/tests/transform-assign-props.test.ts +0 -101
  281. package/tsconfig.json +0 -15
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { run } from '@oclif/core';\n"]}
@@ -0,0 +1,12 @@
1
+ import type { PieDocsContract } from './types.js';
2
+ export interface ContractValidationIssue {
3
+ elementName: string;
4
+ message: string;
5
+ }
6
+ export interface ContractValidationResult {
7
+ issues: ContractValidationIssue[];
8
+ }
9
+ export declare const validateContracts: (contracts: Array<{
10
+ packageDir: string;
11
+ contract: PieDocsContract;
12
+ }>) => ContractValidationResult;
@@ -0,0 +1,38 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export const validateContracts = (contracts) => {
4
+ const issues = [];
5
+ const seenElementNames = new Set();
6
+ for (const entry of contracts) {
7
+ const { contract, packageDir } = entry;
8
+ if (seenElementNames.has(contract.elementName)) {
9
+ issues.push({
10
+ elementName: contract.elementName,
11
+ message: `Duplicate elementName detected: ${contract.elementName}`,
12
+ });
13
+ }
14
+ else {
15
+ seenElementNames.add(contract.elementName);
16
+ }
17
+ if (!contract.views.length) {
18
+ issues.push({
19
+ elementName: contract.elementName,
20
+ message: 'No views declared in contract',
21
+ });
22
+ continue;
23
+ }
24
+ for (const view of contract.views) {
25
+ for (const pointer of [view.pie, view.config]) {
26
+ const filePath = join(packageDir, pointer.file);
27
+ if (!existsSync(filePath)) {
28
+ issues.push({
29
+ elementName: contract.elementName,
30
+ message: `Missing source file for view "${view.view}": ${pointer.file}`,
31
+ });
32
+ }
33
+ }
34
+ }
35
+ }
36
+ return { issues };
37
+ };
38
+ //# sourceMappingURL=contract-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-validator.js","sourceRoot":"","sources":["../../../src/lib/docs/contract-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAYjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAAmE,EACzC,EAAE;IAC5B,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;QACvC,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC;gBACV,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,OAAO,EAAE,mCAAmC,QAAQ,CAAC,WAAW,EAAE;aACnE,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACV,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,OAAO,EAAE,+BAA+B;aACzC,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClC,KAAK,MAAM,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,CAAC;wBACV,WAAW,EAAE,QAAQ,CAAC,WAAW;wBACjC,OAAO,EAAE,iCAAiC,IAAI,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE;qBACxE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { PieDocsContract } from './types.js';\n\nexport interface ContractValidationIssue {\n elementName: string;\n message: string;\n}\n\nexport interface ContractValidationResult {\n issues: ContractValidationIssue[];\n}\n\nexport const validateContracts = (\n contracts: Array<{ packageDir: string; contract: PieDocsContract }>\n): ContractValidationResult => {\n const issues: ContractValidationIssue[] = [];\n const seenElementNames = new Set<string>();\n\n for (const entry of contracts) {\n const { contract, packageDir } = entry;\n if (seenElementNames.has(contract.elementName)) {\n issues.push({\n elementName: contract.elementName,\n message: `Duplicate elementName detected: ${contract.elementName}`,\n });\n } else {\n seenElementNames.add(contract.elementName);\n }\n\n if (!contract.views.length) {\n issues.push({\n elementName: contract.elementName,\n message: 'No views declared in contract',\n });\n continue;\n }\n\n for (const view of contract.views) {\n for (const pointer of [view.pie, view.config]) {\n const filePath = join(packageDir, pointer.file);\n if (!existsSync(filePath)) {\n issues.push({\n elementName: contract.elementName,\n message: `Missing source file for view \"${view.view}\": ${pointer.file}`,\n });\n }\n }\n }\n }\n\n return { issues };\n};\n"]}
@@ -0,0 +1,11 @@
1
+ import type { ElementPackageInfo, PieDocsContract } from './types.js';
2
+ export declare const parseContract: (raw: unknown, location: string) => PieDocsContract;
3
+ export declare const loadContract: (packageDir: string) => Promise<PieDocsContract | null>;
4
+ export declare const writeContract: (packageDir: string, contract: PieDocsContract) => Promise<void>;
5
+ export declare const seedContractForElement: (element: ElementPackageInfo, rootDir: string, options?: {
6
+ refresh?: boolean;
7
+ }) => Promise<{
8
+ wrote: boolean;
9
+ contractPath: string;
10
+ contract: PieDocsContract;
11
+ }>;
@@ -0,0 +1,241 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { join, relative } from 'node:path';
4
+ import { CONTRACT_FILENAME, inferViewsFromPackageExports } from './discovery.js';
5
+ const MODES = ['gather', 'view', 'evaluate'];
6
+ const isObject = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
7
+ const isSourcePointer = (value) => isObject(value) &&
8
+ typeof value.file === 'string' &&
9
+ (value.exportName === undefined || typeof value.exportName === 'string') &&
10
+ (value.path === undefined || typeof value.path === 'string');
11
+ const isPrimitiveEnumValue = (value) => value === null || ['string', 'number', 'boolean'].includes(typeof value);
12
+ const isPropertyMetadata = (value) => {
13
+ if (!isObject(value)) {
14
+ return false;
15
+ }
16
+ const allowed = [
17
+ 'title',
18
+ 'description',
19
+ 'notes',
20
+ 'type',
21
+ 'required',
22
+ 'enum',
23
+ 'minimum',
24
+ 'maximum',
25
+ 'minLength',
26
+ 'maxLength',
27
+ 'pattern',
28
+ 'itemType',
29
+ 'examples',
30
+ ];
31
+ for (const key of Object.keys(value)) {
32
+ if (!allowed.includes(key)) {
33
+ return false;
34
+ }
35
+ }
36
+ if (value.title !== undefined && typeof value.title !== 'string')
37
+ return false;
38
+ if (value.description !== undefined && typeof value.description !== 'string')
39
+ return false;
40
+ if (value.notes !== undefined && typeof value.notes !== 'string')
41
+ return false;
42
+ if (value.type !== undefined && typeof value.type !== 'string')
43
+ return false;
44
+ if (value.required !== undefined && typeof value.required !== 'boolean')
45
+ return false;
46
+ if (value.enum !== undefined) {
47
+ if (!Array.isArray(value.enum) || value.enum.some((entry) => !isPrimitiveEnumValue(entry))) {
48
+ return false;
49
+ }
50
+ }
51
+ for (const key of ['minimum', 'maximum', 'minLength', 'maxLength']) {
52
+ if (value[key] !== undefined && typeof value[key] !== 'number')
53
+ return false;
54
+ }
55
+ if (value.pattern !== undefined && typeof value.pattern !== 'string')
56
+ return false;
57
+ if (value.itemType !== undefined && typeof value.itemType !== 'string')
58
+ return false;
59
+ if (value.examples !== undefined && !Array.isArray(value.examples))
60
+ return false;
61
+ return true;
62
+ };
63
+ const normalizeMetadataMap = (map) => {
64
+ if (!map) {
65
+ return undefined;
66
+ }
67
+ return Object.fromEntries(Object.entries(map)
68
+ .sort(([a], [b]) => a.localeCompare(b))
69
+ .map(([path, metadata]) => [path, { ...metadata }]));
70
+ };
71
+ const isViewMetadata = (value) => {
72
+ if (!isObject(value)) {
73
+ return false;
74
+ }
75
+ for (const key of Object.keys(value)) {
76
+ if (!['pie', 'config'].includes(key)) {
77
+ return false;
78
+ }
79
+ const map = value[key];
80
+ if (map === undefined)
81
+ continue;
82
+ if (!isObject(map))
83
+ return false;
84
+ for (const entry of Object.values(map)) {
85
+ if (!isPropertyMetadata(entry))
86
+ return false;
87
+ }
88
+ }
89
+ return true;
90
+ };
91
+ const normalizePointer = (pointer) => ({
92
+ file: pointer.file,
93
+ ...(pointer.exportName ? { exportName: pointer.exportName } : {}),
94
+ ...(pointer.path ? { path: pointer.path } : {}),
95
+ });
96
+ const normalizeContract = (contract) => ({
97
+ elementName: contract.elementName,
98
+ packageName: contract.packageName,
99
+ framework: contract.framework,
100
+ ...(contract.summary ? { summary: contract.summary } : {}),
101
+ supportedModes: contract.supportedModes?.length ? [...contract.supportedModes] : MODES,
102
+ views: [...contract.views]
103
+ .sort((a, b) => a.view.localeCompare(b.view))
104
+ .map((view) => ({
105
+ view: view.view,
106
+ pie: normalizePointer(view.pie),
107
+ config: normalizePointer(view.config),
108
+ ...(view.description ? { description: view.description } : {}),
109
+ ...(view.metadata
110
+ ? {
111
+ metadata: {
112
+ ...(view.metadata.pie ? { pie: normalizeMetadataMap(view.metadata.pie) } : {}),
113
+ ...(view.metadata.config
114
+ ? { config: normalizeMetadataMap(view.metadata.config) }
115
+ : {}),
116
+ },
117
+ }
118
+ : {}),
119
+ })),
120
+ });
121
+ const inferPiePointer = (packageDir) => {
122
+ const candidates = [
123
+ { file: 'src/author/defaultConfiguration.ts', path: 'model' },
124
+ { file: 'src/author/defaults.ts', path: 'model' },
125
+ { file: 'src/controller/defaults.ts' },
126
+ ];
127
+ for (const candidate of candidates) {
128
+ if (existsSync(join(packageDir, candidate.file))) {
129
+ return candidate;
130
+ }
131
+ }
132
+ return { file: 'src/controller/defaults.ts' };
133
+ };
134
+ const inferConfigPointer = (packageDir) => {
135
+ const candidates = [
136
+ { file: 'src/author/defaultConfiguration.ts', path: 'configuration' },
137
+ { file: 'src/author/defaults.ts', path: 'configuration' },
138
+ { file: 'src/controller/defaults.ts' },
139
+ ];
140
+ for (const candidate of candidates) {
141
+ if (existsSync(join(packageDir, candidate.file))) {
142
+ return candidate;
143
+ }
144
+ }
145
+ return { file: 'src/controller/defaults.ts', path: 'configuration' };
146
+ };
147
+ export const parseContract = (raw, location) => {
148
+ if (!isObject(raw)) {
149
+ throw new Error(`Invalid docs contract in ${location}: expected object`);
150
+ }
151
+ if (typeof raw.elementName !== 'string' || !raw.elementName.trim()) {
152
+ throw new Error(`Invalid docs contract in ${location}: elementName is required`);
153
+ }
154
+ if (typeof raw.packageName !== 'string' || !raw.packageName.startsWith('@pie-element/')) {
155
+ throw new Error(`Invalid docs contract in ${location}: packageName is invalid`);
156
+ }
157
+ if (raw.framework !== 'react' && raw.framework !== 'svelte') {
158
+ throw new Error(`Invalid docs contract in ${location}: framework must be react|svelte`);
159
+ }
160
+ if (!Array.isArray(raw.views) || raw.views.length === 0) {
161
+ throw new Error(`Invalid docs contract in ${location}: at least one view is required`);
162
+ }
163
+ const views = raw.views.map((view, index) => {
164
+ if (!isObject(view)) {
165
+ throw new Error(`Invalid docs contract in ${location}: views[${index}] must be an object`);
166
+ }
167
+ if (typeof view.view !== 'string' || !view.view.trim()) {
168
+ throw new Error(`Invalid docs contract in ${location}: views[${index}].view is required`);
169
+ }
170
+ if (!isSourcePointer(view.pie)) {
171
+ throw new Error(`Invalid docs contract in ${location}: views[${index}].pie is invalid`);
172
+ }
173
+ if (!isSourcePointer(view.config)) {
174
+ throw new Error(`Invalid docs contract in ${location}: views[${index}].config is invalid`);
175
+ }
176
+ if (view.metadata !== undefined && !isViewMetadata(view.metadata)) {
177
+ throw new Error(`Invalid docs contract in ${location}: views[${index}].metadata is invalid`);
178
+ }
179
+ return {
180
+ view: view.view,
181
+ pie: view.pie,
182
+ config: view.config,
183
+ ...(typeof view.description === 'string' ? { description: view.description } : {}),
184
+ ...(view.metadata ? { metadata: view.metadata } : {}),
185
+ };
186
+ });
187
+ const supportedModes = Array.isArray(raw.supportedModes)
188
+ ? raw.supportedModes.filter((mode) => typeof mode === 'string')
189
+ : undefined;
190
+ return normalizeContract({
191
+ elementName: raw.elementName,
192
+ packageName: raw.packageName,
193
+ framework: raw.framework,
194
+ summary: typeof raw.summary === 'string' ? raw.summary : undefined,
195
+ supportedModes: supportedModes?.length ? supportedModes : MODES,
196
+ views,
197
+ });
198
+ };
199
+ export const loadContract = async (packageDir) => {
200
+ const contractPath = join(packageDir, CONTRACT_FILENAME);
201
+ if (!existsSync(contractPath)) {
202
+ return null;
203
+ }
204
+ const raw = JSON.parse(await readFile(contractPath, 'utf-8'));
205
+ return parseContract(raw, contractPath);
206
+ };
207
+ export const writeContract = async (packageDir, contract) => {
208
+ const contractPath = join(packageDir, CONTRACT_FILENAME);
209
+ const normalized = normalizeContract(contract);
210
+ await mkdir(packageDir, { recursive: true });
211
+ await writeFile(contractPath, `${JSON.stringify(normalized, null, 2)}\n`, 'utf-8');
212
+ };
213
+ export const seedContractForElement = async (element, rootDir, options) => {
214
+ const contractPath = join(element.packageDir, CONTRACT_FILENAME);
215
+ const existing = await loadContract(element.packageDir);
216
+ if (existing && !options?.refresh) {
217
+ return { wrote: false, contractPath, contract: existing };
218
+ }
219
+ const piePointer = inferPiePointer(element.packageDir);
220
+ const configPointer = inferConfigPointer(element.packageDir);
221
+ const views = inferViewsFromPackageExports(element.exportsMap).map((view) => ({
222
+ view,
223
+ pie: piePointer,
224
+ config: configPointer,
225
+ }));
226
+ const contract = normalizeContract({
227
+ elementName: element.elementName,
228
+ packageName: element.packageName,
229
+ framework: element.framework,
230
+ summary: existing?.summary || element.packageDescription,
231
+ supportedModes: existing?.supportedModes?.length ? existing.supportedModes : MODES,
232
+ views,
233
+ });
234
+ await writeContract(element.packageDir, contract);
235
+ return {
236
+ wrote: true,
237
+ contractPath: relative(rootDir, contractPath),
238
+ contract,
239
+ };
240
+ };
241
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/lib/docs/contracts.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { CONTRACT_FILENAME, inferViewsFromPackageExports } from './discovery.js';\nimport type {\n ElementPackageInfo,\n PieDocsContract,\n PieDocsPropertyMetadata,\n PieDocsSourcePointer,\n PieDocsViewMetadata,\n} from './types.js';\n\nconst MODES = ['gather', 'view', 'evaluate'];\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === 'object' && !Array.isArray(value);\n\nconst isSourcePointer = (value: unknown): value is PieDocsSourcePointer =>\n isObject(value) &&\n typeof value.file === 'string' &&\n (value.exportName === undefined || typeof value.exportName === 'string') &&\n (value.path === undefined || typeof value.path === 'string');\n\nconst isPrimitiveEnumValue = (value: unknown): value is string | number | boolean | null =>\n value === null || ['string', 'number', 'boolean'].includes(typeof value);\n\nconst isPropertyMetadata = (value: unknown): value is PieDocsPropertyMetadata => {\n if (!isObject(value)) {\n return false;\n }\n const allowed = [\n 'title',\n 'description',\n 'notes',\n 'type',\n 'required',\n 'enum',\n 'minimum',\n 'maximum',\n 'minLength',\n 'maxLength',\n 'pattern',\n 'itemType',\n 'examples',\n ];\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) {\n return false;\n }\n }\n if (value.title !== undefined && typeof value.title !== 'string') return false;\n if (value.description !== undefined && typeof value.description !== 'string') return false;\n if (value.notes !== undefined && typeof value.notes !== 'string') return false;\n if (value.type !== undefined && typeof value.type !== 'string') return false;\n if (value.required !== undefined && typeof value.required !== 'boolean') return false;\n if (value.enum !== undefined) {\n if (!Array.isArray(value.enum) || value.enum.some((entry) => !isPrimitiveEnumValue(entry))) {\n return false;\n }\n }\n for (const key of ['minimum', 'maximum', 'minLength', 'maxLength'] as const) {\n if (value[key] !== undefined && typeof value[key] !== 'number') return false;\n }\n if (value.pattern !== undefined && typeof value.pattern !== 'string') return false;\n if (value.itemType !== undefined && typeof value.itemType !== 'string') return false;\n if (value.examples !== undefined && !Array.isArray(value.examples)) return false;\n return true;\n};\n\nconst normalizeMetadataMap = (\n map?: Record<string, PieDocsPropertyMetadata>\n): Record<string, PieDocsPropertyMetadata> | undefined => {\n if (!map) {\n return undefined;\n }\n return Object.fromEntries(\n Object.entries(map)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([path, metadata]) => [path, { ...metadata }])\n );\n};\n\nconst isViewMetadata = (value: unknown): value is PieDocsViewMetadata => {\n if (!isObject(value)) {\n return false;\n }\n for (const key of Object.keys(value)) {\n if (!['pie', 'config'].includes(key)) {\n return false;\n }\n const map = value[key];\n if (map === undefined) continue;\n if (!isObject(map)) return false;\n for (const entry of Object.values(map)) {\n if (!isPropertyMetadata(entry)) return false;\n }\n }\n return true;\n};\n\nconst normalizePointer = (pointer: PieDocsSourcePointer): PieDocsSourcePointer => ({\n file: pointer.file,\n ...(pointer.exportName ? { exportName: pointer.exportName } : {}),\n ...(pointer.path ? { path: pointer.path } : {}),\n});\n\nconst normalizeContract = (contract: PieDocsContract): PieDocsContract => ({\n elementName: contract.elementName,\n packageName: contract.packageName,\n framework: contract.framework,\n ...(contract.summary ? { summary: contract.summary } : {}),\n supportedModes: contract.supportedModes?.length ? [...contract.supportedModes] : MODES,\n views: [...contract.views]\n .sort((a, b) => a.view.localeCompare(b.view))\n .map((view) => ({\n view: view.view,\n pie: normalizePointer(view.pie),\n config: normalizePointer(view.config),\n ...(view.description ? { description: view.description } : {}),\n ...(view.metadata\n ? {\n metadata: {\n ...(view.metadata.pie ? { pie: normalizeMetadataMap(view.metadata.pie) } : {}),\n ...(view.metadata.config\n ? { config: normalizeMetadataMap(view.metadata.config) }\n : {}),\n },\n }\n : {}),\n })),\n});\n\nconst inferPiePointer = (packageDir: string): PieDocsSourcePointer => {\n const candidates: PieDocsSourcePointer[] = [\n { file: 'src/author/defaultConfiguration.ts', path: 'model' },\n { file: 'src/author/defaults.ts', path: 'model' },\n { file: 'src/controller/defaults.ts' },\n ];\n\n for (const candidate of candidates) {\n if (existsSync(join(packageDir, candidate.file))) {\n return candidate;\n }\n }\n\n return { file: 'src/controller/defaults.ts' };\n};\n\nconst inferConfigPointer = (packageDir: string): PieDocsSourcePointer => {\n const candidates: PieDocsSourcePointer[] = [\n { file: 'src/author/defaultConfiguration.ts', path: 'configuration' },\n { file: 'src/author/defaults.ts', path: 'configuration' },\n { file: 'src/controller/defaults.ts' },\n ];\n\n for (const candidate of candidates) {\n if (existsSync(join(packageDir, candidate.file))) {\n return candidate;\n }\n }\n\n return { file: 'src/controller/defaults.ts', path: 'configuration' };\n};\n\nexport const parseContract = (raw: unknown, location: string): PieDocsContract => {\n if (!isObject(raw)) {\n throw new Error(`Invalid docs contract in ${location}: expected object`);\n }\n if (typeof raw.elementName !== 'string' || !raw.elementName.trim()) {\n throw new Error(`Invalid docs contract in ${location}: elementName is required`);\n }\n if (typeof raw.packageName !== 'string' || !raw.packageName.startsWith('@pie-element/')) {\n throw new Error(`Invalid docs contract in ${location}: packageName is invalid`);\n }\n if (raw.framework !== 'react' && raw.framework !== 'svelte') {\n throw new Error(`Invalid docs contract in ${location}: framework must be react|svelte`);\n }\n if (!Array.isArray(raw.views) || raw.views.length === 0) {\n throw new Error(`Invalid docs contract in ${location}: at least one view is required`);\n }\n\n const views = raw.views.map((view, index) => {\n if (!isObject(view)) {\n throw new Error(`Invalid docs contract in ${location}: views[${index}] must be an object`);\n }\n if (typeof view.view !== 'string' || !view.view.trim()) {\n throw new Error(`Invalid docs contract in ${location}: views[${index}].view is required`);\n }\n if (!isSourcePointer(view.pie)) {\n throw new Error(`Invalid docs contract in ${location}: views[${index}].pie is invalid`);\n }\n if (!isSourcePointer(view.config)) {\n throw new Error(`Invalid docs contract in ${location}: views[${index}].config is invalid`);\n }\n if (view.metadata !== undefined && !isViewMetadata(view.metadata)) {\n throw new Error(`Invalid docs contract in ${location}: views[${index}].metadata is invalid`);\n }\n\n return {\n view: view.view,\n pie: view.pie,\n config: view.config,\n ...(typeof view.description === 'string' ? { description: view.description } : {}),\n ...(view.metadata ? { metadata: view.metadata } : {}),\n };\n });\n\n const supportedModes = Array.isArray(raw.supportedModes)\n ? raw.supportedModes.filter((mode): mode is string => typeof mode === 'string')\n : undefined;\n\n return normalizeContract({\n elementName: raw.elementName,\n packageName: raw.packageName,\n framework: raw.framework,\n summary: typeof raw.summary === 'string' ? raw.summary : undefined,\n supportedModes: supportedModes?.length ? supportedModes : MODES,\n views,\n });\n};\n\nexport const loadContract = async (packageDir: string): Promise<PieDocsContract | null> => {\n const contractPath = join(packageDir, CONTRACT_FILENAME);\n if (!existsSync(contractPath)) {\n return null;\n }\n const raw = JSON.parse(await readFile(contractPath, 'utf-8')) as unknown;\n return parseContract(raw, contractPath);\n};\n\nexport const writeContract = async (\n packageDir: string,\n contract: PieDocsContract\n): Promise<void> => {\n const contractPath = join(packageDir, CONTRACT_FILENAME);\n const normalized = normalizeContract(contract);\n await mkdir(packageDir, { recursive: true });\n await writeFile(contractPath, `${JSON.stringify(normalized, null, 2)}\\n`, 'utf-8');\n};\n\nexport const seedContractForElement = async (\n element: ElementPackageInfo,\n rootDir: string,\n options?: { refresh?: boolean }\n): Promise<{ wrote: boolean; contractPath: string; contract: PieDocsContract }> => {\n const contractPath = join(element.packageDir, CONTRACT_FILENAME);\n const existing = await loadContract(element.packageDir);\n if (existing && !options?.refresh) {\n return { wrote: false, contractPath, contract: existing };\n }\n\n const piePointer = inferPiePointer(element.packageDir);\n const configPointer = inferConfigPointer(element.packageDir);\n const views = inferViewsFromPackageExports(element.exportsMap).map((view) => ({\n view,\n pie: piePointer,\n config: configPointer,\n }));\n\n const contract: PieDocsContract = normalizeContract({\n elementName: element.elementName,\n packageName: element.packageName,\n framework: element.framework,\n summary: existing?.summary || element.packageDescription,\n supportedModes: existing?.supportedModes?.length ? existing.supportedModes : MODES,\n views,\n });\n\n await writeContract(element.packageDir, contract);\n\n return {\n wrote: true,\n contractPath: relative(rootDir, contractPath),\n contract,\n };\n};\n"]}
@@ -0,0 +1,10 @@
1
+ import type { ElementPackageInfo, PieElementFramework } from './types.js';
2
+ interface DiscoverOptions {
3
+ rootDir: string;
4
+ frameworkFilter: PieElementFramework | 'all';
5
+ elementFilter?: string;
6
+ }
7
+ export declare const CONTRACT_FILENAME = "docs.contract.json";
8
+ export declare const discoverElementPackages: (options: DiscoverOptions) => Promise<ElementPackageInfo[]>;
9
+ export declare const inferViewsFromPackageExports: (exportsMap?: Record<string, unknown>) => string[];
10
+ export {};
@@ -0,0 +1,91 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { readdir, readFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ const ELEMENT_PREFIX = '@pie-element/';
5
+ const FRAMEWORK_DIRS = {
6
+ react: 'packages/elements-react',
7
+ svelte: 'packages/elements-svelte',
8
+ };
9
+ export const CONTRACT_FILENAME = 'docs.contract.json';
10
+ const safeReadPackageJson = async (packageJsonPath) => {
11
+ try {
12
+ const content = await readFile(packageJsonPath, 'utf-8');
13
+ return JSON.parse(content);
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ };
19
+ const coerceRecord = (value) => value && typeof value === 'object' && !Array.isArray(value)
20
+ ? value
21
+ : undefined;
22
+ export const discoverElementPackages = async (options) => {
23
+ const frameworks = options.frameworkFilter === 'all'
24
+ ? Object.keys(FRAMEWORK_DIRS)
25
+ : [options.frameworkFilter];
26
+ const results = [];
27
+ for (const framework of frameworks) {
28
+ const frameworkDir = join(options.rootDir, FRAMEWORK_DIRS[framework]);
29
+ if (!existsSync(frameworkDir)) {
30
+ continue;
31
+ }
32
+ const packageDirs = await readdir(frameworkDir);
33
+ for (const dirName of packageDirs) {
34
+ const packageDir = join(frameworkDir, dirName);
35
+ const packageJsonPath = join(packageDir, 'package.json');
36
+ if (!existsSync(packageJsonPath)) {
37
+ continue;
38
+ }
39
+ const pkg = await safeReadPackageJson(packageJsonPath);
40
+ if (!pkg) {
41
+ continue;
42
+ }
43
+ const packageName = typeof pkg.name === 'string' ? pkg.name : '';
44
+ if (!packageName.startsWith(ELEMENT_PREFIX)) {
45
+ continue;
46
+ }
47
+ const elementName = packageName.slice(ELEMENT_PREFIX.length).trim();
48
+ if (!elementName) {
49
+ continue;
50
+ }
51
+ if (options.elementFilter && options.elementFilter !== elementName) {
52
+ continue;
53
+ }
54
+ results.push({
55
+ elementName,
56
+ packageName,
57
+ framework,
58
+ packageDir,
59
+ packageDescription: typeof pkg.description === 'string' ? pkg.description : undefined,
60
+ exportsMap: coerceRecord(pkg.exports),
61
+ });
62
+ }
63
+ }
64
+ return results.sort((a, b) => a.elementName.localeCompare(b.elementName));
65
+ };
66
+ export const inferViewsFromPackageExports = (exportsMap) => {
67
+ if (!exportsMap) {
68
+ return ['delivery'];
69
+ }
70
+ const views = new Set(['delivery']);
71
+ for (const key of Object.keys(exportsMap)) {
72
+ if (!key.startsWith('./')) {
73
+ continue;
74
+ }
75
+ const view = key.replace('./', '').trim();
76
+ if (!view ||
77
+ view === 'delivery' ||
78
+ view === 'configure' ||
79
+ view === 'controller' ||
80
+ view === 'controller.js' ||
81
+ view === 'runtime-support' ||
82
+ view.startsWith('browser/')) {
83
+ continue;
84
+ }
85
+ if (view === 'author' || view === 'print' || view.startsWith('delivery-')) {
86
+ views.add(view);
87
+ }
88
+ }
89
+ return Array.from(views).sort();
90
+ };
91
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/lib/docs/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ElementPackageInfo, PieElementFramework } from './types.js';\n\ninterface DiscoverOptions {\n rootDir: string;\n frameworkFilter: PieElementFramework | 'all';\n elementFilter?: string;\n}\n\nconst ELEMENT_PREFIX = '@pie-element/';\n\nconst FRAMEWORK_DIRS: Record<PieElementFramework, string> = {\n react: 'packages/elements-react',\n svelte: 'packages/elements-svelte',\n};\n\nexport const CONTRACT_FILENAME = 'docs.contract.json';\n\nconst safeReadPackageJson = async (\n packageJsonPath: string\n): Promise<Record<string, unknown> | null> => {\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\n\nconst coerceRecord = (value: unknown): Record<string, unknown> | undefined =>\n value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n\nexport const discoverElementPackages = async (\n options: DiscoverOptions\n): Promise<ElementPackageInfo[]> => {\n const frameworks: PieElementFramework[] =\n options.frameworkFilter === 'all'\n ? (Object.keys(FRAMEWORK_DIRS) as PieElementFramework[])\n : [options.frameworkFilter];\n\n const results: ElementPackageInfo[] = [];\n\n for (const framework of frameworks) {\n const frameworkDir = join(options.rootDir, FRAMEWORK_DIRS[framework]);\n if (!existsSync(frameworkDir)) {\n continue;\n }\n\n const packageDirs = await readdir(frameworkDir);\n for (const dirName of packageDirs) {\n const packageDir = join(frameworkDir, dirName);\n const packageJsonPath = join(packageDir, 'package.json');\n if (!existsSync(packageJsonPath)) {\n continue;\n }\n\n const pkg = await safeReadPackageJson(packageJsonPath);\n if (!pkg) {\n continue;\n }\n\n const packageName = typeof pkg.name === 'string' ? pkg.name : '';\n if (!packageName.startsWith(ELEMENT_PREFIX)) {\n continue;\n }\n\n const elementName = packageName.slice(ELEMENT_PREFIX.length).trim();\n if (!elementName) {\n continue;\n }\n\n if (options.elementFilter && options.elementFilter !== elementName) {\n continue;\n }\n\n results.push({\n elementName,\n packageName,\n framework,\n packageDir,\n packageDescription: typeof pkg.description === 'string' ? pkg.description : undefined,\n exportsMap: coerceRecord(pkg.exports),\n });\n }\n }\n\n return results.sort((a, b) => a.elementName.localeCompare(b.elementName));\n};\n\nexport const inferViewsFromPackageExports = (exportsMap?: Record<string, unknown>): string[] => {\n if (!exportsMap) {\n return ['delivery'];\n }\n\n const views = new Set<string>(['delivery']);\n for (const key of Object.keys(exportsMap)) {\n if (!key.startsWith('./')) {\n continue;\n }\n const view = key.replace('./', '').trim();\n if (\n !view ||\n view === 'delivery' ||\n view === 'configure' ||\n view === 'controller' ||\n view === 'controller.js' ||\n view === 'runtime-support' ||\n view.startsWith('browser/')\n ) {\n continue;\n }\n if (view === 'author' || view === 'print' || view.startsWith('delivery-')) {\n views.add(view);\n }\n }\n\n return Array.from(views).sort();\n};\n"]}
@@ -0,0 +1,14 @@
1
+ import type { PieDocsContract, PieDocsElementOutput } from './types.js';
2
+ export interface GenerateDocsOptions {
3
+ outputDir: string;
4
+ dryRun: boolean;
5
+ check: boolean;
6
+ }
7
+ export interface GenerateDocsResult {
8
+ filesWritten: string[];
9
+ filesChecked: string[];
10
+ driftFiles: string[];
11
+ outputs: PieDocsElementOutput[];
12
+ }
13
+ export declare const generateDocsForContract: (packageDir: string, contract: PieDocsContract, options: GenerateDocsOptions) => Promise<GenerateDocsResult>;
14
+ export declare const toRelativePaths: (rootDir: string, paths: string[]) => string[];