primitive-admin 1.0.61 → 1.0.63

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 (320) hide show
  1. package/README.md +125 -69
  2. package/assets/skill/skills/primitive-platform/SKILL.md +336 -37
  3. package/dist/bin/primitive.js +25 -14
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/analytics.js +36 -16
  6. package/dist/src/commands/analytics.js.map +1 -1
  7. package/dist/src/commands/apps.js +52 -188
  8. package/dist/src/commands/apps.js.map +1 -1
  9. package/dist/src/commands/blob-buckets.js +13 -153
  10. package/dist/src/commands/blob-buckets.js.map +1 -1
  11. package/dist/src/commands/collection-type-configs.js +14 -100
  12. package/dist/src/commands/collection-type-configs.js.map +1 -1
  13. package/dist/src/commands/collections.js +47 -8
  14. package/dist/src/commands/collections.js.map +1 -1
  15. package/dist/src/commands/config.d.ts +46 -0
  16. package/dist/src/commands/config.js +479 -0
  17. package/dist/src/commands/config.js.map +1 -0
  18. package/dist/src/commands/connections.js +12 -7
  19. package/dist/src/commands/connections.js.map +1 -1
  20. package/dist/src/commands/cron-triggers.js +84 -176
  21. package/dist/src/commands/cron-triggers.js.map +1 -1
  22. package/dist/src/commands/database-type-configs.d.ts +2 -0
  23. package/dist/src/commands/database-type-configs.js +171 -0
  24. package/dist/src/commands/database-type-configs.js.map +1 -0
  25. package/dist/src/commands/database-types.js +4 -4
  26. package/dist/src/commands/database-types.js.map +1 -1
  27. package/dist/src/commands/databases.d.ts +63 -0
  28. package/dist/src/commands/databases.js +649 -87
  29. package/dist/src/commands/databases.js.map +1 -1
  30. package/dist/src/commands/documents.js +869 -12
  31. package/dist/src/commands/documents.js.map +1 -1
  32. package/dist/src/commands/email-templates.js +21 -128
  33. package/dist/src/commands/email-templates.js.map +1 -1
  34. package/dist/src/commands/env.d.ts +12 -1
  35. package/dist/src/commands/env.js +115 -26
  36. package/dist/src/commands/env.js.map +1 -1
  37. package/dist/src/commands/feature-flags.d.ts +14 -0
  38. package/dist/src/commands/feature-flags.js +116 -0
  39. package/dist/src/commands/feature-flags.js.map +1 -0
  40. package/dist/src/commands/group-type-configs.js +14 -109
  41. package/dist/src/commands/group-type-configs.js.map +1 -1
  42. package/dist/src/commands/init.d.ts +24 -1
  43. package/dist/src/commands/init.js +1194 -279
  44. package/dist/src/commands/init.js.map +1 -1
  45. package/dist/src/commands/integrations.js +166 -435
  46. package/dist/src/commands/integrations.js.map +1 -1
  47. package/dist/src/commands/metadata-category-configs.d.ts +12 -0
  48. package/dist/src/commands/metadata-category-configs.js +112 -0
  49. package/dist/src/commands/metadata-category-configs.js.map +1 -0
  50. package/dist/src/commands/metadata.js +33 -141
  51. package/dist/src/commands/metadata.js.map +1 -1
  52. package/dist/src/commands/prompts.js +206 -563
  53. package/dist/src/commands/prompts.js.map +1 -1
  54. package/dist/src/commands/rule-sets.d.ts +1 -1
  55. package/dist/src/commands/rule-sets.js +16 -132
  56. package/dist/src/commands/rule-sets.js.map +1 -1
  57. package/dist/src/commands/scripts.d.ts +10 -0
  58. package/dist/src/commands/scripts.js +203 -241
  59. package/dist/src/commands/scripts.js.map +1 -1
  60. package/dist/src/commands/sessions.js +17 -5
  61. package/dist/src/commands/sessions.js.map +1 -1
  62. package/dist/src/commands/sync-app-settings.d.ts +113 -70
  63. package/dist/src/commands/sync-app-settings.js +193 -242
  64. package/dist/src/commands/sync-app-settings.js.map +1 -1
  65. package/dist/src/commands/sync.d.ts +1904 -51
  66. package/dist/src/commands/sync.js +9468 -1790
  67. package/dist/src/commands/sync.js.map +1 -1
  68. package/dist/src/commands/tokens.js +8 -2
  69. package/dist/src/commands/tokens.js.map +1 -1
  70. package/dist/src/commands/users.js +92 -1
  71. package/dist/src/commands/users.js.map +1 -1
  72. package/dist/src/commands/vars.js +44 -58
  73. package/dist/src/commands/vars.js.map +1 -1
  74. package/dist/src/commands/webhooks.js +318 -156
  75. package/dist/src/commands/webhooks.js.map +1 -1
  76. package/dist/src/commands/workflows.d.ts +49 -12
  77. package/dist/src/commands/workflows.js +652 -1086
  78. package/dist/src/commands/workflows.js.map +1 -1
  79. package/dist/src/lib/access-rule-display.d.ts +21 -0
  80. package/dist/src/lib/access-rule-display.js +34 -0
  81. package/dist/src/lib/access-rule-display.js.map +1 -0
  82. package/dist/src/lib/api-client.d.ts +541 -61
  83. package/dist/src/lib/api-client.js +559 -102
  84. package/dist/src/lib/api-client.js.map +1 -1
  85. package/dist/src/lib/app-settings-descriptor.d.ts +180 -25
  86. package/dist/src/lib/app-settings-descriptor.js +403 -82
  87. package/dist/src/lib/app-settings-descriptor.js.map +1 -1
  88. package/dist/src/lib/canonical-json.d.ts +12 -0
  89. package/dist/src/lib/canonical-json.js +35 -0
  90. package/dist/src/lib/canonical-json.js.map +1 -0
  91. package/dist/src/lib/cli-manifest.d.ts +8 -0
  92. package/dist/src/lib/cli-manifest.js +1 -0
  93. package/dist/src/lib/cli-manifest.js.map +1 -1
  94. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +6 -2
  95. package/dist/src/lib/codegen-shared/generatedFiles.js +9 -2
  96. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
  97. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +6 -6
  98. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +8 -8
  99. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
  100. package/dist/src/lib/config-object-descriptor.d.ts +127 -0
  101. package/dist/src/lib/config-object-descriptor.js +658 -0
  102. package/dist/src/lib/config-object-descriptor.js.map +1 -0
  103. package/dist/src/lib/config-payload.d.ts +85 -0
  104. package/dist/src/lib/config-payload.js +116 -0
  105. package/dist/src/lib/config-payload.js.map +1 -0
  106. package/dist/src/lib/config-surface.d.ts +130 -0
  107. package/dist/src/lib/config-surface.js +300 -0
  108. package/dist/src/lib/config-surface.js.map +1 -0
  109. package/dist/src/lib/credentials-store.d.ts +10 -0
  110. package/dist/src/lib/credentials-store.js +23 -0
  111. package/dist/src/lib/credentials-store.js.map +1 -1
  112. package/dist/src/lib/data-input.d.ts +23 -0
  113. package/dist/src/lib/data-input.js +50 -0
  114. package/dist/src/lib/data-input.js.map +1 -0
  115. package/dist/src/lib/db-codegen/dbTemplates.js +1 -1
  116. package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
  117. package/dist/src/lib/db-codegen/dbTypeIR.d.ts +1 -1
  118. package/dist/src/lib/env-resolver-core.d.ts +187 -0
  119. package/dist/src/lib/env-resolver-core.js +325 -0
  120. package/dist/src/lib/env-resolver-core.js.map +1 -0
  121. package/dist/src/lib/env-resolver.d.ts +28 -6
  122. package/dist/src/lib/env-resolver.js +44 -32
  123. package/dist/src/lib/env-resolver.js.map +1 -1
  124. package/dist/src/lib/generated-allowlist.js +12 -0
  125. package/dist/src/lib/generated-allowlist.js.map +1 -1
  126. package/dist/src/lib/generated-config-surfaces.d.ts +682 -0
  127. package/dist/src/lib/generated-config-surfaces.js +4058 -0
  128. package/dist/src/lib/generated-config-surfaces.js.map +1 -0
  129. package/dist/src/lib/generated-template-lint.d.ts +212 -0
  130. package/dist/src/lib/generated-template-lint.js +624 -0
  131. package/dist/src/lib/generated-template-lint.js.map +1 -0
  132. package/dist/src/lib/init-adopt.d.ts +16 -0
  133. package/dist/src/lib/init-adopt.js +34 -0
  134. package/dist/src/lib/init-adopt.js.map +1 -0
  135. package/dist/src/lib/init-assets.d.ts +39 -0
  136. package/dist/src/lib/init-assets.js +97 -0
  137. package/dist/src/lib/init-assets.js.map +1 -0
  138. package/dist/src/lib/init-client-platforms.d.ts +14 -0
  139. package/dist/src/lib/init-client-platforms.js +71 -0
  140. package/dist/src/lib/init-client-platforms.js.map +1 -0
  141. package/dist/src/lib/init-config.d.ts +44 -5
  142. package/dist/src/lib/init-config.js +80 -7
  143. package/dist/src/lib/init-config.js.map +1 -1
  144. package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
  145. package/dist/src/lib/init-email-redirect-uris.js +46 -0
  146. package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
  147. package/dist/src/lib/init-ios-links.d.ts +90 -0
  148. package/dist/src/lib/init-ios-links.js +218 -0
  149. package/dist/src/lib/init-ios-links.js.map +1 -0
  150. package/dist/src/lib/init-plan.d.ts +80 -0
  151. package/dist/src/lib/init-plan.js +95 -0
  152. package/dist/src/lib/init-plan.js.map +1 -0
  153. package/dist/src/lib/init-production-env.d.ts +48 -0
  154. package/dist/src/lib/init-production-env.js +59 -0
  155. package/dist/src/lib/init-production-env.js.map +1 -0
  156. package/dist/src/lib/init-schema.d.ts +74 -0
  157. package/dist/src/lib/init-schema.js +358 -0
  158. package/dist/src/lib/init-schema.js.map +1 -0
  159. package/dist/src/lib/init-xcode.d.ts +33 -0
  160. package/dist/src/lib/init-xcode.js +114 -0
  161. package/dist/src/lib/init-xcode.js.map +1 -0
  162. package/dist/src/lib/integration-request-config.d.ts +30 -0
  163. package/dist/src/lib/integration-request-config.js +145 -0
  164. package/dist/src/lib/integration-request-config.js.map +1 -0
  165. package/dist/src/lib/integration-selector.d.ts +42 -0
  166. package/dist/src/lib/integration-selector.js +46 -0
  167. package/dist/src/lib/integration-selector.js.map +1 -0
  168. package/dist/src/lib/local-state.d.ts +55 -0
  169. package/dist/src/lib/local-state.js +167 -0
  170. package/dist/src/lib/local-state.js.map +1 -0
  171. package/dist/src/lib/local-test-cases.d.ts +63 -0
  172. package/dist/src/lib/local-test-cases.js +135 -0
  173. package/dist/src/lib/local-test-cases.js.map +1 -0
  174. package/dist/src/lib/log-inspection.d.ts +568 -0
  175. package/dist/src/lib/log-inspection.js +639 -0
  176. package/dist/src/lib/log-inspection.js.map +1 -0
  177. package/dist/src/lib/migration-nag.d.ts +2 -2
  178. package/dist/src/lib/migration-nag.js +3 -3
  179. package/dist/src/lib/object-status-filter.d.ts +22 -0
  180. package/dist/src/lib/object-status-filter.js +45 -0
  181. package/dist/src/lib/object-status-filter.js.map +1 -0
  182. package/dist/src/lib/output.d.ts +24 -1
  183. package/dist/src/lib/output.js +42 -1
  184. package/dist/src/lib/output.js.map +1 -1
  185. package/dist/src/lib/package-manager.d.ts +140 -0
  186. package/dist/src/lib/package-manager.js +305 -0
  187. package/dist/src/lib/package-manager.js.map +1 -0
  188. package/dist/src/lib/paginate.d.ts +50 -0
  189. package/dist/src/lib/paginate.js +53 -0
  190. package/dist/src/lib/paginate.js.map +1 -1
  191. package/dist/src/lib/platform-owned.d.ts +29 -3
  192. package/dist/src/lib/platform-owned.js +42 -3
  193. package/dist/src/lib/platform-owned.js.map +1 -1
  194. package/dist/src/lib/project-config.d.ts +8 -0
  195. package/dist/src/lib/project-config.js +30 -5
  196. package/dist/src/lib/project-config.js.map +1 -1
  197. package/dist/src/lib/query-operators.d.ts +1 -1
  198. package/dist/src/lib/query-operators.js +1 -1
  199. package/dist/src/lib/record-filter.d.ts +18 -0
  200. package/dist/src/lib/record-filter.js +55 -0
  201. package/dist/src/lib/record-filter.js.map +1 -0
  202. package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
  203. package/dist/src/lib/resolve-init-dev-port.js +55 -0
  204. package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
  205. package/dist/src/lib/resolve-init-server.d.ts +64 -0
  206. package/dist/src/lib/resolve-init-server.js +77 -0
  207. package/dist/src/lib/resolve-init-server.js.map +1 -0
  208. package/dist/src/lib/resolve-platform.d.ts +43 -14
  209. package/dist/src/lib/resolve-platform.js +74 -12
  210. package/dist/src/lib/resolve-platform.js.map +1 -1
  211. package/dist/src/lib/run-status.d.ts +19 -0
  212. package/dist/src/lib/run-status.generated.d.ts +39 -0
  213. package/dist/src/lib/run-status.generated.js +66 -0
  214. package/dist/src/lib/run-status.generated.js.map +1 -0
  215. package/dist/src/lib/run-status.js +19 -0
  216. package/dist/src/lib/run-status.js.map +1 -0
  217. package/dist/src/lib/server-text-normalization.d.ts +51 -0
  218. package/dist/src/lib/server-text-normalization.js +90 -0
  219. package/dist/src/lib/server-text-normalization.js.map +1 -0
  220. package/dist/src/lib/server-url.d.ts +22 -0
  221. package/dist/src/lib/server-url.js +33 -0
  222. package/dist/src/lib/server-url.js.map +1 -0
  223. package/dist/src/lib/signing-secret-status.d.ts +81 -0
  224. package/dist/src/lib/signing-secret-status.js +116 -0
  225. package/dist/src/lib/signing-secret-status.js.map +1 -0
  226. package/dist/src/lib/skill-installer.js +6 -3
  227. package/dist/src/lib/skill-installer.js.map +1 -1
  228. package/dist/src/lib/snapshots.d.ts +2 -2
  229. package/dist/src/lib/snapshots.js +2 -2
  230. package/dist/src/lib/swift-codegen/dbGenerator.d.ts +15 -2
  231. package/dist/src/lib/swift-codegen/dbGenerator.js +250 -18
  232. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
  233. package/dist/src/lib/swift-codegen/generator.d.ts +11 -2
  234. package/dist/src/lib/swift-codegen/generator.js +181 -7
  235. package/dist/src/lib/swift-codegen/generator.js.map +1 -1
  236. package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +7 -3
  237. package/dist/src/lib/swift-codegen/siblingSymbols.js +4 -1
  238. package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -1
  239. package/dist/src/lib/sync-dir-selector.d.ts +21 -0
  240. package/dist/src/lib/sync-dir-selector.js +30 -0
  241. package/dist/src/lib/sync-dir-selector.js.map +1 -0
  242. package/dist/src/lib/sync-paths.d.ts +39 -0
  243. package/dist/src/lib/sync-paths.js +70 -2
  244. package/dist/src/lib/sync-paths.js.map +1 -1
  245. package/dist/src/lib/sync-resource-types.d.ts +138 -31
  246. package/dist/src/lib/sync-resource-types.js +241 -47
  247. package/dist/src/lib/sync-resource-types.js.map +1 -1
  248. package/dist/src/lib/sync-selectors.d.ts +95 -0
  249. package/dist/src/lib/sync-selectors.js +228 -0
  250. package/dist/src/lib/sync-selectors.js.map +1 -0
  251. package/dist/src/lib/template.d.ts +62 -4
  252. package/dist/src/lib/template.js +147 -39
  253. package/dist/src/lib/template.js.map +1 -1
  254. package/dist/src/lib/test-case-file-names.d.ts +40 -0
  255. package/dist/src/lib/test-case-file-names.js +91 -0
  256. package/dist/src/lib/test-case-file-names.js.map +1 -0
  257. package/dist/src/lib/test-case-keys.d.ts +29 -0
  258. package/dist/src/lib/test-case-keys.js +55 -0
  259. package/dist/src/lib/test-case-keys.js.map +1 -0
  260. package/dist/src/lib/test-case-variables.d.ts +15 -0
  261. package/dist/src/lib/test-case-variables.js +29 -0
  262. package/dist/src/lib/test-case-variables.js.map +1 -0
  263. package/dist/src/lib/toml-database-config.d.ts +4 -4
  264. package/dist/src/lib/toml-database-config.js +27 -34
  265. package/dist/src/lib/toml-database-config.js.map +1 -1
  266. package/dist/src/lib/toml-metadata-config.d.ts +9 -5
  267. package/dist/src/lib/toml-metadata-config.js +40 -45
  268. package/dist/src/lib/toml-metadata-config.js.map +1 -1
  269. package/dist/src/lib/toml-native-form.d.ts +1 -1
  270. package/dist/src/lib/toml-native-form.js +1 -1
  271. package/dist/src/lib/toml-params-validator.d.ts +1 -1
  272. package/dist/src/lib/toml-params-validator.js +1 -1
  273. package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
  274. package/dist/src/lib/toml-scalar-edit.js +283 -0
  275. package/dist/src/lib/toml-scalar-edit.js.map +1 -0
  276. package/dist/src/lib/user-selector.d.ts +24 -0
  277. package/dist/src/lib/user-selector.js +33 -0
  278. package/dist/src/lib/user-selector.js.map +1 -0
  279. package/dist/src/lib/version-check.d.ts +25 -0
  280. package/dist/src/lib/version-check.js +77 -8
  281. package/dist/src/lib/version-check.js.map +1 -1
  282. package/dist/src/lib/watch.d.ts +121 -0
  283. package/dist/src/lib/watch.js +169 -0
  284. package/dist/src/lib/watch.js.map +1 -0
  285. package/dist/src/lib/web-url.d.ts +40 -0
  286. package/dist/src/lib/web-url.js +76 -0
  287. package/dist/src/lib/web-url.js.map +1 -0
  288. package/dist/src/lib/workflow-apply.d.ts +69 -45
  289. package/dist/src/lib/workflow-apply.js +99 -72
  290. package/dist/src/lib/workflow-apply.js.map +1 -1
  291. package/dist/src/lib/workflow-codegen/generator.js +4 -4
  292. package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
  293. package/dist/src/lib/workflow-codegen/invokerIR.d.ts +11 -0
  294. package/dist/src/lib/workflow-codegen/invokerIR.js +5 -0
  295. package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -1
  296. package/dist/src/lib/workflow-config-apply.d.ts +70 -0
  297. package/dist/src/lib/workflow-config-apply.js +137 -0
  298. package/dist/src/lib/workflow-config-apply.js.map +1 -0
  299. package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
  300. package/dist/src/lib/workflow-config-sidecar.js +96 -0
  301. package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
  302. package/dist/src/lib/workflow-defaults.d.ts +29 -0
  303. package/dist/src/lib/workflow-defaults.js +41 -0
  304. package/dist/src/lib/workflow-defaults.js.map +1 -0
  305. package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
  306. package/dist/src/lib/workflow-include-preserve.js +286 -0
  307. package/dist/src/lib/workflow-include-preserve.js.map +1 -0
  308. package/dist/src/lib/workflow-payload.d.ts +31 -20
  309. package/dist/src/lib/workflow-payload.js +100 -110
  310. package/dist/src/lib/workflow-payload.js.map +1 -1
  311. package/dist/src/lib/workflow-toml-validator.d.ts +37 -16
  312. package/dist/src/lib/workflow-toml-validator.js +141 -16
  313. package/dist/src/lib/workflow-toml-validator.js.map +1 -1
  314. package/dist/src/types/index.d.ts +78 -22
  315. package/dist/src/validators.d.ts +7 -7
  316. package/dist/src/validators.js +6 -6
  317. package/package.json +11 -6
  318. package/dist/src/commands/settings.d.ts +0 -15
  319. package/dist/src/commands/settings.js +0 -102
  320. package/dist/src/commands/settings.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ import type { Platform } from "./resolve-platform.js";
2
+ /** The canonical schema's path, relative to the project root. */
3
+ export declare const CANONICAL_SCHEMA_RELATIVE: string;
4
+ /**
5
+ * A POSIX-style relative specifier from `fromDir` to `toFile`, always prefixed
6
+ * with `./` or `../` — what both an import specifier and a `-i` argument need.
7
+ */
8
+ export declare function relativeSchemaPath(fromDir: string, toFile: string): string;
9
+ /**
10
+ * The schema a freshly installed client template ships, or null when it has
11
+ * none (the Swift starter is comment-only but the file is still there).
12
+ */
13
+ export declare function findClientSchema(clientDir: string, platform: Platform): string | null;
14
+ /** The Swift target's source directory (`Sources/<AppName>`), if there is one. */
15
+ export declare function findSwiftTargetDir(clientDir: string): string | null;
16
+ /**
17
+ * The models a schema declares, in the order it declares them.
18
+ *
19
+ * `[models.<name>]`, `[models.<name>.fields.<field>]` and the array form all
20
+ * name the same model; the loader treats the first path segment after `models`
21
+ * as the model name, and so does this.
22
+ */
23
+ export declare function declaredModelNames(toml: string): string[];
24
+ /**
25
+ * The app's one schema has to declare every model its clients read.
26
+ *
27
+ * A client's template ships both a starter schema and code generated from it —
28
+ * the web template's store reads `UserPref`, and the model generator refuses a
29
+ * schema with no models at all. So composing the shared schema is not "pick a
30
+ * starter": it is the base schema (an existing client's, when one is being
31
+ * promoted) PLUS every model a client being added declares and the base does
32
+ * not. Nothing is ever overwritten — a model the base already declares is the
33
+ * app's definition of it, and stays exactly as it is.
34
+ */
35
+ export declare function composeSchemaContent(input: {
36
+ /** The schema the app already has, or the one being promoted to the root. */
37
+ base: string;
38
+ /** The starter schemas of the clients this run is adding. */
39
+ starters: string[];
40
+ }): {
41
+ content: string;
42
+ added: string[];
43
+ };
44
+ /** What `wireClientToSchema` actually rewrote, for the caller to report. */
45
+ export interface SchemaWiringResult {
46
+ /** Files rewritten or created so this client reads the shared schema. */
47
+ rewired: string[];
48
+ /** The client-local schema copy that was removed, if any. */
49
+ removed?: string;
50
+ /** Set when the client's shape was not recognized and nothing was rewired. */
51
+ error?: string;
52
+ }
53
+ /**
54
+ * Points one client at the shared schema and drops its own copy.
55
+ *
56
+ * Writes the new wiring BEFORE removing the client-local schema, so a failure
57
+ * leaves a client that still has a schema rather than one with neither.
58
+ */
59
+ export declare function wireClientToSchema(clientDir: string, platform: Platform, schemaPath: string): SchemaWiringResult;
60
+ /**
61
+ * Why this client cannot be pointed at the shared schema, or null when it can.
62
+ *
63
+ * Separate from the wiring itself because the answer decides whether the run
64
+ * happens at all: a client that keeps its own schema while the app has another
65
+ * is the two-copies layout the shared schema exists to prevent, so a caller
66
+ * asks this BEFORE it writes the shared file — before the download, when the
67
+ * client already exists.
68
+ */
69
+ export declare function checkClientWiring(clientDir: string, platform: Platform, schemaPath: string): string | null;
70
+ /**
71
+ * Writes the canonical schema, creating `models/` if needed. Never overwrites:
72
+ * an existing shared schema is the app's, not this run's.
73
+ */
74
+ export declare function writeCanonicalSchema(schemaPath: string, content: string): boolean;
@@ -0,0 +1,358 @@
1
+ /**
2
+ * One model schema for one Primitive app, however many clients it has (#2890).
3
+ *
4
+ * The schema cannot be duplicated: its TOML keys are the wire field names, so
5
+ * two copies that drift orphan each other's records. It also must not be a
6
+ * symlink — that was a way around the generators not reading a schema outside
7
+ * the client tree, which #2889 fixed. This module is the wiring against that
8
+ * landed surface:
9
+ *
10
+ * web — `js-bao-codegen-v2 -i <path to the shared schema> -o src/models`.
11
+ * The generated barrel imports the schema it was generated FROM, by a
12
+ * relative specifier, so the same file feeds codegen and the runtime
13
+ * `loadSchemaFromTomlString` call.
14
+ * swift — `bao-codegen.json` at the root of the target's source directory:
15
+ * `{ "input": "../../../models/models.toml" }`, resolved against the
16
+ * target directory. When present it replaces the plugin's scan of the
17
+ * target's own sources, and `scripts/generate-models.sh` (the Xcode
18
+ * path) reads the same file.
19
+ *
20
+ * Every function here reports what it changed rather than throwing on a shape
21
+ * it does not recognize, so a caller can say precisely what it did and did not
22
+ * rewire.
23
+ */
24
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "fs";
25
+ import { createHash } from "crypto";
26
+ import { dirname, join, relative, sep } from "path";
27
+ import { retargetXcodePath, xcodePathsLeftBehind } from "./init-xcode.js";
28
+ /** The canonical schema's path, relative to the project root. */
29
+ export const CANONICAL_SCHEMA_RELATIVE = join("models", "models.toml");
30
+ /** Where a freshly scaffolded web client keeps its starter schema. */
31
+ const WEB_SCHEMA_RELATIVE = join("src", "models", "models.toml");
32
+ /** The generated barrel that imports the schema at runtime. */
33
+ const WEB_BARREL_RELATIVE = join("src", "models", "index.ts");
34
+ /** The barrel's schema import, as the generator emits it. */
35
+ const BARREL_SCHEMA_IMPORT = /(import modelsToml from\s+")([^"]+)(\?raw";)/;
36
+ /**
37
+ * A POSIX-style relative specifier from `fromDir` to `toFile`, always prefixed
38
+ * with `./` or `../` — what both an import specifier and a `-i` argument need.
39
+ */
40
+ export function relativeSchemaPath(fromDir, toFile) {
41
+ const rel = relative(fromDir, toFile).split(sep).join("/");
42
+ return rel.startsWith(".") ? rel : `./${rel}`;
43
+ }
44
+ /**
45
+ * The schema a freshly installed client template ships, or null when it has
46
+ * none (the Swift starter is comment-only but the file is still there).
47
+ */
48
+ export function findClientSchema(clientDir, platform) {
49
+ if (platform === "web") {
50
+ const path = join(clientDir, WEB_SCHEMA_RELATIVE);
51
+ return existsSync(path) ? path : null;
52
+ }
53
+ return findSwiftSchema(clientDir);
54
+ }
55
+ /** `Sources/<AppName>/Models/models.toml`, whatever the app is called. */
56
+ function findSwiftSchema(clientDir) {
57
+ const sources = join(clientDir, "Sources");
58
+ let entries;
59
+ try {
60
+ entries = readdirSync(sources);
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ for (const entry of entries) {
66
+ const candidate = join(sources, entry, "Models", "models.toml");
67
+ if (existsSync(candidate))
68
+ return candidate;
69
+ }
70
+ return null;
71
+ }
72
+ /** The Swift target's source directory (`Sources/<AppName>`), if there is one. */
73
+ export function findSwiftTargetDir(clientDir) {
74
+ const schema = findSwiftSchema(clientDir);
75
+ if (schema)
76
+ return dirname(dirname(schema));
77
+ const sources = join(clientDir, "Sources");
78
+ try {
79
+ const dirs = readdirSync(sources, { withFileTypes: true }).filter((e) => e.isDirectory());
80
+ return dirs.length === 1 ? join(sources, dirs[0].name) : null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * The models a schema declares, in the order it declares them.
88
+ *
89
+ * `[models.<name>]`, `[models.<name>.fields.<field>]` and the array form all
90
+ * name the same model; the loader treats the first path segment after `models`
91
+ * as the model name, and so does this.
92
+ */
93
+ export function declaredModelNames(toml) {
94
+ const names = [];
95
+ for (const match of toml.matchAll(/^\s*\[\[?models\.([A-Za-z0-9_-]+)/gm)) {
96
+ if (!names.includes(match[1]))
97
+ names.push(match[1]);
98
+ }
99
+ return names;
100
+ }
101
+ /**
102
+ * Splits a schema into the raw text of each model it declares, keyed by model
103
+ * name and in declaration order. A model declared by several tables (one per
104
+ * field, which is how both starters spell it) comes back as one entry, and the
105
+ * comment lines introducing a table stay with it.
106
+ */
107
+ function modelSections(toml) {
108
+ const sections = new Map();
109
+ let current = null;
110
+ let pending = "";
111
+ const append = (model, text) => {
112
+ sections.set(model, (sections.get(model) ?? "") + text);
113
+ };
114
+ for (const line of toml.split("\n")) {
115
+ const header = line.match(/^\s*\[\[?([A-Za-z0-9_.\-]+)/);
116
+ if (header) {
117
+ current = header[1].startsWith("models.")
118
+ ? header[1].slice("models.".length).split(".")[0]
119
+ : null;
120
+ if (current)
121
+ append(current, `${pending}${line}\n`);
122
+ pending = "";
123
+ continue;
124
+ }
125
+ // A comment or a blank line introduces whatever comes next as often as it
126
+ // closes what came before — hold it until the next line says which.
127
+ if (line.trim() === "" || line.trimStart().startsWith("#")) {
128
+ pending += `${line}\n`;
129
+ continue;
130
+ }
131
+ if (current)
132
+ append(current, `${pending}${line}\n`);
133
+ pending = "";
134
+ }
135
+ return sections;
136
+ }
137
+ /**
138
+ * The app's one schema has to declare every model its clients read.
139
+ *
140
+ * A client's template ships both a starter schema and code generated from it —
141
+ * the web template's store reads `UserPref`, and the model generator refuses a
142
+ * schema with no models at all. So composing the shared schema is not "pick a
143
+ * starter": it is the base schema (an existing client's, when one is being
144
+ * promoted) PLUS every model a client being added declares and the base does
145
+ * not. Nothing is ever overwritten — a model the base already declares is the
146
+ * app's definition of it, and stays exactly as it is.
147
+ */
148
+ export function composeSchemaContent(input) {
149
+ let content = input.base;
150
+ const added = [];
151
+ const declared = declaredModelNames(content);
152
+ for (const starter of input.starters) {
153
+ for (const [model, text] of modelSections(starter)) {
154
+ if (declared.includes(model))
155
+ continue;
156
+ declared.push(model);
157
+ added.push(model);
158
+ content = `${content.replace(/\n*$/, "\n")}\n${text.replace(/^\n*/, "").replace(/\n*$/, "\n")}`;
159
+ }
160
+ }
161
+ return { content, added };
162
+ }
163
+ /**
164
+ * Points one client at the shared schema and drops its own copy.
165
+ *
166
+ * Writes the new wiring BEFORE removing the client-local schema, so a failure
167
+ * leaves a client that still has a schema rather than one with neither.
168
+ */
169
+ export function wireClientToSchema(clientDir, platform, schemaPath) {
170
+ const blocked = checkClientWiring(clientDir, platform, schemaPath);
171
+ if (blocked)
172
+ return { rewired: [], error: blocked };
173
+ return platform === "web"
174
+ ? wireWebClient(clientDir, schemaPath)
175
+ : wireSwiftClient(clientDir, schemaPath);
176
+ }
177
+ /**
178
+ * Why this client cannot be pointed at the shared schema, or null when it can.
179
+ *
180
+ * Separate from the wiring itself because the answer decides whether the run
181
+ * happens at all: a client that keeps its own schema while the app has another
182
+ * is the two-copies layout the shared schema exists to prevent, so a caller
183
+ * asks this BEFORE it writes the shared file — before the download, when the
184
+ * client already exists.
185
+ */
186
+ export function checkClientWiring(clientDir, platform, schemaPath) {
187
+ return platform === "web"
188
+ ? checkWebWiring(clientDir, schemaPath)
189
+ : checkSwiftWiring(clientDir, schemaPath);
190
+ }
191
+ function checkWebWiring(clientDir, schemaPath) {
192
+ const packageJsonPath = join(clientDir, "package.json");
193
+ if (!existsSync(packageJsonPath)) {
194
+ return `no package.json in ${clientDir}`;
195
+ }
196
+ let pkg;
197
+ try {
198
+ pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
199
+ }
200
+ catch (err) {
201
+ return `could not parse ${packageJsonPath}: ${err.message}`;
202
+ }
203
+ const codegen = pkg.scripts?.codegen;
204
+ if (!codegen || !codegen.includes("js-bao-codegen-v2")) {
205
+ return `no js-bao-codegen-v2 step in ${packageJsonPath}`;
206
+ }
207
+ // The generated barrel imports the schema at runtime, so it and the codegen
208
+ // input have to move together: a barrel whose import this cannot rewrite
209
+ // would keep naming the copy that gets removed, and the client would fail its
210
+ // next build on a path with nothing saying the schema moved.
211
+ const barrelPath = join(clientDir, WEB_BARREL_RELATIVE);
212
+ const barrel = existsSync(barrelPath) ? readFileSync(barrelPath, "utf-8") : null;
213
+ if (barrel !== null && !BARREL_SCHEMA_IMPORT.test(barrel)) {
214
+ return (`${barrelPath} does not import its schema as \`import modelsToml from "…?raw"\`, ` +
215
+ `so it cannot be pointed at ${schemaPath} — the client keeps its own schema`);
216
+ }
217
+ return null;
218
+ }
219
+ function checkSwiftWiring(clientDir, schemaPath) {
220
+ if (!findSwiftTargetDir(clientDir)) {
221
+ return `no Sources/<App>/ directory in ${clientDir}`;
222
+ }
223
+ // The client's own schema is removed by the wiring, so every Xcode file that
224
+ // declares it has to be able to name the shared one instead. One that cannot
225
+ // is the Swift counterpart of an unrewritable barrel: the build reads a path
226
+ // that is no longer there and reports the path, not the move.
227
+ const declaredSchema = findSwiftSchema(clientDir);
228
+ if (declaredSchema && declaredSchema !== schemaPath) {
229
+ const stranded = xcodePathsLeftBehind(clientDir, relative(clientDir, declaredSchema), relative(clientDir, schemaPath));
230
+ if (stranded.length > 0) {
231
+ return (`${stranded.join(", ")} declares ${declaredSchema} as a build input in a form ` +
232
+ `this cannot point at ${schemaPath} — the client keeps its own schema`);
233
+ }
234
+ }
235
+ return null;
236
+ }
237
+ function wireWebClient(clientDir, schemaPath) {
238
+ const rewired = [];
239
+ const packageJsonPath = join(clientDir, "package.json");
240
+ // The codegen input: `-i src/models/models.toml` -> `-i ../models/models.toml`.
241
+ const inputSpecifier = relativeSchemaPath(clientDir, schemaPath);
242
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
243
+ const codegen = pkg.scripts.codegen;
244
+ const barrelPath = join(clientDir, WEB_BARREL_RELATIVE);
245
+ const barrel = existsSync(barrelPath) ? readFileSync(barrelPath, "utf-8") : null;
246
+ pkg.scripts.codegen = codegen.replace(/(-i\s+)(\S+)/, (_match, flag) => `${flag}${inputSpecifier}`);
247
+ writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`);
248
+ rewired.push(packageJsonPath);
249
+ // Rewriting the barrel's specifier here is exactly what the next
250
+ // `pnpm codegen` emits, so the scaffold runs before its first codegen and
251
+ // stays byte-identical after it.
252
+ if (barrel !== null) {
253
+ const importSpecifier = relativeSchemaPath(dirname(barrelPath), schemaPath);
254
+ const rewritten = barrel.replace(BARREL_SCHEMA_IMPORT, `$1${importSpecifier}$3`);
255
+ if (rewritten !== barrel) {
256
+ writeFileSync(barrelPath, rewritten);
257
+ rewired.push(barrelPath);
258
+ }
259
+ }
260
+ // Codegen stamps each generated file with a fingerprint of the schema it read,
261
+ // and the shared schema is the starter plus a header — a different file, and
262
+ // so a different fingerprint. Restamping them here is what the next
263
+ // `pnpm codegen` would write anyway, so the first `pnpm dev` after init leaves
264
+ // the freshly committed repository clean instead of rewriting its own files.
265
+ if (existsSync(schemaPath)) {
266
+ rewired.push(...restampGeneratedFiles(join(clientDir, "src", "models"), readFileSync(schemaPath, "utf-8")));
267
+ }
268
+ const localSchema = join(clientDir, WEB_SCHEMA_RELATIVE);
269
+ let removed;
270
+ if (existsSync(localSchema) && localSchema !== schemaPath) {
271
+ rmSync(localSchema);
272
+ removed = localSchema;
273
+ }
274
+ return { rewired, removed };
275
+ }
276
+ /**
277
+ * Rewrites the `// fingerprint:` line of every generated file in a directory to
278
+ * the one the generator computes for `schemaContent` (a 16-hex-char SHA-256
279
+ * prefix — see `fingerprintToml`). Returns the files it changed.
280
+ */
281
+ function restampGeneratedFiles(modelsDir, schemaContent) {
282
+ const fingerprint = createHash("sha256")
283
+ .update(schemaContent, "utf-8")
284
+ .digest("hex")
285
+ .slice(0, 16);
286
+ let entries;
287
+ try {
288
+ entries = readdirSync(modelsDir);
289
+ }
290
+ catch {
291
+ return [];
292
+ }
293
+ const restamped = [];
294
+ for (const entry of entries.filter((name) => name.endsWith(".ts"))) {
295
+ const path = join(modelsDir, entry);
296
+ const before = readFileSync(path, "utf-8");
297
+ const after = before.replace(/^\/\/ fingerprint: [0-9a-f]+$/m, `// fingerprint: ${fingerprint}`);
298
+ if (after === before)
299
+ continue;
300
+ writeFileSync(path, after);
301
+ restamped.push(path);
302
+ }
303
+ return restamped;
304
+ }
305
+ function wireSwiftClient(clientDir, schemaPath) {
306
+ const rewired = [];
307
+ const targetDir = findSwiftTargetDir(clientDir);
308
+ // #2889's surface: the plugin (and `scripts/generate-models.sh`) read this
309
+ // instead of scanning the target's own sources.
310
+ const configPath = join(targetDir, "bao-codegen.json");
311
+ const input = relativeSchemaPath(targetDir, schemaPath);
312
+ mkdirSync(targetDir, { recursive: true });
313
+ writeFileSync(configPath, `${JSON.stringify({ input }, null, 2)}\n`);
314
+ rewired.push(configPath);
315
+ // SwiftPM warns about a file in a target it has no rule for, so the manifest
316
+ // has to exclude the config it just gained.
317
+ const manifestPath = join(clientDir, "Package.swift");
318
+ if (existsSync(manifestPath)) {
319
+ const manifest = readFileSync(manifestPath, "utf-8");
320
+ if (!manifest.includes("bao-codegen.json")) {
321
+ const rewritten = manifest.replace(/exclude:\s*\[([^\]]*)\]/, (_match, inner) => `exclude: [${inner.trim().length > 0 ? `${inner.trimEnd()}, ` : ""}"bao-codegen.json"]`);
322
+ if (rewritten !== manifest) {
323
+ writeFileSync(manifestPath, rewritten);
324
+ rewired.push(manifestPath);
325
+ }
326
+ }
327
+ }
328
+ // The Xcode pre-build phase declares the schema as its input file, which is
329
+ // how Xcode knows to re-run codegen when the schema changes. It has to name
330
+ // the shared file too, or a build reads a path that is no longer there.
331
+ //
332
+ // `project.yml` generates the Xcode project, but the project is CHECKED IN
333
+ // and is what Xcode itself compiles, so the retarget lands in both — an
334
+ // .xcodeproj still declaring the removed copy fails the build naming a path,
335
+ // with nothing saying the schema moved.
336
+ const localSchema = findSwiftSchema(clientDir);
337
+ if (localSchema) {
338
+ rewired.push(...retargetXcodePath(clientDir, relative(clientDir, localSchema), relative(clientDir, schemaPath)));
339
+ }
340
+ let removed;
341
+ if (localSchema && localSchema !== schemaPath) {
342
+ rmSync(localSchema);
343
+ removed = localSchema;
344
+ }
345
+ return { rewired, removed };
346
+ }
347
+ /**
348
+ * Writes the canonical schema, creating `models/` if needed. Never overwrites:
349
+ * an existing shared schema is the app's, not this run's.
350
+ */
351
+ export function writeCanonicalSchema(schemaPath, content) {
352
+ if (existsSync(schemaPath))
353
+ return false;
354
+ mkdirSync(dirname(schemaPath), { recursive: true });
355
+ writeFileSync(schemaPath, content);
356
+ return true;
357
+ }
358
+ //# sourceMappingURL=init-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-schema.js","sourceRoot":"","sources":["../../../src/lib/init-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,EACN,aAAa,GACd,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG1E,iEAAiE;AACjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEvE,sEAAsE;AACtE,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEjE,+DAA+D;AAC/D,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAE9D,6DAA6D;AAC7D,MAAM,oBAAoB,GAAG,8CAA8C,CAAC;AAE5E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,MAAc;IAChE,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,QAAkB;IAElB,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;QAClD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;IACD,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,0EAA0E;AAC1E,SAAS,eAAe,CAAC,SAAiB;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAChE,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtE,CAAC,CAAC,WAAW,EAAE,CAChB,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,qCAAqC,CAAC,EAAE,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,IAAY,EAAQ,EAAE;QACnD,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACzD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;gBACvC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjD,CAAC,CAAC,IAAI,CAAC;YACT,IAAI,OAAO;gBAAE,MAAM,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC;YACpD,OAAO,GAAG,EAAE,CAAC;YACb,SAAS;QACX,CAAC;QACD,0EAA0E;QAC1E,oEAAoE;QACpE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,IAAI,GAAG,IAAI,IAAI,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,OAAO;YAAE,MAAM,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC;QACpD,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAKpC;IACC,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YACvC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,OAAO,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QAClG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,QAAkB,EAClB,UAAkB;IAElB,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACnE,IAAI,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACpD,OAAO,QAAQ,KAAK,KAAK;QACvB,CAAC,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC;QACtC,CAAC,CAAC,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,QAAkB,EAClB,UAAkB;IAElB,OAAO,QAAQ,KAAK,KAAK;QACvB,CAAC,CAAC,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC;QACvC,CAAC,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB,EAAE,UAAkB;IAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,OAAO,sBAAsB,SAAS,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,mBAAmB,eAAe,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;IAC9D,CAAC;IACD,MAAM,OAAO,GAAuB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;IACzD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACvD,OAAO,gCAAgC,eAAe,EAAE,CAAC;IAC3D,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,8EAA8E;IAC9E,6DAA6D;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,OAAO,CACL,GAAG,UAAU,qEAAqE;YAClF,8BAA8B,UAAU,oCAAoC,CAC7E,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB,EAAE,UAAkB;IAC7D,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,OAAO,kCAAkC,SAAS,EAAE,CAAC;IACvD,CAAC;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM,cAAc,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,cAAc,IAAI,cAAc,KAAK,UAAU,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,oBAAoB,CACnC,SAAS,EACT,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,EACnC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAChC,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CACL,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,cAAc,8BAA8B;gBAC/E,wBAAwB,UAAU,oCAAoC,CACvE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB,EAAE,UAAkB;IAC1D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAExD,gFAAgF;IAChF,MAAM,cAAc,GAAG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,GAAG,GAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;IACpE,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjF,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CACnC,cAAc,EACd,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,cAAc,EAAE,CAC7D,CAAC;IACF,aAAa,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE9B,iEAAiE;IACjE,0EAA0E;IAC1E,iCAAiC;IACjC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;QAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAC9B,oBAAoB,EACpB,KAAK,eAAe,IAAI,CACzB,CAAC;QACF,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,6EAA6E;IAC7E,oEAAoE;IACpE,+EAA+E;IAC/E,6EAA6E;IAC7E,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CACV,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IACzD,IAAI,OAA2B,CAAC;IAChC,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,CAAC;QACpB,OAAO,GAAG,WAAW,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,SAAiB,EAAE,aAAqB;IACrE,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC;SACrC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC;SAC9B,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,gCAAgC,EAAE,mBAAmB,WAAW,EAAE,CAAC,CAAC;QACjG,IAAI,KAAK,KAAK,MAAM;YAAE,SAAS;QAC/B,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,UAAkB;IAC5D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAE,CAAC;IAEjD,2EAA2E;IAC3E,gDAAgD;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACxD,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,aAAa,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEzB,6EAA6E;IAC7E,4CAA4C;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAChC,yBAAyB,EACzB,CAAC,MAAc,EAAE,KAAa,EAAE,EAAE,CAChC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAC1F,CAAC;YACF,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC3B,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;gBACvC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,4EAA4E;IAC5E,wEAAwE;IACxE,EAAE;IACF,2EAA2E;IAC3E,wEAAwE;IACxE,6EAA6E;IAC7E,wCAAwC;IACxC,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CACV,GAAG,iBAAiB,CAClB,SAAS,EACT,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,EAChC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAChC,CACF,CAAC;IACJ,CAAC;IAED,IAAI,OAA2B,CAAC;IAChC,IAAI,WAAW,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC9C,MAAM,CAAC,WAAW,CAAC,CAAC;QACpB,OAAO,GAAG,WAAW,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,OAAe;IACtE,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Retargets one `$(SRCROOT)`-relative build-phase path, in `project.yml` and in
3
+ * every checked-in Xcode project. Both spell the path the same way, so one
4
+ * literal substitution covers the declared inputs and outputs alike.
5
+ *
6
+ * Returns the files it rewrote.
7
+ */
8
+ export declare function retargetXcodePath(clientDir: string, fromRelative: string, toRelative: string): string[];
9
+ /**
10
+ * The Xcode files that would still name `fromRelative` after `retargetXcodePath`
11
+ * moved it to `toRelative` — spellings the substitution above does not reach,
12
+ * such as a path written without the `$(SRCROOT)/` prefix.
13
+ *
14
+ * A caller that is about to REMOVE the file at `fromRelative` asks this first:
15
+ * a project left declaring it has a build input that is not there, and Xcode
16
+ * reports the path rather than the move that stranded it.
17
+ */
18
+ export declare function xcodePathsLeftBehind(clientDir: string, fromRelative: string, toRelative: string): string[];
19
+ /**
20
+ * Points the Xcode build phases at the app's `.primitive/config.json` when it
21
+ * lives above the client.
22
+ *
23
+ * Without this an Xcode build has no readable config: the phase declares
24
+ * `$(SRCROOT)/.primitive/config.json`, which a composed client does not have,
25
+ * and the sandbox denies everything undeclared. A fresh clone (where
26
+ * `primitive.json` is gitignored) then cannot build at all, and a working copy
27
+ * that still has one keeps whichever environment generated it — so
28
+ * `primitive env use` would leave Xcode builds on the old backend.
29
+ *
30
+ * Returns the files it rewrote; an empty list means the client was already
31
+ * pointed at its own root (a standalone scaffold) or ships no Xcode project.
32
+ */
33
+ export declare function declareSharedProjectConfig(clientDir: string, projectRoot: string): string[];
@@ -0,0 +1,114 @@
1
+ /**
2
+ * The Swift client's Xcode project, when the app it belongs to lives above it
3
+ * (#2890).
4
+ *
5
+ * `project.yml` is the source of truth, but the `.xcodeproj` it generates is
6
+ * CHECKED IN — that is what Xcode's Run button, a bare `xcodebuild` and a fresh
7
+ * clone all compile. A composed repository moves two files the Xcode build
8
+ * phases declare out of the client: the model schema (up to `models/` at the
9
+ * root) and `.primitive/config.json` (which the whole app shares). Rewriting
10
+ * only `project.yml` would leave the shipped project declaring paths that are
11
+ * no longer there — a build input error naming a file, with nothing saying the
12
+ * schema moved — so every rewrite here lands in both places.
13
+ *
14
+ * The declared inputs are also what Xcode's user-script sandbox permits a phase
15
+ * to READ. Declaring the root config is what lets `resolve-primitive-config.sh`
16
+ * find it from inside an Xcode build at all.
17
+ */
18
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from "fs";
19
+ import { join, relative, sep } from "path";
20
+ /** The build phase inputs that name the project config, relative to a client. */
21
+ const PROJECT_CONFIG_INPUTS = [
22
+ join(".primitive", "config.json"),
23
+ join(".primitive", "local.json"),
24
+ ];
25
+ /** A POSIX-style path from `fromDir` to `toPath`, for a build-setting string. */
26
+ function posixRelative(fromDir, toPath) {
27
+ return relative(fromDir, toPath).split(sep).join("/");
28
+ }
29
+ /** Every checked-in `project.pbxproj` beside the client's sources. */
30
+ function findPbxprojFiles(clientDir) {
31
+ let entries;
32
+ try {
33
+ entries = readdirSync(clientDir);
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ return entries
39
+ .filter((entry) => entry.endsWith(".xcodeproj"))
40
+ .map((entry) => join(clientDir, entry, "project.pbxproj"))
41
+ .filter((path) => existsSync(path));
42
+ }
43
+ /**
44
+ * Retargets one `$(SRCROOT)`-relative build-phase path, in `project.yml` and in
45
+ * every checked-in Xcode project. Both spell the path the same way, so one
46
+ * literal substitution covers the declared inputs and outputs alike.
47
+ *
48
+ * Returns the files it rewrote.
49
+ */
50
+ export function retargetXcodePath(clientDir, fromRelative, toRelative) {
51
+ const from = `$(SRCROOT)/${fromRelative.split(sep).join("/")}`;
52
+ const to = `$(SRCROOT)/${toRelative.split(sep).join("/")}`;
53
+ if (from === to)
54
+ return [];
55
+ const rewritten = [];
56
+ for (const path of [join(clientDir, "project.yml"), ...findPbxprojFiles(clientDir)]) {
57
+ if (!existsSync(path))
58
+ continue;
59
+ const before = readFileSync(path, "utf-8");
60
+ const after = before.split(from).join(to);
61
+ if (after === before)
62
+ continue;
63
+ writeFileSync(path, after);
64
+ rewritten.push(path);
65
+ }
66
+ return rewritten;
67
+ }
68
+ /**
69
+ * The Xcode files that would still name `fromRelative` after `retargetXcodePath`
70
+ * moved it to `toRelative` — spellings the substitution above does not reach,
71
+ * such as a path written without the `$(SRCROOT)/` prefix.
72
+ *
73
+ * A caller that is about to REMOVE the file at `fromRelative` asks this first:
74
+ * a project left declaring it has a build input that is not there, and Xcode
75
+ * reports the path rather than the move that stranded it.
76
+ */
77
+ export function xcodePathsLeftBehind(clientDir, fromRelative, toRelative) {
78
+ const from = `$(SRCROOT)/${fromRelative.split(sep).join("/")}`;
79
+ const to = `$(SRCROOT)/${toRelative.split(sep).join("/")}`;
80
+ if (from === to)
81
+ return [];
82
+ const stranded = [];
83
+ for (const path of [join(clientDir, "project.yml"), ...findPbxprojFiles(clientDir)]) {
84
+ if (!existsSync(path))
85
+ continue;
86
+ const retargeted = readFileSync(path, "utf-8").split(from).join(to);
87
+ if (retargeted.includes(fromRelative.split(sep).join("/")))
88
+ stranded.push(path);
89
+ }
90
+ return stranded;
91
+ }
92
+ /**
93
+ * Points the Xcode build phases at the app's `.primitive/config.json` when it
94
+ * lives above the client.
95
+ *
96
+ * Without this an Xcode build has no readable config: the phase declares
97
+ * `$(SRCROOT)/.primitive/config.json`, which a composed client does not have,
98
+ * and the sandbox denies everything undeclared. A fresh clone (where
99
+ * `primitive.json` is gitignored) then cannot build at all, and a working copy
100
+ * that still has one keeps whichever environment generated it — so
101
+ * `primitive env use` would leave Xcode builds on the old backend.
102
+ *
103
+ * Returns the files it rewrote; an empty list means the client was already
104
+ * pointed at its own root (a standalone scaffold) or ships no Xcode project.
105
+ */
106
+ export function declareSharedProjectConfig(clientDir, projectRoot) {
107
+ const rewritten = [];
108
+ for (const input of PROJECT_CONFIG_INPUTS) {
109
+ const target = posixRelative(clientDir, join(projectRoot, input));
110
+ rewritten.push(...retargetXcodePath(clientDir, input, target));
111
+ }
112
+ return rewritten;
113
+ }
114
+ //# sourceMappingURL=init-xcode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-xcode.js","sourceRoot":"","sources":["../../../src/lib/init-xcode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The CLI's mirror of the server's integration `requestConfig` normalization
3
+ * (issue #2880, DSO-003).
4
+ *
5
+ * `normalizeIntegrationRequestConfig` (`src/services/integration-utils.ts`)
6
+ * rewrites an accepted request config on the way in: the base URL gains a
7
+ * single trailing slash, methods are upper-cased and de-duplicated, header and
8
+ * query lists are trimmed, and the optional keys are materialized. So the state
9
+ * the server RETURNS is not the text a hand-authored file holds — and comparing
10
+ * the two raw makes an authored integration read `local-edited` on every run,
11
+ * with push re-applying the same update forever. Baseline restamping cannot
12
+ * save it: after an apply the remote hash equals the fresh baseline while the
13
+ * local hash still does not.
14
+ *
15
+ * Mirrored rather than imported: the published CLI must not import server
16
+ * `src/` at runtime (the same rule the vendored config surfaces follow). The
17
+ * acceptance fixture pinning this mirror is the tripwire if the server's rule
18
+ * moves — a disagreement then shows as an ordinary `Modified` row, never a
19
+ * crash, which is why every step here is total: an input the server would
20
+ * REJECT (a missing base URL, a bogus method) is left exactly as authored so
21
+ * the server's own error is what the operator sees.
22
+ */
23
+ /**
24
+ * The request config as the server would store it, from what the file says.
25
+ *
26
+ * Applied to BOTH sides of the comparison (the remote side reaches it through
27
+ * the same projection), which is safe because the server's own output is
28
+ * already canonical and this is idempotent.
29
+ */
30
+ export declare function canonicalizeIntegrationRequestConfig(input: unknown): any;