primitive-admin 1.1.0-alpha.7 → 1.1.0-alpha.71
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.
- package/README.md +404 -80
- package/assets/skill/skills/primitive-platform/SKILL.md +808 -0
- package/dist/bin/primitive.d.ts +2 -0
- package/dist/bin/primitive.js +294 -21
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.d.ts +2 -0
- package/dist/src/commands/admins.js +138 -19
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +2 -0
- package/dist/src/commands/analytics.js +544 -55
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.d.ts +2 -0
- package/dist/src/commands/apps.js +51 -96
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +177 -7
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.d.ts +2 -0
- package/dist/src/commands/blob-buckets.js +330 -0
- package/dist/src/commands/blob-buckets.js.map +1 -0
- package/dist/src/commands/catalog.d.ts +2 -0
- package/dist/src/commands/catalog.js +37 -38
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.d.ts +2 -0
- package/dist/src/commands/collection-type-configs.js +92 -0
- package/dist/src/commands/collection-type-configs.js.map +1 -0
- package/dist/src/commands/collections.d.ts +2 -0
- package/dist/src/commands/collections.js +565 -0
- package/dist/src/commands/collections.js.map +1 -0
- package/dist/src/commands/comparisons.d.ts +2 -0
- package/dist/src/commands/comparisons.js +6 -6
- package/dist/src/commands/comparisons.js.map +1 -1
- package/dist/src/commands/config.d.ts +46 -0
- package/dist/src/commands/config.js +479 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/connections.d.ts +2 -0
- package/dist/src/commands/connections.js +100 -0
- package/dist/src/commands/connections.js.map +1 -0
- package/dist/src/commands/cron-triggers.d.ts +2 -0
- package/dist/src/commands/cron-triggers.js +265 -0
- package/dist/src/commands/cron-triggers.js.map +1 -0
- package/dist/src/commands/database-type-configs.d.ts +2 -0
- package/dist/src/commands/database-type-configs.js +171 -0
- package/dist/src/commands/database-type-configs.js.map +1 -0
- package/dist/src/commands/database-types.d.ts +2 -0
- package/dist/src/commands/database-types.js +471 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.d.ts +65 -0
- package/dist/src/commands/databases.js +2140 -112
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +2 -0
- package/dist/src/commands/documents.js +1357 -19
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.d.ts +2 -0
- package/dist/src/commands/email-templates.js +174 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/env.d.ts +23 -0
- package/dist/src/commands/env.js +333 -0
- package/dist/src/commands/env.js.map +1 -0
- package/dist/src/commands/feature-flags.d.ts +14 -0
- package/dist/src/commands/feature-flags.js +116 -0
- package/dist/src/commands/feature-flags.js.map +1 -0
- package/dist/src/commands/group-type-configs.d.ts +2 -0
- package/dist/src/commands/group-type-configs.js +86 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.d.ts +2 -0
- package/dist/src/commands/groups.js +38 -99
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.d.ts +223 -0
- package/dist/src/commands/guides.js +617 -65
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +25 -0
- package/dist/src/commands/init.js +1605 -208
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.d.ts +2 -0
- package/dist/src/commands/integrations.js +380 -178
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/llm.d.ts +2 -0
- package/dist/src/commands/llm.js +4 -2
- package/dist/src/commands/llm.js.map +1 -1
- package/dist/src/commands/locks.d.ts +8 -0
- package/dist/src/commands/locks.js +160 -0
- package/dist/src/commands/locks.js.map +1 -0
- package/dist/src/commands/metadata-category-configs.d.ts +12 -0
- package/dist/src/commands/metadata-category-configs.js +112 -0
- package/dist/src/commands/metadata-category-configs.js.map +1 -0
- package/dist/src/commands/metadata.d.ts +2 -0
- package/dist/src/commands/metadata.js +281 -0
- package/dist/src/commands/metadata.js.map +1 -0
- package/dist/src/commands/prompts.d.ts +2 -0
- package/dist/src/commands/prompts.js +225 -584
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +3 -0
- package/dist/src/commands/rule-sets.js +272 -0
- package/dist/src/commands/rule-sets.js.map +1 -0
- package/dist/src/commands/scripts.d.ts +20 -0
- package/dist/src/commands/scripts.js +554 -0
- package/dist/src/commands/scripts.js.map +1 -0
- package/dist/src/commands/secrets.d.ts +2 -0
- package/dist/src/commands/secrets.js +108 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/sessions.d.ts +2 -0
- package/dist/src/commands/sessions.js +75 -0
- package/dist/src/commands/sessions.js.map +1 -0
- package/dist/src/commands/skill.d.ts +2 -0
- package/dist/src/commands/skill.js +29 -0
- package/dist/src/commands/skill.js.map +1 -0
- package/dist/src/commands/sync-app-settings.d.ts +158 -0
- package/dist/src/commands/sync-app-settings.js +330 -0
- package/dist/src/commands/sync-app-settings.js.map +1 -0
- package/dist/src/commands/sync.d.ts +2323 -0
- package/dist/src/commands/sync.js +15065 -843
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.d.ts +2 -0
- package/dist/src/commands/tokens.js +130 -21
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.d.ts +2 -0
- package/dist/src/commands/users.js +532 -23
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.d.ts +8 -0
- package/dist/src/commands/vars.js +96 -0
- package/dist/src/commands/vars.js.map +1 -0
- package/dist/src/commands/waitlist.d.ts +2 -0
- package/dist/src/commands/waitlist.js +10 -10
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +2 -0
- package/dist/src/commands/webhooks.js +562 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.d.ts +116 -0
- package/dist/src/commands/workflows.js +1583 -681
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/access-rule-display.d.ts +21 -0
- package/dist/src/lib/access-rule-display.js +34 -0
- package/dist/src/lib/access-rule-display.js.map +1 -0
- package/dist/src/lib/api-client.d.ts +1936 -0
- package/dist/src/lib/api-client.js +1826 -138
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +263 -0
- package/dist/src/lib/app-settings-descriptor.js +575 -0
- package/dist/src/lib/app-settings-descriptor.js.map +1 -0
- package/dist/src/lib/auth-flow.d.ts +8 -0
- package/dist/src/lib/batch.d.ts +26 -0
- package/dist/src/lib/batch.js +32 -0
- package/dist/src/lib/batch.js.map +1 -0
- package/dist/src/lib/block-layout.d.ts +160 -0
- package/dist/src/lib/block-layout.js +451 -0
- package/dist/src/lib/block-layout.js.map +1 -0
- package/dist/src/lib/canonical-json.d.ts +12 -0
- package/dist/src/lib/canonical-json.js +35 -0
- package/dist/src/lib/canonical-json.js.map +1 -0
- package/dist/src/lib/channel.d.ts +30 -0
- package/dist/src/lib/channel.js +68 -0
- package/dist/src/lib/channel.js.map +1 -0
- package/dist/src/lib/cli-manifest.d.ts +68 -0
- package/dist/src/lib/cli-manifest.js +71 -0
- package/dist/src/lib/cli-manifest.js.map +1 -0
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +101 -0
- package/dist/src/lib/codegen-shared/generatedFiles.js +191 -0
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -0
- package/dist/src/lib/codegen-shared/prettierStable.d.ts +262 -0
- package/dist/src/lib/codegen-shared/prettierStable.js +610 -0
- package/dist/src/lib/codegen-shared/prettierStable.js.map +1 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +68 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +168 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
- package/dist/src/lib/config-object-descriptor.d.ts +127 -0
- package/dist/src/lib/config-object-descriptor.js +658 -0
- package/dist/src/lib/config-object-descriptor.js.map +1 -0
- package/dist/src/lib/config-payload.d.ts +85 -0
- package/dist/src/lib/config-payload.js +116 -0
- package/dist/src/lib/config-payload.js.map +1 -0
- package/dist/src/lib/config-surface.d.ts +130 -0
- package/dist/src/lib/config-surface.js +300 -0
- package/dist/src/lib/config-surface.js.map +1 -0
- package/dist/src/lib/config-toml.d.ts +10 -0
- package/dist/src/lib/config-toml.js +42 -0
- package/dist/src/lib/config-toml.js.map +1 -0
- package/dist/src/lib/config.d.ts +53 -0
- package/dist/src/lib/config.js +92 -53
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/confirm-prompt.d.ts +83 -0
- package/dist/src/lib/confirm-prompt.js +110 -0
- package/dist/src/lib/confirm-prompt.js.map +1 -0
- package/dist/src/lib/constants.d.ts +11 -0
- package/dist/src/lib/constants.js +12 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/crash-handlers.d.ts +20 -0
- package/dist/src/lib/crash-handlers.js +49 -0
- package/dist/src/lib/crash-handlers.js.map +1 -0
- package/dist/src/lib/credentials-store.d.ts +89 -0
- package/dist/src/lib/credentials-store.js +330 -0
- package/dist/src/lib/credentials-store.js.map +1 -0
- package/dist/src/lib/csv.d.ts +47 -0
- package/dist/src/lib/csv.js +172 -0
- package/dist/src/lib/csv.js.map +1 -0
- package/dist/src/lib/data-input.d.ts +23 -0
- package/dist/src/lib/data-input.js +50 -0
- package/dist/src/lib/data-input.js.map +1 -0
- package/dist/src/lib/db-codegen/dbFingerprint.d.ts +10 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js +17 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js.map +1 -0
- package/dist/src/lib/db-codegen/dbGenerator.d.ts +67 -0
- package/dist/src/lib/db-codegen/dbGenerator.js +170 -0
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/db-codegen/dbNaming.d.ts +87 -0
- package/dist/src/lib/db-codegen/dbNaming.js +180 -0
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +272 -0
- package/dist/src/lib/db-codegen/dbTemplates.js +480 -0
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTsTypes.d.ts +73 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js +139 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +146 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js +517 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.d.ts +112 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js +211 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js.map +1 -0
- package/dist/src/lib/env-resolver-core.d.ts +147 -0
- package/dist/src/lib/env-resolver-core.js +265 -0
- package/dist/src/lib/env-resolver-core.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +84 -0
- package/dist/src/lib/env-resolver.js +133 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/fetch.d.ts +5 -0
- package/dist/src/lib/generated-allowlist.d.ts +28 -0
- package/dist/src/lib/generated-allowlist.js +277 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -0
- package/dist/src/lib/generated-config-surfaces.d.ts +682 -0
- package/dist/src/lib/generated-config-surfaces.js +4058 -0
- package/dist/src/lib/generated-config-surfaces.js.map +1 -0
- package/dist/src/lib/generated-template-lint.d.ts +212 -0
- package/dist/src/lib/generated-template-lint.js +624 -0
- package/dist/src/lib/generated-template-lint.js.map +1 -0
- package/dist/src/lib/init-adopt.d.ts +16 -0
- package/dist/src/lib/init-adopt.js +34 -0
- package/dist/src/lib/init-adopt.js.map +1 -0
- package/dist/src/lib/init-assets.d.ts +39 -0
- package/dist/src/lib/init-assets.js +97 -0
- package/dist/src/lib/init-assets.js.map +1 -0
- package/dist/src/lib/init-config.d.ts +98 -0
- package/dist/src/lib/init-config.js +186 -0
- package/dist/src/lib/init-config.js.map +1 -0
- package/dist/src/lib/init-ios-links.d.ts +50 -0
- package/dist/src/lib/init-ios-links.js +153 -0
- package/dist/src/lib/init-ios-links.js.map +1 -0
- package/dist/src/lib/init-plan.d.ts +80 -0
- package/dist/src/lib/init-plan.js +95 -0
- package/dist/src/lib/init-plan.js.map +1 -0
- package/dist/src/lib/init-production-env.d.ts +48 -0
- package/dist/src/lib/init-production-env.js +59 -0
- package/dist/src/lib/init-production-env.js.map +1 -0
- package/dist/src/lib/init-schema.d.ts +74 -0
- package/dist/src/lib/init-schema.js +358 -0
- package/dist/src/lib/init-schema.js.map +1 -0
- package/dist/src/lib/init-xcode.d.ts +33 -0
- package/dist/src/lib/init-xcode.js +114 -0
- package/dist/src/lib/init-xcode.js.map +1 -0
- package/dist/src/lib/integration-request-config.d.ts +30 -0
- package/dist/src/lib/integration-request-config.js +145 -0
- package/dist/src/lib/integration-request-config.js.map +1 -0
- package/dist/src/lib/local-state.d.ts +55 -0
- package/dist/src/lib/local-state.js +167 -0
- package/dist/src/lib/local-state.js.map +1 -0
- package/dist/src/lib/log-inspection.d.ts +568 -0
- package/dist/src/lib/log-inspection.js +639 -0
- package/dist/src/lib/log-inspection.js.map +1 -0
- package/dist/src/lib/migration-nag.d.ts +49 -0
- package/dist/src/lib/migration-nag.js +163 -0
- package/dist/src/lib/migration-nag.js.map +1 -0
- package/dist/src/lib/object-status-filter.d.ts +22 -0
- package/dist/src/lib/object-status-filter.js +45 -0
- package/dist/src/lib/object-status-filter.js.map +1 -0
- package/dist/src/lib/output.d.ts +109 -0
- package/dist/src/lib/output.js +191 -8
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/package-manager.d.ts +140 -0
- package/dist/src/lib/package-manager.js +305 -0
- package/dist/src/lib/package-manager.js.map +1 -0
- package/dist/src/lib/paginate.d.ts +83 -0
- package/dist/src/lib/paginate.js +95 -0
- package/dist/src/lib/paginate.js.map +1 -0
- package/dist/src/lib/platform-owned.d.ts +63 -0
- package/dist/src/lib/platform-owned.js +85 -0
- package/dist/src/lib/platform-owned.js.map +1 -0
- package/dist/src/lib/project-config.d.ts +97 -0
- package/dist/src/lib/project-config.js +217 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/query-operators.d.ts +43 -0
- package/dist/src/lib/query-operators.js +80 -0
- package/dist/src/lib/query-operators.js.map +1 -0
- package/dist/src/lib/record-filter.d.ts +18 -0
- package/dist/src/lib/record-filter.js +55 -0
- package/dist/src/lib/record-filter.js.map +1 -0
- package/dist/src/lib/refresh-admin-credentials.d.ts +65 -0
- package/dist/src/lib/refresh-admin-credentials.js +103 -0
- package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
- package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
- package/dist/src/lib/resolve-init-dev-port.js +55 -0
- package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
- package/dist/src/lib/resolve-init-server.d.ts +64 -0
- package/dist/src/lib/resolve-init-server.js +77 -0
- package/dist/src/lib/resolve-init-server.js.map +1 -0
- package/dist/src/lib/resolve-platform.d.ts +74 -0
- package/dist/src/lib/resolve-platform.js +105 -0
- package/dist/src/lib/resolve-platform.js.map +1 -0
- package/dist/src/lib/run-status.d.ts +19 -0
- package/dist/src/lib/run-status.generated.d.ts +39 -0
- package/dist/src/lib/run-status.generated.js +66 -0
- package/dist/src/lib/run-status.generated.js.map +1 -0
- package/dist/src/lib/run-status.js +19 -0
- package/dist/src/lib/run-status.js.map +1 -0
- package/dist/src/lib/server-text-normalization.d.ts +51 -0
- package/dist/src/lib/server-text-normalization.js +90 -0
- package/dist/src/lib/server-text-normalization.js.map +1 -0
- package/dist/src/lib/server-url.d.ts +22 -0
- package/dist/src/lib/server-url.js +33 -0
- package/dist/src/lib/server-url.js.map +1 -0
- package/dist/src/lib/signing-secret-status.d.ts +81 -0
- package/dist/src/lib/signing-secret-status.js +116 -0
- package/dist/src/lib/signing-secret-status.js.map +1 -0
- package/dist/src/lib/skill-installer.d.ts +25 -0
- package/dist/src/lib/skill-installer.js +266 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +99 -0
- package/dist/src/lib/snapshots.js +357 -0
- package/dist/src/lib/snapshots.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +113 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js +914 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
- package/dist/src/lib/swift-codegen/generator.d.ts +94 -0
- package/dist/src/lib/swift-codegen/generator.js +440 -0
- package/dist/src/lib/swift-codegen/generator.js.map +1 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +72 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js +644 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +94 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js +155 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -0
- package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
- package/dist/src/lib/sync-dir-selector.d.ts +21 -0
- package/dist/src/lib/sync-dir-selector.js +30 -0
- package/dist/src/lib/sync-dir-selector.js.map +1 -0
- package/dist/src/lib/sync-paths.d.ts +111 -0
- package/dist/src/lib/sync-paths.js +198 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/sync-resource-types.d.ts +544 -0
- package/dist/src/lib/sync-resource-types.js +975 -0
- package/dist/src/lib/sync-resource-types.js.map +1 -0
- package/dist/src/lib/sync-selectors.d.ts +95 -0
- package/dist/src/lib/sync-selectors.js +228 -0
- package/dist/src/lib/sync-selectors.js.map +1 -0
- package/dist/src/lib/template.d.ts +170 -0
- package/dist/src/lib/template.js +484 -68
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/test-case-keys.d.ts +29 -0
- package/dist/src/lib/test-case-keys.js +55 -0
- package/dist/src/lib/test-case-keys.js.map +1 -0
- package/dist/src/lib/test-case-variables.d.ts +15 -0
- package/dist/src/lib/test-case-variables.js +29 -0
- package/dist/src/lib/test-case-variables.js.map +1 -0
- package/dist/src/lib/token-inject.d.ts +56 -0
- package/dist/src/lib/token-inject.js +204 -0
- package/dist/src/lib/token-inject.js.map +1 -0
- package/dist/src/lib/toml-database-config.d.ts +123 -0
- package/dist/src/lib/toml-database-config.js +527 -0
- package/dist/src/lib/toml-database-config.js.map +1 -0
- package/dist/src/lib/toml-metadata-config.d.ts +151 -0
- package/dist/src/lib/toml-metadata-config.js +476 -0
- package/dist/src/lib/toml-metadata-config.js.map +1 -0
- package/dist/src/lib/toml-native-form.d.ts +46 -0
- package/dist/src/lib/toml-native-form.js +78 -0
- package/dist/src/lib/toml-native-form.js.map +1 -0
- package/dist/src/lib/toml-params-validator.d.ts +129 -0
- package/dist/src/lib/toml-params-validator.js +298 -0
- package/dist/src/lib/toml-params-validator.js.map +1 -0
- package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
- package/dist/src/lib/toml-scalar-edit.js +283 -0
- package/dist/src/lib/toml-scalar-edit.js.map +1 -0
- package/dist/src/lib/user-selector.d.ts +24 -0
- package/dist/src/lib/user-selector.js +33 -0
- package/dist/src/lib/user-selector.js.map +1 -0
- package/dist/src/lib/version-check.d.ts +35 -0
- package/dist/src/lib/version-check.js +241 -0
- package/dist/src/lib/version-check.js.map +1 -0
- package/dist/src/lib/watch.d.ts +121 -0
- package/dist/src/lib/watch.js +169 -0
- package/dist/src/lib/watch.js.map +1 -0
- package/dist/src/lib/workflow-apply.d.ts +110 -0
- package/dist/src/lib/workflow-apply.js +164 -0
- package/dist/src/lib/workflow-apply.js.map +1 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +129 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +269 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -0
- package/dist/src/lib/workflow-codegen/generator.d.ts +96 -0
- package/dist/src/lib/workflow-codegen/generator.js +361 -0
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -0
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +94 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js +76 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
- package/dist/src/lib/workflow-codegen/naming.d.ts +33 -0
- package/dist/src/lib/workflow-codegen/naming.js +81 -0
- package/dist/src/lib/workflow-codegen/naming.js.map +1 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +80 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.js +303 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -0
- package/dist/src/lib/workflow-config-apply.d.ts +70 -0
- package/dist/src/lib/workflow-config-apply.js +137 -0
- package/dist/src/lib/workflow-config-apply.js.map +1 -0
- package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
- package/dist/src/lib/workflow-config-sidecar.js +96 -0
- package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
- package/dist/src/lib/workflow-defaults.d.ts +29 -0
- package/dist/src/lib/workflow-defaults.js +41 -0
- package/dist/src/lib/workflow-defaults.js.map +1 -0
- package/dist/src/lib/workflow-fragments.d.ts +64 -0
- package/dist/src/lib/workflow-fragments.js +342 -0
- package/dist/src/lib/workflow-fragments.js.map +1 -0
- package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
- package/dist/src/lib/workflow-include-preserve.js +286 -0
- package/dist/src/lib/workflow-include-preserve.js.map +1 -0
- package/dist/src/lib/workflow-payload.d.ts +98 -0
- package/dist/src/lib/workflow-payload.js +178 -0
- package/dist/src/lib/workflow-payload.js.map +1 -0
- package/dist/src/lib/workflow-toml-validator.d.ts +202 -0
- package/dist/src/lib/workflow-toml-validator.js +757 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- package/dist/src/types/index.d.ts +581 -0
- package/dist/src/validators.d.ts +65 -0
- package/dist/src/validators.js +64 -0
- package/dist/src/validators.js.map +1 -0
- package/package.json +32 -8
package/dist/src/lib/template.js
CHANGED
|
@@ -1,8 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cpSync, existsSync, mkdtempSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from "fs";
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
2
3
|
import { join } from "path";
|
|
4
|
+
import { tmpdir } from "os";
|
|
3
5
|
import * as tar from "tar";
|
|
4
|
-
|
|
6
|
+
import { PRODUCTION_SERVER_URL } from "./constants.js";
|
|
7
|
+
import { installArgv, PRIMITIVE_CLI_PACKAGE } from "./package-manager.js";
|
|
8
|
+
import { resolveChannelBranch, DEFAULT_CHANNEL_BRANCH } from "./channel.js";
|
|
9
|
+
// Mirror repos pushed from this monorepo at publish time:
|
|
10
|
+
// templates/primitive-vue-template via scripts/sync-vue-template.mjs, and
|
|
11
|
+
// templates/primitive-swift-template via scripts/publish-swift-packages.sh.
|
|
12
|
+
// The branch is the channel (issue #1934): `main` = production, `alpha` =
|
|
13
|
+
// the alpha environment (its Primitive deps are pinned to the alpha
|
|
14
|
+
// prerelease npm versions / mirror branches).
|
|
15
|
+
export function vueTemplateUrl(branch = DEFAULT_CHANNEL_BRANCH) {
|
|
16
|
+
return `https://github.com/Primitive-Labs/primitive-vue-template/archive/refs/heads/${branch}.tar.gz`;
|
|
17
|
+
}
|
|
18
|
+
export function iosTemplateUrl(branch = DEFAULT_CHANNEL_BRANCH) {
|
|
19
|
+
return `https://api.github.com/repos/Primitive-Labs/primitive-swift-template/tarball/${branch}`;
|
|
20
|
+
}
|
|
21
|
+
const TEMPLATE_URL = vueTemplateUrl();
|
|
22
|
+
const IOS_TEMPLATE_URL = iosTemplateUrl();
|
|
23
|
+
/**
|
|
24
|
+
* Resolve which template branch `primitive init` scaffolds from — same
|
|
25
|
+
* precedence as `primitive guides` (see resolveChannelBranch): the
|
|
26
|
+
* undocumented `PRIMITIVE_TEMPLATE_BRANCH` override (validated), then alpha
|
|
27
|
+
* server-URL detection, then `main`.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveTemplateBranch(serverUrl, override = process.env.PRIMITIVE_TEMPLATE_BRANCH) {
|
|
30
|
+
return resolveChannelBranch(serverUrl, override, "PRIMITIVE_TEMPLATE_BRANCH");
|
|
31
|
+
}
|
|
5
32
|
const DOWNLOAD_TIMEOUT_MS = 30000; // 30 seconds
|
|
33
|
+
/**
|
|
34
|
+
* Tries to get a GitHub token from the gh CLI for authenticated downloads.
|
|
35
|
+
* Returns null if gh is not installed or not authenticated.
|
|
36
|
+
*/
|
|
37
|
+
async function getGitHubToken() {
|
|
38
|
+
const { execSync } = await import("child_process");
|
|
39
|
+
try {
|
|
40
|
+
return execSync("gh auth token", { stdio: ["ignore", "pipe", "ignore"] })
|
|
41
|
+
.toString()
|
|
42
|
+
.trim();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
6
48
|
/**
|
|
7
49
|
* Check if a directory is empty.
|
|
8
50
|
*/
|
|
@@ -13,21 +55,21 @@ export function isDirectoryEmpty(dir) {
|
|
|
13
55
|
const files = readdirSync(dir);
|
|
14
56
|
return files.length === 0;
|
|
15
57
|
}
|
|
16
|
-
|
|
17
|
-
* Downloads and extracts the Primitive app template.
|
|
18
|
-
* The tarball extracts to a subfolder, so we strip that prefix by moving contents up.
|
|
19
|
-
*/
|
|
20
|
-
export async function downloadAndExtractTemplate(options) {
|
|
21
|
-
const { targetDir, onProgress } = options;
|
|
22
|
-
// Ensure target directory exists
|
|
23
|
-
mkdirSync(targetDir, { recursive: true });
|
|
24
|
-
onProgress?.("Downloading template...");
|
|
58
|
+
async function fetchTemplateTarball(url) {
|
|
25
59
|
// Fetch the tarball with timeout
|
|
26
60
|
const controller = new AbortController();
|
|
27
61
|
const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
|
|
28
62
|
let response;
|
|
29
63
|
try {
|
|
30
|
-
|
|
64
|
+
const headers = {
|
|
65
|
+
"User-Agent": "primitive-cli",
|
|
66
|
+
};
|
|
67
|
+
// For private repos, use GitHub token if available (from gh CLI)
|
|
68
|
+
const ghToken = await getGitHubToken();
|
|
69
|
+
if (ghToken) {
|
|
70
|
+
headers["Authorization"] = `token ${ghToken}`;
|
|
71
|
+
}
|
|
72
|
+
response = await fetch(url, { signal: controller.signal, headers });
|
|
31
73
|
}
|
|
32
74
|
catch (err) {
|
|
33
75
|
clearTimeout(timeout);
|
|
@@ -43,50 +85,118 @@ export async function downloadAndExtractTemplate(options) {
|
|
|
43
85
|
throw new Error(`Failed to download template: HTTP ${response.status}`);
|
|
44
86
|
}
|
|
45
87
|
const arrayBuffer = await response.arrayBuffer();
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
return Buffer.from(arrayBuffer);
|
|
89
|
+
}
|
|
90
|
+
async function downloadTemplateBuffer(options) {
|
|
91
|
+
const { onProgress, onFallback, fallbackTemplateUrl } = options;
|
|
92
|
+
onProgress?.("Downloading template...");
|
|
93
|
+
try {
|
|
94
|
+
return await fetchTemplateTarball(options.templateUrl || TEMPLATE_URL);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (!fallbackTemplateUrl)
|
|
98
|
+
throw err;
|
|
99
|
+
// A channel branch that hasn't been pushed yet 404s — fall back to the
|
|
100
|
+
// default branch rather than failing the scaffold.
|
|
101
|
+
onFallback?.(err.message);
|
|
102
|
+
return await fetchTemplateTarball(fallbackTemplateUrl);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Downloads and validates the Primitive app template in a temporary staging
|
|
107
|
+
* directory. Nothing is written to the final target directory until install()
|
|
108
|
+
* is called.
|
|
109
|
+
*/
|
|
110
|
+
export async function prepareTemplate(options = {}) {
|
|
111
|
+
const tempDir = mkdtempSync(join(tmpdir(), "primitive-template-"));
|
|
112
|
+
try {
|
|
113
|
+
const buffer = await downloadTemplateBuffer(options);
|
|
114
|
+
options.onProgress?.("Extracting template...");
|
|
115
|
+
const extractRoot = join(tempDir, "extract");
|
|
116
|
+
mkdirSync(extractRoot, { recursive: true });
|
|
117
|
+
const tempTarPath = join(tempDir, "template.tar.gz");
|
|
118
|
+
writeFileSync(tempTarPath, buffer);
|
|
119
|
+
await tar.extract({
|
|
120
|
+
file: tempTarPath,
|
|
121
|
+
cwd: extractRoot,
|
|
122
|
+
});
|
|
123
|
+
rmSync(tempTarPath);
|
|
124
|
+
// Find the extracted directory (e.g., "primitive-vue-template-main")
|
|
125
|
+
const extractedItems = readdirSync(extractRoot);
|
|
126
|
+
if (extractedItems.length !== 1) {
|
|
127
|
+
throw new Error(`Unexpected template structure: expected 1 directory, found ${extractedItems.length}`);
|
|
128
|
+
}
|
|
129
|
+
const extractedDir = join(extractRoot, extractedItems[0]);
|
|
130
|
+
// Verify it's a directory
|
|
131
|
+
if (!statSync(extractedDir).isDirectory()) {
|
|
132
|
+
throw new Error("Unexpected template structure: expected a directory");
|
|
78
133
|
}
|
|
79
|
-
|
|
134
|
+
options.onProgress?.("Template downloaded and validated.");
|
|
135
|
+
return {
|
|
136
|
+
install(targetDir) {
|
|
137
|
+
// Ensure target directory exists
|
|
138
|
+
mkdirSync(targetDir, { recursive: true });
|
|
139
|
+
// Move contents to target directory
|
|
140
|
+
for (const item of readdirSync(extractedDir)) {
|
|
141
|
+
const src = join(extractedDir, item);
|
|
142
|
+
const dest = join(targetDir, item);
|
|
143
|
+
// Remove existing item if it exists (for overwrite scenarios)
|
|
144
|
+
if (existsSync(dest)) {
|
|
145
|
+
rmSync(dest, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
cpSync(src, dest, { recursive: true, force: true });
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
cleanup() {
|
|
151
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Derives VITE_API_URL and VITE_WS_URL from a server URL.
|
|
162
|
+
* https:// → wss://, http:// → ws://
|
|
163
|
+
*/
|
|
164
|
+
function deriveEnvUrls(serverUrl) {
|
|
165
|
+
const apiUrl = serverUrl.replace(/\/+$/, "");
|
|
166
|
+
if (!/^https?:\/\//.test(apiUrl)) {
|
|
167
|
+
throw new Error(`Invalid server URL (must start with http:// or https://): ${apiUrl}`);
|
|
168
|
+
}
|
|
169
|
+
const wsUrl = apiUrl
|
|
170
|
+
.replace(/^https:\/\//, "wss://")
|
|
171
|
+
.replace(/^http:\/\//, "ws://");
|
|
172
|
+
return { apiUrl, wsUrl };
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Replaces a key=value pair in env file content IF the key is already there.
|
|
176
|
+
*
|
|
177
|
+
* Replace-only, deliberately (#2873): the Vue template no longer authors the
|
|
178
|
+
* identity keys — `primitiveEnv()` fills them from `.primitive/config.json` —
|
|
179
|
+
* so appending one would re-create the second source of truth this change
|
|
180
|
+
* removed, and `cf-deploy` treats an identity key in a `.env` file as a hard
|
|
181
|
+
* error. An OLD template still carries the keys, and those must keep being
|
|
182
|
+
* filled in, which is exactly what "replace if present" does.
|
|
183
|
+
*/
|
|
184
|
+
function setEnvVar(content, key, value) {
|
|
185
|
+
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
186
|
+
const pattern = new RegExp(`^${escapedKey}=.*`, "m");
|
|
187
|
+
// Quote values that contain characters dotenv would misparse (# starts
|
|
188
|
+
// a comment, leading/trailing whitespace is stripped, etc.)
|
|
189
|
+
const formatted = /[#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
190
|
+
if (pattern.test(content)) {
|
|
191
|
+
return content.replace(pattern, `${key}=${formatted}`);
|
|
80
192
|
}
|
|
81
|
-
|
|
82
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
83
|
-
onProgress?.("Template extracted successfully.");
|
|
193
|
+
return content;
|
|
84
194
|
}
|
|
85
195
|
/**
|
|
86
|
-
* Updates a single env file with the app ID.
|
|
196
|
+
* Updates a single env file with the app ID and server URLs.
|
|
87
197
|
* Returns true if the file was updated, false if it didn't exist.
|
|
88
198
|
*/
|
|
89
|
-
function updateSingleEnvFile(envPath, appId, fallbackPath) {
|
|
199
|
+
function updateSingleEnvFile(envPath, appId, serverUrl, appName, fallbackPath) {
|
|
90
200
|
let envContent = "";
|
|
91
201
|
// If file doesn't exist but fallback does, copy from fallback
|
|
92
202
|
if (!existsSync(envPath) && fallbackPath && existsSync(fallbackPath)) {
|
|
@@ -98,29 +208,34 @@ function updateSingleEnvFile(envPath, appId, fallbackPath) {
|
|
|
98
208
|
else {
|
|
99
209
|
return false;
|
|
100
210
|
}
|
|
101
|
-
|
|
102
|
-
if (
|
|
103
|
-
envContent = envContent
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
envContent = envContent.trimEnd() + `\nVITE_APP_ID=${appId}\n`;
|
|
211
|
+
envContent = setEnvVar(envContent, "VITE_APP_ID", appId);
|
|
212
|
+
if (appName) {
|
|
213
|
+
envContent = setEnvVar(envContent, "VITE_APP_NAME", appName);
|
|
107
214
|
}
|
|
215
|
+
const { apiUrl, wsUrl } = deriveEnvUrls(serverUrl);
|
|
216
|
+
envContent = setEnvVar(envContent, "VITE_API_URL", apiUrl);
|
|
217
|
+
envContent = setEnvVar(envContent, "VITE_WS_URL", wsUrl);
|
|
108
218
|
writeFileSync(envPath, envContent.trimEnd() + "\n");
|
|
109
219
|
return true;
|
|
110
220
|
}
|
|
111
221
|
/**
|
|
112
|
-
* Updates .env and .env.production files with the app ID.
|
|
222
|
+
* Updates .env and .env.production files with the app ID and server URLs.
|
|
113
223
|
* For .env, if it doesn't exist but .env.example does, copies from example first.
|
|
114
224
|
* Returns information about which files were updated.
|
|
225
|
+
*
|
|
226
|
+
* `production` names the backend/app pair a production build should talk to.
|
|
227
|
+
* Omit it and `.env.production` points at the hosted production server with
|
|
228
|
+
* this app id — the historical behavior, which is correct for an app created
|
|
229
|
+
* there and wrong for one created anywhere else, so composed runs derive the
|
|
230
|
+
* pair from the project's own environments and pass it in (#2890).
|
|
115
231
|
*/
|
|
116
|
-
export function updateEnvFile(targetDir, appId) {
|
|
232
|
+
export function updateEnvFile(targetDir, appId, serverUrl, appName, production) {
|
|
117
233
|
const envPath = join(targetDir, ".env");
|
|
118
234
|
const envExamplePath = join(targetDir, ".env.example");
|
|
119
235
|
const envProductionPath = join(targetDir, ".env.production");
|
|
120
236
|
// Update .env (create from .env.example if needed)
|
|
121
|
-
const envUpdated = updateSingleEnvFile(envPath, appId, envExamplePath);
|
|
122
|
-
|
|
123
|
-
const envProductionUpdated = updateSingleEnvFile(envProductionPath, appId);
|
|
237
|
+
const envUpdated = updateSingleEnvFile(envPath, appId, serverUrl, appName, envExamplePath);
|
|
238
|
+
const envProductionUpdated = updateSingleEnvFile(envProductionPath, production?.appId ?? appId, production?.serverUrl ?? PRODUCTION_SERVER_URL, production?.appName ?? appName);
|
|
124
239
|
return { envUpdated, envProductionUpdated };
|
|
125
240
|
}
|
|
126
241
|
/**
|
|
@@ -183,14 +298,14 @@ export async function installPnpmGlobally() {
|
|
|
183
298
|
});
|
|
184
299
|
}
|
|
185
300
|
/**
|
|
186
|
-
* Checks if the primitive CLI
|
|
187
|
-
*
|
|
188
|
-
*
|
|
301
|
+
* Checks if the primitive CLI is installed and available in PATH.
|
|
302
|
+
* Checks for the `primitive` command directly, which covers installs via
|
|
303
|
+
* npm, pnpm, yarn, or any other package manager.
|
|
189
304
|
*/
|
|
190
305
|
export async function isPrimitiveCliInstalled() {
|
|
191
306
|
const { execSync } = await import("child_process");
|
|
192
307
|
try {
|
|
193
|
-
execSync("
|
|
308
|
+
execSync("primitive --version", { stdio: "ignore" });
|
|
194
309
|
return true;
|
|
195
310
|
}
|
|
196
311
|
catch {
|
|
@@ -198,12 +313,313 @@ export async function isPrimitiveCliInstalled() {
|
|
|
198
313
|
}
|
|
199
314
|
}
|
|
200
315
|
/**
|
|
201
|
-
*
|
|
316
|
+
* Initializes a git repository in the target directory.
|
|
317
|
+
*/
|
|
318
|
+
async function spawnGit(args, cwd) {
|
|
319
|
+
const { spawn } = await import("child_process");
|
|
320
|
+
return new Promise((resolve, reject) => {
|
|
321
|
+
const proc = spawn("git", args, {
|
|
322
|
+
cwd,
|
|
323
|
+
stdio: "ignore",
|
|
324
|
+
shell: process.platform === "win32",
|
|
325
|
+
});
|
|
326
|
+
proc.on("close", (code) => {
|
|
327
|
+
if (code === 0) {
|
|
328
|
+
resolve();
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
reject(new Error(`git ${args[0]} exited with code ${code}`));
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
proc.on("error", reject);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
export async function gitInitRepo(targetDir) {
|
|
338
|
+
await spawnGit(["init"], targetDir);
|
|
339
|
+
}
|
|
340
|
+
export async function gitInitialCommit(targetDir) {
|
|
341
|
+
await spawnGit(["add", "-A"], targetDir);
|
|
342
|
+
await spawnGit(["commit", "--allow-empty", "-m", "Initial Commit"], targetDir);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Tries to connect to `host:port`. Returns true if something answered
|
|
346
|
+
* (port occupied), false if the connection was refused (port free).
|
|
347
|
+
*/
|
|
348
|
+
function canConnect(port, host) {
|
|
349
|
+
return new Promise((resolve) => {
|
|
350
|
+
import("net").then(({ createConnection }) => {
|
|
351
|
+
const socket = createConnection({ port, host });
|
|
352
|
+
socket.once("connect", () => {
|
|
353
|
+
socket.destroy();
|
|
354
|
+
resolve(true);
|
|
355
|
+
});
|
|
356
|
+
socket.once("error", () => resolve(false));
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Checks whether a TCP port is currently in use on localhost.
|
|
362
|
+
* Tries both IPv4 (127.0.0.1) and IPv6 (::1) since a server may only
|
|
363
|
+
* bind to one address family.
|
|
364
|
+
*/
|
|
365
|
+
export async function isPortFree(port) {
|
|
366
|
+
const [v4, v6] = await Promise.all([
|
|
367
|
+
canConnect(port, "127.0.0.1"),
|
|
368
|
+
canConnect(port, "::1"),
|
|
369
|
+
]);
|
|
370
|
+
return !v4 && !v6;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Locates the `{` that opens the configuration object literal of a vite
|
|
374
|
+
* config, so a `server` block can be inserted into it. Returns null when the
|
|
375
|
+
* shape isn't one we can patch safely.
|
|
376
|
+
*
|
|
377
|
+
* The shipped template exports `defineConfig(({ mode }) => { ... return {...} })`,
|
|
378
|
+
* so matching only `defineConfig({` — as this used to — silently patched
|
|
379
|
+
* nothing (#2720).
|
|
380
|
+
*/
|
|
381
|
+
function findConfigObjectStart(content) {
|
|
382
|
+
const call = /defineConfig\s*\(\s*/.exec(content);
|
|
383
|
+
if (call) {
|
|
384
|
+
const afterCall = call.index + call[0].length;
|
|
385
|
+
// `defineConfig({ ... })` — a direct object literal.
|
|
386
|
+
if (content[afterCall] === "{")
|
|
387
|
+
return afterCall;
|
|
388
|
+
// `defineConfig((env) => ...)` — an arrow function, with either a concise
|
|
389
|
+
// object body or a block body that returns the config.
|
|
390
|
+
const arrow = /^(?:async\s+)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>\s*/.exec(content.slice(afterCall));
|
|
391
|
+
if (arrow) {
|
|
392
|
+
const body = afterCall + arrow[0].length;
|
|
393
|
+
// Concise body: `=> ({ ... })`.
|
|
394
|
+
const concise = /^\(\s*\{/.exec(content.slice(body));
|
|
395
|
+
if (concise)
|
|
396
|
+
return body + concise[0].length - 1;
|
|
397
|
+
// Block body: the config is whatever the function returns.
|
|
398
|
+
if (content[body] === "{") {
|
|
399
|
+
const ret = /\breturn\s*\{/.exec(content.slice(body));
|
|
400
|
+
if (ret)
|
|
401
|
+
return body + ret.index + ret[0].length - 1;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// `export default { ... }` — a plain object config, no `defineConfig`.
|
|
406
|
+
const plain = /export\s+default\s*\{/.exec(content);
|
|
407
|
+
if (plain)
|
|
408
|
+
return plain.index + plain[0].length - 1;
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
/** Indentation of the line the given offset sits on. */
|
|
412
|
+
function indentOfLineAt(content, index) {
|
|
413
|
+
const lineStart = content.lastIndexOf("\n", index) + 1;
|
|
414
|
+
return /^[ \t]*/.exec(content.slice(lineStart, index))?.[0] ?? "";
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Pins `server.port` in the source of a vite config. Returns the patched
|
|
418
|
+
* source, or null when the config's shape is one we can't patch — the caller
|
|
419
|
+
* must not claim success in that case.
|
|
420
|
+
*
|
|
421
|
+
* Exported for tests, which pin this against the real shipped template.
|
|
422
|
+
*/
|
|
423
|
+
export function patchViteConfigPort(content, port) {
|
|
424
|
+
// An existing numeric `server.port`: retarget it.
|
|
425
|
+
if (/server\s*:\s*\{[^}]*port\s*:\s*\d+/.test(content)) {
|
|
426
|
+
return content.replace(/(server\s*:\s*\{[^}]*port\s*:\s*)\d+/, `$1${port}`);
|
|
427
|
+
}
|
|
428
|
+
// A `server.port` set to something other than a literal (`env.PORT`, say).
|
|
429
|
+
// Rewriting it would either be a no-op or clobber the author's intent.
|
|
430
|
+
if (/server\s*:\s*\{[^}]*port\s*:/.test(content))
|
|
431
|
+
return null;
|
|
432
|
+
// A `server` block with no port: add one.
|
|
433
|
+
if (/server\s*:\s*\{/.test(content)) {
|
|
434
|
+
const match = /server\s*:\s*\{/.exec(content);
|
|
435
|
+
const indent = indentOfLineAt(content, match.index);
|
|
436
|
+
return content.replace(/(server\s*:\s*\{)/, `$1\n${indent} port: ${port},`);
|
|
437
|
+
}
|
|
438
|
+
// No `server` block at all: insert one at the head of the config object.
|
|
439
|
+
const objectStart = findConfigObjectStart(content);
|
|
440
|
+
if (objectStart === null)
|
|
441
|
+
return null;
|
|
442
|
+
const indent = indentOfLineAt(content, objectStart) + " ";
|
|
443
|
+
return (content.slice(0, objectStart + 1) +
|
|
444
|
+
`\n${indent}server: {\n${indent} port: ${port},\n${indent}},` +
|
|
445
|
+
content.slice(objectStart + 1));
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Pins the dev server port in vite.config.{ts,js,mts,mjs} by injecting or
|
|
449
|
+
* updating the `server.port` field. Returns true only if a config file was
|
|
450
|
+
* found *and* actually rewritten.
|
|
451
|
+
*/
|
|
452
|
+
export function updateViteConfig(targetDir, port) {
|
|
453
|
+
const candidates = [
|
|
454
|
+
"vite.config.ts",
|
|
455
|
+
"vite.config.js",
|
|
456
|
+
"vite.config.mts",
|
|
457
|
+
"vite.config.mjs",
|
|
458
|
+
];
|
|
459
|
+
let configPath = null;
|
|
460
|
+
for (const name of candidates) {
|
|
461
|
+
const p = join(targetDir, name);
|
|
462
|
+
if (existsSync(p)) {
|
|
463
|
+
configPath = p;
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (!configPath)
|
|
468
|
+
return false;
|
|
469
|
+
const content = readFileSync(configPath, "utf-8");
|
|
470
|
+
const patched = patchViteConfigPort(content, port);
|
|
471
|
+
if (patched === null)
|
|
472
|
+
return false;
|
|
473
|
+
writeFileSync(configPath, patched);
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Updates port-sensitive env vars (VITE_OAUTH_REDIRECT_URI, VITE_BASE_URL)
|
|
478
|
+
* in the project's .env file to point at the given localhost port.
|
|
479
|
+
*/
|
|
480
|
+
export function updateEnvPort(targetDir, port) {
|
|
481
|
+
const envPath = join(targetDir, ".env");
|
|
482
|
+
if (!existsSync(envPath))
|
|
483
|
+
return;
|
|
484
|
+
const origin = `http://localhost:${port}`;
|
|
485
|
+
let content = readFileSync(envPath, "utf-8");
|
|
486
|
+
if (content.includes("VITE_OAUTH_REDIRECT_URI=")) {
|
|
487
|
+
content = content.replace(/VITE_OAUTH_REDIRECT_URI=.*/, `VITE_OAUTH_REDIRECT_URI=${origin}/oauth/callback`);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
content =
|
|
491
|
+
content.trimEnd() +
|
|
492
|
+
`\nVITE_OAUTH_REDIRECT_URI=${origin}/oauth/callback\n`;
|
|
493
|
+
}
|
|
494
|
+
if (content.includes("VITE_BASE_URL=")) {
|
|
495
|
+
content = content.replace(/VITE_BASE_URL=.*/, `VITE_BASE_URL=${origin}`);
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
content = content.trimEnd() + `\nVITE_BASE_URL=${origin}\n`;
|
|
499
|
+
}
|
|
500
|
+
writeFileSync(envPath, content.trimEnd() + "\n");
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Starting from `startPort` (default 5173), finds the first free port and
|
|
504
|
+
* returns which ports were already occupied and which port vite will bind to.
|
|
505
|
+
* `exhausted` is true when all checked ports were occupied and the returned
|
|
506
|
+
* port is a best-guess beyond the checked range.
|
|
507
|
+
*/
|
|
508
|
+
export async function findDevPort(startPort = 5173, maxChecks = 10) {
|
|
509
|
+
const takenPorts = [];
|
|
510
|
+
for (let port = startPort; port < startPort + maxChecks; port++) {
|
|
511
|
+
if (await isPortFree(port)) {
|
|
512
|
+
return { availablePort: port, takenPorts, exhausted: false };
|
|
513
|
+
}
|
|
514
|
+
takenPorts.push(port);
|
|
515
|
+
}
|
|
516
|
+
// All checked ports were occupied — best guess is the next one
|
|
517
|
+
return { availablePort: startPort + maxChecks, takenPorts, exhausted: true };
|
|
518
|
+
}
|
|
519
|
+
// ── iOS template helpers ──────────────────────────────────────────────
|
|
520
|
+
export { IOS_TEMPLATE_URL };
|
|
521
|
+
/**
|
|
522
|
+
* Updates primitive.json in the iOS template with app ID, server URL, and app name.
|
|
523
|
+
* Replaces __PRIMITIVE_*__ placeholder values.
|
|
524
|
+
* Returns true if the file was found and updated.
|
|
525
|
+
*/
|
|
526
|
+
export function updatePrimitiveJson(targetDir, appId, serverUrl, appName) {
|
|
527
|
+
const jsonPath = join(targetDir, "primitive.json");
|
|
528
|
+
if (!existsSync(jsonPath))
|
|
529
|
+
return false;
|
|
530
|
+
let content = readFileSync(jsonPath, "utf-8");
|
|
531
|
+
content = content.replace(/__PRIMITIVE_APP_ID__/g, appId);
|
|
532
|
+
content = content.replace(/__PRIMITIVE_SERVER_URL__/g, serverUrl.replace(/\/+$/, ""));
|
|
533
|
+
if (appName) {
|
|
534
|
+
content = content.replace(/__PRIMITIVE_APP_NAME__/g, appName);
|
|
535
|
+
}
|
|
536
|
+
writeFileSync(jsonPath, content);
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Gives an Apple scaffold a working `primitive.json`.
|
|
541
|
+
*
|
|
542
|
+
* In a current template that file is a BUILD PRODUCT generated from the
|
|
543
|
+
* Primitive environment in `.primitive/config.json` (#2873) — the one place
|
|
544
|
+
* the app ID and server URL are typed. `init` has just scaffolded that config,
|
|
545
|
+
* so running the template's own resolve script here means the scaffold has a
|
|
546
|
+
* `primitive.json` immediately rather than only after its first build, and
|
|
547
|
+
* there is exactly one implementation of the resolution.
|
|
548
|
+
*
|
|
549
|
+
* A template that predates the change has no such script and ships a tracked
|
|
550
|
+
* file with `__PRIMITIVE_*__` placeholders instead; filling those in keeps a
|
|
551
|
+
* new CLI working against an old template.
|
|
552
|
+
*/
|
|
553
|
+
export function configurePrimitiveJson(targetDir, appId, serverUrl, appName, options = {}) {
|
|
554
|
+
const script = join(targetDir, "scripts", "resolve-primitive-config.sh");
|
|
555
|
+
if (existsSync(script)) {
|
|
556
|
+
try {
|
|
557
|
+
execFileSync("bash", [
|
|
558
|
+
"scripts/resolve-primitive-config.sh",
|
|
559
|
+
...(options.environmentName
|
|
560
|
+
? ["--primitive-env", options.environmentName]
|
|
561
|
+
: []),
|
|
562
|
+
], {
|
|
563
|
+
cwd: targetDir,
|
|
564
|
+
stdio: "pipe",
|
|
565
|
+
});
|
|
566
|
+
return { outcome: "generated" };
|
|
567
|
+
}
|
|
568
|
+
catch (err) {
|
|
569
|
+
const detail = [err?.stderr?.toString(), err?.stdout?.toString(), err?.message]
|
|
570
|
+
.filter(Boolean)
|
|
571
|
+
.join("\n")
|
|
572
|
+
.trim();
|
|
573
|
+
return { outcome: "failed", detail };
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return updatePrimitiveJson(targetDir, appId, serverUrl, appName)
|
|
577
|
+
? { outcome: "filled" }
|
|
578
|
+
: { outcome: "missing" };
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Checks if Xcode command-line tools are installed.
|
|
582
|
+
*/
|
|
583
|
+
export async function isXcodeInstalled() {
|
|
584
|
+
const { execSync } = await import("child_process");
|
|
585
|
+
try {
|
|
586
|
+
execSync("xcodebuild -version", { stdio: "ignore" });
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
catch {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Runs `swift package resolve` in the target directory to download SPM dependencies.
|
|
595
|
+
*/
|
|
596
|
+
export async function runSwiftPackageResolve(targetDir) {
|
|
597
|
+
const { spawn } = await import("child_process");
|
|
598
|
+
return new Promise((resolve, reject) => {
|
|
599
|
+
const proc = spawn("swift", ["package", "resolve"], {
|
|
600
|
+
cwd: targetDir,
|
|
601
|
+
stdio: "inherit",
|
|
602
|
+
});
|
|
603
|
+
proc.on("close", (code) => {
|
|
604
|
+
if (code === 0) {
|
|
605
|
+
resolve();
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
reject(new Error(`swift package resolve exited with code ${code}`));
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
proc.on("error", reject);
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Installs the primitive CLI (primitive-admin) globally, using whichever
|
|
616
|
+
* package manager already owns a global copy — pnpm by default.
|
|
202
617
|
*/
|
|
203
618
|
export async function installPrimitiveCli() {
|
|
204
619
|
const { spawn } = await import("child_process");
|
|
620
|
+
const { command, args } = installArgv(PRIMITIVE_CLI_PACKAGE);
|
|
205
621
|
return new Promise((resolve, reject) => {
|
|
206
|
-
const proc = spawn(
|
|
622
|
+
const proc = spawn(command, args, {
|
|
207
623
|
stdio: "inherit",
|
|
208
624
|
shell: process.platform === "win32",
|
|
209
625
|
});
|
|
@@ -212,7 +628,7 @@ export async function installPrimitiveCli() {
|
|
|
212
628
|
resolve();
|
|
213
629
|
}
|
|
214
630
|
else {
|
|
215
|
-
reject(new Error(
|
|
631
|
+
reject(new Error(`${[command, ...args].join(" ")} exited with code ${code}`));
|
|
216
632
|
}
|
|
217
633
|
});
|
|
218
634
|
proc.on("error", reject);
|