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.
- package/README.md +125 -69
- package/assets/skill/skills/primitive-platform/SKILL.md +336 -37
- package/dist/bin/primitive.js +25 -14
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/analytics.js +36 -16
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.js +52 -188
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/blob-buckets.js +13 -153
- package/dist/src/commands/blob-buckets.js.map +1 -1
- package/dist/src/commands/collection-type-configs.js +14 -100
- package/dist/src/commands/collection-type-configs.js.map +1 -1
- package/dist/src/commands/collections.js +47 -8
- package/dist/src/commands/collections.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.js +12 -7
- package/dist/src/commands/connections.js.map +1 -1
- package/dist/src/commands/cron-triggers.js +84 -176
- package/dist/src/commands/cron-triggers.js.map +1 -1
- 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.js +4 -4
- package/dist/src/commands/database-types.js.map +1 -1
- package/dist/src/commands/databases.d.ts +63 -0
- package/dist/src/commands/databases.js +649 -87
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.js +869 -12
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.js +21 -128
- package/dist/src/commands/email-templates.js.map +1 -1
- package/dist/src/commands/env.d.ts +12 -1
- package/dist/src/commands/env.js +115 -26
- package/dist/src/commands/env.js.map +1 -1
- 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.js +14 -109
- package/dist/src/commands/group-type-configs.js.map +1 -1
- package/dist/src/commands/init.d.ts +24 -1
- package/dist/src/commands/init.js +1194 -279
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +166 -435
- package/dist/src/commands/integrations.js.map +1 -1
- 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.js +33 -141
- package/dist/src/commands/metadata.js.map +1 -1
- package/dist/src/commands/prompts.js +206 -563
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +1 -1
- package/dist/src/commands/rule-sets.js +16 -132
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +10 -0
- package/dist/src/commands/scripts.js +203 -241
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/sessions.js +17 -5
- package/dist/src/commands/sessions.js.map +1 -1
- package/dist/src/commands/sync-app-settings.d.ts +113 -70
- package/dist/src/commands/sync-app-settings.js +193 -242
- package/dist/src/commands/sync-app-settings.js.map +1 -1
- package/dist/src/commands/sync.d.ts +1904 -51
- package/dist/src/commands/sync.js +9468 -1790
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.js +8 -2
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.js +92 -1
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.js +44 -58
- package/dist/src/commands/vars.js.map +1 -1
- package/dist/src/commands/webhooks.js +318 -156
- package/dist/src/commands/webhooks.js.map +1 -1
- package/dist/src/commands/workflows.d.ts +49 -12
- package/dist/src/commands/workflows.js +652 -1086
- 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 +541 -61
- package/dist/src/lib/api-client.js +559 -102
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +180 -25
- package/dist/src/lib/app-settings-descriptor.js +403 -82
- package/dist/src/lib/app-settings-descriptor.js.map +1 -1
- 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/cli-manifest.d.ts +8 -0
- package/dist/src/lib/cli-manifest.js +1 -0
- package/dist/src/lib/cli-manifest.js.map +1 -1
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +6 -2
- package/dist/src/lib/codegen-shared/generatedFiles.js +9 -2
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +6 -6
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +8 -8
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
- 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/credentials-store.d.ts +10 -0
- package/dist/src/lib/credentials-store.js +23 -0
- package/dist/src/lib/credentials-store.js.map +1 -1
- 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/dbTemplates.js +1 -1
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +1 -1
- package/dist/src/lib/env-resolver-core.d.ts +187 -0
- package/dist/src/lib/env-resolver-core.js +325 -0
- package/dist/src/lib/env-resolver-core.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +28 -6
- package/dist/src/lib/env-resolver.js +44 -32
- package/dist/src/lib/env-resolver.js.map +1 -1
- package/dist/src/lib/generated-allowlist.js +12 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- 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-client-platforms.d.ts +14 -0
- package/dist/src/lib/init-client-platforms.js +71 -0
- package/dist/src/lib/init-client-platforms.js.map +1 -0
- package/dist/src/lib/init-config.d.ts +44 -5
- package/dist/src/lib/init-config.js +80 -7
- package/dist/src/lib/init-config.js.map +1 -1
- package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
- package/dist/src/lib/init-email-redirect-uris.js +46 -0
- package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
- package/dist/src/lib/init-ios-links.d.ts +90 -0
- package/dist/src/lib/init-ios-links.js +218 -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/integration-selector.d.ts +42 -0
- package/dist/src/lib/integration-selector.js +46 -0
- package/dist/src/lib/integration-selector.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/local-test-cases.d.ts +63 -0
- package/dist/src/lib/local-test-cases.js +135 -0
- package/dist/src/lib/local-test-cases.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 +2 -2
- package/dist/src/lib/migration-nag.js +3 -3
- 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 +24 -1
- package/dist/src/lib/output.js +42 -1
- 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 +50 -0
- package/dist/src/lib/paginate.js +53 -0
- package/dist/src/lib/paginate.js.map +1 -1
- package/dist/src/lib/platform-owned.d.ts +29 -3
- package/dist/src/lib/platform-owned.js +42 -3
- package/dist/src/lib/platform-owned.js.map +1 -1
- package/dist/src/lib/project-config.d.ts +8 -0
- package/dist/src/lib/project-config.js +30 -5
- package/dist/src/lib/project-config.js.map +1 -1
- package/dist/src/lib/query-operators.d.ts +1 -1
- package/dist/src/lib/query-operators.js +1 -1
- 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/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 +43 -14
- package/dist/src/lib/resolve-platform.js +74 -12
- package/dist/src/lib/resolve-platform.js.map +1 -1
- 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.js +6 -3
- package/dist/src/lib/skill-installer.js.map +1 -1
- package/dist/src/lib/snapshots.d.ts +2 -2
- package/dist/src/lib/snapshots.js +2 -2
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +15 -2
- package/dist/src/lib/swift-codegen/dbGenerator.js +250 -18
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
- package/dist/src/lib/swift-codegen/generator.d.ts +11 -2
- package/dist/src/lib/swift-codegen/generator.js +181 -7
- package/dist/src/lib/swift-codegen/generator.js.map +1 -1
- package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +7 -3
- package/dist/src/lib/swift-codegen/siblingSymbols.js +4 -1
- package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -1
- 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 +39 -0
- package/dist/src/lib/sync-paths.js +70 -2
- package/dist/src/lib/sync-paths.js.map +1 -1
- package/dist/src/lib/sync-resource-types.d.ts +138 -31
- package/dist/src/lib/sync-resource-types.js +241 -47
- package/dist/src/lib/sync-resource-types.js.map +1 -1
- 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 +62 -4
- package/dist/src/lib/template.js +147 -39
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/test-case-file-names.d.ts +40 -0
- package/dist/src/lib/test-case-file-names.js +91 -0
- package/dist/src/lib/test-case-file-names.js.map +1 -0
- 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/toml-database-config.d.ts +4 -4
- package/dist/src/lib/toml-database-config.js +27 -34
- package/dist/src/lib/toml-database-config.js.map +1 -1
- package/dist/src/lib/toml-metadata-config.d.ts +9 -5
- package/dist/src/lib/toml-metadata-config.js +40 -45
- package/dist/src/lib/toml-metadata-config.js.map +1 -1
- package/dist/src/lib/toml-native-form.d.ts +1 -1
- package/dist/src/lib/toml-native-form.js +1 -1
- package/dist/src/lib/toml-params-validator.d.ts +1 -1
- package/dist/src/lib/toml-params-validator.js +1 -1
- 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 +25 -0
- package/dist/src/lib/version-check.js +77 -8
- package/dist/src/lib/version-check.js.map +1 -1
- 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/web-url.d.ts +40 -0
- package/dist/src/lib/web-url.js +76 -0
- package/dist/src/lib/web-url.js.map +1 -0
- package/dist/src/lib/workflow-apply.d.ts +69 -45
- package/dist/src/lib/workflow-apply.js +99 -72
- package/dist/src/lib/workflow-apply.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generator.js +4 -4
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +11 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js +5 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -1
- 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-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 +31 -20
- package/dist/src/lib/workflow-payload.js +100 -110
- package/dist/src/lib/workflow-payload.js.map +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +37 -16
- package/dist/src/lib/workflow-toml-validator.js +141 -16
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- package/dist/src/types/index.d.ts +78 -22
- package/dist/src/validators.d.ts +7 -7
- package/dist/src/validators.js +6 -6
- package/package.json +11 -6
- package/dist/src/commands/settings.d.ts +0 -15
- package/dist/src/commands/settings.js +0 -102
- package/dist/src/commands/settings.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the app identity out of the project a run is adopting (#2890).
|
|
3
|
+
*
|
|
4
|
+
* `getCurrentEnvironment()` resolves from the process's working directory,
|
|
5
|
+
* which is not necessarily inside the project being adopted — `primitive init
|
|
6
|
+
* ../ios` resolves against the TARGET, not the cwd. This resolves the same
|
|
7
|
+
* precedence order (`--env` -> `PRIMITIVE_ENV` -> this machine's selection ->
|
|
8
|
+
* the committed default -> the sole environment) against an explicit root.
|
|
9
|
+
*/
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
import { readLocalSelection, selectEnvironmentName } from "./env-resolver-core.js";
|
|
12
|
+
import { PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILENAME, loadProjectConfigFromPath, } from "./project-config.js";
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the environment `init` adopts from the project rooted at `root`.
|
|
15
|
+
* Throws whatever the loader or the selector throws — a broken or ambiguous
|
|
16
|
+
* project config must stop the run, not be guessed around.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveAdoptedEnvironment(root, options = {}) {
|
|
19
|
+
const projectConfigPath = join(root, PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILENAME);
|
|
20
|
+
const projectConfig = loadProjectConfigFromPath(projectConfigPath);
|
|
21
|
+
const { name } = selectEnvironmentName(projectConfig, {
|
|
22
|
+
explicitEnvName: options.explicitEnvName ?? null,
|
|
23
|
+
envVarName: options.envVarName ?? null,
|
|
24
|
+
localSelection: readLocalSelection(projectConfigPath),
|
|
25
|
+
configPath: projectConfigPath,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
name,
|
|
29
|
+
config: projectConfig.environments[name],
|
|
30
|
+
projectConfig,
|
|
31
|
+
projectConfigPath,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=init-adopt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-adopt.js","sourceRoot":"","sources":["../../../src/lib/init-adopt.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,GAG1B,MAAM,qBAAqB,CAAC;AAS7B;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAY,EACZ,UAA2E,EAAE;IAE7E,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,EAAE,kBAAkB,EAAE,uBAAuB,CAAC,CAAC;IAClF,MAAM,aAAa,GAAG,yBAAyB,CAAC,iBAAiB,CAAC,CAAC;IACnE,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB,CAAC,aAAoB,EAAE;QAC3D,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI;QAChD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;QACtC,cAAc,EAAE,kBAAkB,CAAC,iBAAiB,CAAC;QACrD,UAAU,EAAE,iBAAiB;KAC9B,CAAC,CAAC;IACH,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC;QACxC,aAAa;QACb,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files `primitive init` writes at the ROOT of a repository that holds
|
|
3
|
+
* several clients of one Primitive app (#2890).
|
|
4
|
+
*
|
|
5
|
+
* These are app-wide, not client-wide: each client's own `AGENTS.md`,
|
|
6
|
+
* `package.json`, runtime config and dependencies ship with its template. What
|
|
7
|
+
* belongs here is only what the clients share — which is exactly the part a
|
|
8
|
+
* team otherwise has to reverse-engineer.
|
|
9
|
+
*/
|
|
10
|
+
import type { Platform } from "./resolve-platform.js";
|
|
11
|
+
/** Human label for a platform, used in generated prose and summaries. */
|
|
12
|
+
export declare function platformLabel(platform: Platform): string;
|
|
13
|
+
/**
|
|
14
|
+
* The header prepended to the canonical `models/models.toml`.
|
|
15
|
+
*
|
|
16
|
+
* The schema is not client state: its TOML keys are the wire field names, so a
|
|
17
|
+
* second copy that drifts orphans the first one's records. Saying so in the
|
|
18
|
+
* file is the cheapest place for a reader to find that rule.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CANONICAL_SCHEMA_HEADER = "# The model schema for this app \u2014 ONE copy, shared by every client.\n#\n# The TOML keys here are the wire field names, so a second copy that drifts\n# orphans the other one's records. Every client reads THIS file:\n# - the web client's codegen input points at it, and its generated barrel\n# imports it directly\n# - the Swift client names it in `bao-codegen.json` beside its sources\n# Add or change a model here, then re-run each client's codegen.\n";
|
|
21
|
+
/**
|
|
22
|
+
* A starter schema for the rare composition that has no template starter to
|
|
23
|
+
* adopt. The scaffolded clients normally supply their own, which is what a
|
|
24
|
+
* composed repo promotes to the root.
|
|
25
|
+
*/
|
|
26
|
+
export declare const FALLBACK_STARTER_SCHEMA = "[models.user_prefs.fields.id]\ntype = \"id\"\nauto_assign = true\nindexed = true\nrequired = true\n\n[models.user_prefs.fields.key]\ntype = \"string\"\nindexed = true\nunique = true\n\n[models.user_prefs.fields.value]\ntype = \"string\"\n";
|
|
27
|
+
/**
|
|
28
|
+
* The app-wide `AGENTS.md` for a repository with several clients.
|
|
29
|
+
*
|
|
30
|
+
* Written only when there is no `AGENTS.md` at the root already — a client's
|
|
31
|
+
* own file is never replaced by init.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rootAgentsMarkdown(input: {
|
|
34
|
+
appName: string;
|
|
35
|
+
clients: Array<{
|
|
36
|
+
platform: Platform;
|
|
37
|
+
dir: string;
|
|
38
|
+
}>;
|
|
39
|
+
}): string;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** Human label for a platform, used in generated prose and summaries. */
|
|
2
|
+
export function platformLabel(platform) {
|
|
3
|
+
return platform === "ios" ? "iOS (SwiftUI)" : "Web (Vue)";
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The header prepended to the canonical `models/models.toml`.
|
|
7
|
+
*
|
|
8
|
+
* The schema is not client state: its TOML keys are the wire field names, so a
|
|
9
|
+
* second copy that drifts orphans the first one's records. Saying so in the
|
|
10
|
+
* file is the cheapest place for a reader to find that rule.
|
|
11
|
+
*/
|
|
12
|
+
export const CANONICAL_SCHEMA_HEADER = `# The model schema for this app — ONE copy, shared by every client.
|
|
13
|
+
#
|
|
14
|
+
# The TOML keys here are the wire field names, so a second copy that drifts
|
|
15
|
+
# orphans the other one's records. Every client reads THIS file:
|
|
16
|
+
# - the web client's codegen input points at it, and its generated barrel
|
|
17
|
+
# imports it directly
|
|
18
|
+
# - the Swift client names it in \`bao-codegen.json\` beside its sources
|
|
19
|
+
# Add or change a model here, then re-run each client's codegen.
|
|
20
|
+
`;
|
|
21
|
+
/**
|
|
22
|
+
* A starter schema for the rare composition that has no template starter to
|
|
23
|
+
* adopt. The scaffolded clients normally supply their own, which is what a
|
|
24
|
+
* composed repo promotes to the root.
|
|
25
|
+
*/
|
|
26
|
+
export const FALLBACK_STARTER_SCHEMA = `[models.user_prefs.fields.id]
|
|
27
|
+
type = "id"
|
|
28
|
+
auto_assign = true
|
|
29
|
+
indexed = true
|
|
30
|
+
required = true
|
|
31
|
+
|
|
32
|
+
[models.user_prefs.fields.key]
|
|
33
|
+
type = "string"
|
|
34
|
+
indexed = true
|
|
35
|
+
unique = true
|
|
36
|
+
|
|
37
|
+
[models.user_prefs.fields.value]
|
|
38
|
+
type = "string"
|
|
39
|
+
`;
|
|
40
|
+
/**
|
|
41
|
+
* The app-wide `AGENTS.md` for a repository with several clients.
|
|
42
|
+
*
|
|
43
|
+
* Written only when there is no `AGENTS.md` at the root already — a client's
|
|
44
|
+
* own file is never replaced by init.
|
|
45
|
+
*/
|
|
46
|
+
export function rootAgentsMarkdown(input) {
|
|
47
|
+
const rows = input.clients
|
|
48
|
+
.map((client) => `- \`${client.dir}/\` — ${platformLabel(client.platform)} client`)
|
|
49
|
+
.join("\n");
|
|
50
|
+
return `# ${input.appName}
|
|
51
|
+
|
|
52
|
+
One Primitive app, several clients. The app is the shared thing: one app ID,
|
|
53
|
+
one set of environments, one exported server config, one model schema. Each
|
|
54
|
+
client is an independent project in its own directory — there is no workspace
|
|
55
|
+
file and no root \`package.json\`.
|
|
56
|
+
|
|
57
|
+
## Layout
|
|
58
|
+
|
|
59
|
+
- \`.primitive/config.json\` — the Primitive environments (backend URL + app ID
|
|
60
|
+
per environment). The single source of truth, for every client.
|
|
61
|
+
- \`.primitive/sync/<env>/<appId>/\` — the exported server config (workflows,
|
|
62
|
+
database type configs, app settings) that \`primitive config diff\` and
|
|
63
|
+
\`primitive config push\` read and write.
|
|
64
|
+
- \`models/models.toml\` — the model schema. ONE copy: its keys are the wire
|
|
65
|
+
field names, so a second copy that drifts orphans the other's records. Each
|
|
66
|
+
client's codegen reads this file in place; never copy it into a client.
|
|
67
|
+
${rows}
|
|
68
|
+
|
|
69
|
+
## Per app vs per client
|
|
70
|
+
|
|
71
|
+
| Per app (here, at the root) | Per client (in its directory) |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| Environments and app ID | Generated code |
|
|
74
|
+
| Exported server config | Dependencies and build config |
|
|
75
|
+
| Model schema | Runtime connection settings |
|
|
76
|
+
| Secrets | Deploy configuration |
|
|
77
|
+
| — | Its own \`AGENTS.md\` |
|
|
78
|
+
|
|
79
|
+
## Running commands
|
|
80
|
+
|
|
81
|
+
Every \`primitive\` command walks up to this directory's \`.primitive/config.json\`,
|
|
82
|
+
so it resolves the same app from any client directory and needs no path flag.
|
|
83
|
+
\`primitive env use <name>\` selects the environment every command in this
|
|
84
|
+
repository targets — it is an app-wide selection, not a per-client one.
|
|
85
|
+
|
|
86
|
+
## Adding another client
|
|
87
|
+
|
|
88
|
+
\`\`\`sh
|
|
89
|
+
primitive init <dir> --platform <web|ios>
|
|
90
|
+
\`\`\`
|
|
91
|
+
|
|
92
|
+
Run from inside this repository, that adds a client to THIS app: it reuses this
|
|
93
|
+
config, wires the new client to \`models/models.toml\`, and creates no second
|
|
94
|
+
\`.primitive/\` and no second git repository.
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=init-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-assets.js","sourceRoot":"","sources":["../../../src/lib/init-assets.ts"],"names":[],"mappings":"AAWA,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,OAAO,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;CAQtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;CAatC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAGlC;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO;SACvB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,GAAG,SAAS,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;SAClF,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,KAAK,KAAK,CAAC,OAAO;;;;;;;;;;;;;;;;;EAiBzB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BL,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Platform } from "./resolve-platform.js";
|
|
2
|
+
/**
|
|
3
|
+
* The platform of the client in `dir`, or null when `dir` is not a client.
|
|
4
|
+
* The ONE definition of the template signals — the AGENTS.md client listing
|
|
5
|
+
* and the both-platforms predicate read it, so they cannot drift.
|
|
6
|
+
*/
|
|
7
|
+
export declare function detectClientPlatform(dir: string): Platform | null;
|
|
8
|
+
/**
|
|
9
|
+
* Every platform already present under `projectRoot`, counting a client that
|
|
10
|
+
* IS the root. Deduplicated, in canonical order.
|
|
11
|
+
*/
|
|
12
|
+
export declare function discoverClientPlatforms(projectRoot: string): Platform[];
|
|
13
|
+
/** Whether the app ends up with an iOS client AND a web client. */
|
|
14
|
+
export declare function appHasBothPlatforms(planned: Platform[], discovered: Platform[]): boolean;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which client platforms an app HAS — the ones this run scaffolds plus the
|
|
3
|
+
* ones already in the repository (#2982).
|
|
4
|
+
*
|
|
5
|
+
* An app with both an iOS and a web client gets the universal-link wiring: the
|
|
6
|
+
* emailed sign-in link becomes the web deployment's https callback, which
|
|
7
|
+
* opens the installed app and still signs in from any browser. So "does this
|
|
8
|
+
* app have both?" decides whether init seeds a `webUrl` and prints the
|
|
9
|
+
* activation checklist.
|
|
10
|
+
*
|
|
11
|
+
* The existing clients are found by the signals the templates ship — a Swift
|
|
12
|
+
* package or Xcode project, a Vite project — so a `functions/` directory with
|
|
13
|
+
* a `package.json` is not mistaken for a client. They are looked for in child
|
|
14
|
+
* directories AND at the project root: `primitive init` still produces the
|
|
15
|
+
* flat single-client layout where the client IS the repository root, and
|
|
16
|
+
* adding the second platform to such a repository is exactly the case this
|
|
17
|
+
* feature exists for (DSO-2982-013).
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, readdirSync } from "fs";
|
|
20
|
+
import { join } from "path";
|
|
21
|
+
/**
|
|
22
|
+
* The platform of the client in `dir`, or null when `dir` is not a client.
|
|
23
|
+
* The ONE definition of the template signals — the AGENTS.md client listing
|
|
24
|
+
* and the both-platforms predicate read it, so they cannot drift.
|
|
25
|
+
*/
|
|
26
|
+
export function detectClientPlatform(dir) {
|
|
27
|
+
let hasXcodeProject = false;
|
|
28
|
+
try {
|
|
29
|
+
hasXcodeProject = readdirSync(dir).some((name) => name.endsWith(".xcodeproj"));
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (existsSync(join(dir, "Package.swift")) || hasXcodeProject)
|
|
35
|
+
return "ios";
|
|
36
|
+
if (existsSync(join(dir, "package.json")) && existsSync(join(dir, "vite.config.ts"))) {
|
|
37
|
+
return "web";
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Every platform already present under `projectRoot`, counting a client that
|
|
43
|
+
* IS the root. Deduplicated, in canonical order.
|
|
44
|
+
*/
|
|
45
|
+
export function discoverClientPlatforms(projectRoot) {
|
|
46
|
+
const found = new Set();
|
|
47
|
+
const atRoot = detectClientPlatform(projectRoot);
|
|
48
|
+
if (atRoot)
|
|
49
|
+
found.add(atRoot);
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = readdirSync(projectRoot, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
entries = [];
|
|
56
|
+
}
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
59
|
+
continue;
|
|
60
|
+
const platform = detectClientPlatform(join(projectRoot, entry.name));
|
|
61
|
+
if (platform)
|
|
62
|
+
found.add(platform);
|
|
63
|
+
}
|
|
64
|
+
return ["web", "ios"].filter((platform) => found.has(platform));
|
|
65
|
+
}
|
|
66
|
+
/** Whether the app ends up with an iOS client AND a web client. */
|
|
67
|
+
export function appHasBothPlatforms(planned, discovered) {
|
|
68
|
+
const platforms = new Set([...planned, ...discovered]);
|
|
69
|
+
return platforms.has("ios") && platforms.has("web");
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=init-client-platforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-client-platforms.js","sourceRoot":"","sources":["../../../src/lib/init-client-platforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAE7C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,IAAI,eAAe;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACrF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAY,CAAC;IAElC,MAAM,MAAM,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE9B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,IAAI,QAAQ;YAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,OAAQ,CAAC,KAAK,EAAE,KAAK,CAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,mBAAmB,CACjC,OAAmB,EACnB,UAAsB;IAEtB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAW,CAAC,GAAG,OAAO,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;IACjE,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
export declare const INIT_CONFIG_FILENAME = ".primitive-init.toml";
|
|
2
2
|
export interface InitConfig {
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* What this run does with the app:
|
|
5
|
+
* - `create` — make a new app (needs `app_name`)
|
|
6
|
+
* - `use-existing` — scaffold against an app that already exists (needs `app_id`)
|
|
7
|
+
* - `add-client` — add another client to the Primitive app the surrounding
|
|
8
|
+
* project already targets (#2890). The app comes from the selected
|
|
9
|
+
* environment of the nearest ancestor `.primitive/config.json`, so this
|
|
10
|
+
* action names no app of its own.
|
|
11
|
+
*/
|
|
12
|
+
action: "create" | "use-existing" | "add-client";
|
|
5
13
|
/** App name (required for action = "create") */
|
|
6
14
|
app_name?: string;
|
|
7
15
|
/** Existing app ID (required for action = "use-existing") */
|
|
@@ -14,7 +22,11 @@ export interface InitConfig {
|
|
|
14
22
|
dev_port?: number;
|
|
15
23
|
/** Whether to skip npm install */
|
|
16
24
|
skip_install?: boolean;
|
|
17
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Custom server URL. Behaves like the `-s/--server` flag: the app is created
|
|
27
|
+
* on this server and the scaffolded project config records it. The flag wins
|
|
28
|
+
* when both are given. (#2376)
|
|
29
|
+
*/
|
|
18
30
|
server?: string;
|
|
19
31
|
/** Email addresses to invite (for invite-only mode) */
|
|
20
32
|
invite_emails?: string[];
|
|
@@ -22,8 +34,17 @@ export interface InitConfig {
|
|
|
22
34
|
allowed_domains?: string[];
|
|
23
35
|
/** Whether to overwrite a non-empty target directory (default: false) */
|
|
24
36
|
overwrite?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Target platform(s) for the scaffolded client(s): `"web"`, `"ios"`, a
|
|
39
|
+
* comma-separated string, or a TOML array (`platform = ["web", "ios"]`).
|
|
40
|
+
*/
|
|
41
|
+
platform?: string | string[];
|
|
42
|
+
/**
|
|
43
|
+
* Non-interactive consent to move an existing single-client repo's model
|
|
44
|
+
* schema to `<project root>/models/models.toml` so both clients read one copy
|
|
45
|
+
* (#2890). Valid only with `action = "add-client"`.
|
|
46
|
+
*/
|
|
47
|
+
promote_schema?: boolean;
|
|
27
48
|
}
|
|
28
49
|
export interface ValidationResult {
|
|
29
50
|
valid: boolean;
|
|
@@ -42,6 +63,24 @@ export interface ValidationResult {
|
|
|
42
63
|
* should create a new app).
|
|
43
64
|
*/
|
|
44
65
|
export declare function resolveUseExistingAppId(flag: string | undefined, initConfig: InitConfig | null): string | undefined;
|
|
66
|
+
/** Where the resolved "skip dependency install" decision came from. */
|
|
67
|
+
export type SkipInstallSource = "flag" | "config" | "default";
|
|
68
|
+
export interface ResolvedSkipInstall {
|
|
69
|
+
skipInstall: boolean;
|
|
70
|
+
source: SkipInstallSource;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolves whether `primitive init` skips the dependency install, from the two
|
|
74
|
+
* places it can be requested: the `--skip-install` flag (highest precedence)
|
|
75
|
+
* or `skip_install = true` in the init-config TOML.
|
|
76
|
+
*
|
|
77
|
+
* `init` used to read only the flag, so a config's `skip_install` was silently
|
|
78
|
+
* ignored and CI runs installed anyway (#2720). Precedence matches #2376's
|
|
79
|
+
* `server` fix: the flag wins. Because `--skip-install` is a boolean flag it
|
|
80
|
+
* can only ever request a skip, so an explicit `skip_install = false` in the
|
|
81
|
+
* config cannot un-skip a run that passed the flag.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveSkipInstall(flag: boolean | undefined, initConfig: InitConfig | null): ResolvedSkipInstall;
|
|
45
84
|
/**
|
|
46
85
|
* Parses a TOML string into an InitConfig object.
|
|
47
86
|
* Throws if the string contains invalid TOML.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
3
|
import { parseConfigToml } from "./config-toml.js";
|
|
4
|
+
import { PROJECT_CONFIG_DISPLAY_NAME } from "./project-config.js";
|
|
5
|
+
import { parsePlatformList } from "./resolve-platform.js";
|
|
6
|
+
import { validateServerUrl } from "./server-url.js";
|
|
4
7
|
export const INIT_CONFIG_FILENAME = ".primitive-init.toml";
|
|
5
8
|
/**
|
|
6
9
|
* Resolves the "use an existing app" app id from the two places it can be
|
|
@@ -21,6 +24,27 @@ export function resolveUseExistingAppId(flag, initConfig) {
|
|
|
21
24
|
return initConfig.app_id;
|
|
22
25
|
return undefined;
|
|
23
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves whether `primitive init` skips the dependency install, from the two
|
|
29
|
+
* places it can be requested: the `--skip-install` flag (highest precedence)
|
|
30
|
+
* or `skip_install = true` in the init-config TOML.
|
|
31
|
+
*
|
|
32
|
+
* `init` used to read only the flag, so a config's `skip_install` was silently
|
|
33
|
+
* ignored and CI runs installed anyway (#2720). Precedence matches #2376's
|
|
34
|
+
* `server` fix: the flag wins. Because `--skip-install` is a boolean flag it
|
|
35
|
+
* can only ever request a skip, so an explicit `skip_install = false` in the
|
|
36
|
+
* config cannot un-skip a run that passed the flag.
|
|
37
|
+
*/
|
|
38
|
+
export function resolveSkipInstall(flag, initConfig) {
|
|
39
|
+
if (flag)
|
|
40
|
+
return { skipInstall: true, source: "flag" };
|
|
41
|
+
// Strict `=== true`: a non-boolean that slipped past validation must not
|
|
42
|
+
// skip the install by truthiness (`skip_install = "false"` reads as a skip).
|
|
43
|
+
if (initConfig?.skip_install === true) {
|
|
44
|
+
return { skipInstall: true, source: "config" };
|
|
45
|
+
}
|
|
46
|
+
return { skipInstall: false, source: "default" };
|
|
47
|
+
}
|
|
24
48
|
/**
|
|
25
49
|
* Parses a TOML string into an InitConfig object.
|
|
26
50
|
* Throws if the string contains invalid TOML.
|
|
@@ -49,11 +73,12 @@ export function loadInitConfig(dir) {
|
|
|
49
73
|
export function validateInitConfig(config) {
|
|
50
74
|
const errors = [];
|
|
51
75
|
// action is required
|
|
76
|
+
const ACTIONS = ["create", "use-existing", "add-client"];
|
|
52
77
|
if (!config.action) {
|
|
53
|
-
errors.push(
|
|
78
|
+
errors.push(`Missing required field: "action" (must be ${ACTIONS.map((a) => `"${a}"`).join(", ")})`);
|
|
54
79
|
}
|
|
55
|
-
else if (
|
|
56
|
-
errors.push(
|
|
80
|
+
else if (!ACTIONS.includes(config.action)) {
|
|
81
|
+
errors.push(`"action" must be ${ACTIONS.map((a) => `"${a}"`).join(", ")}`);
|
|
57
82
|
}
|
|
58
83
|
else {
|
|
59
84
|
// Validate action-specific required fields
|
|
@@ -63,6 +88,24 @@ export function validateInitConfig(config) {
|
|
|
63
88
|
if (config.action === "use-existing" && !config.app_id) {
|
|
64
89
|
errors.push('"app_id" is required when action is "use-existing"');
|
|
65
90
|
}
|
|
91
|
+
// `add-client` takes its app — and therefore its access mode and its
|
|
92
|
+
// invitations — from the environment it adopts. Naming any of them here
|
|
93
|
+
// would describe a second app this run is not allowed to touch.
|
|
94
|
+
if (config.action === "add-client") {
|
|
95
|
+
for (const key of [
|
|
96
|
+
"app_name",
|
|
97
|
+
"app_id",
|
|
98
|
+
"access_mode",
|
|
99
|
+
"invite_emails",
|
|
100
|
+
"allowed_domains",
|
|
101
|
+
]) {
|
|
102
|
+
const value = config[key];
|
|
103
|
+
const present = Array.isArray(value) ? value.length > 0 : value !== undefined;
|
|
104
|
+
if (present) {
|
|
105
|
+
errors.push(`"${key}" is not allowed with action = "add-client": the app comes from the selected environment of the existing ${PROJECT_CONFIG_DISPLAY_NAME}.`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
66
109
|
}
|
|
67
110
|
// Validate access_mode if provided
|
|
68
111
|
if (config.access_mode) {
|
|
@@ -74,12 +117,42 @@ export function validateInitConfig(config) {
|
|
|
74
117
|
errors.push('"allowed_domains" is required when access_mode is "domain"');
|
|
75
118
|
}
|
|
76
119
|
}
|
|
77
|
-
// Validate platform if provided.
|
|
78
|
-
// (`macos` is intentionally rejected until the macOS
|
|
120
|
+
// Validate platform if provided. A string or an array of strings; only "web"
|
|
121
|
+
// and "ios" are supported (`macos` is intentionally rejected until the macOS
|
|
122
|
+
// template is ready), and each may be named once (#2890).
|
|
79
123
|
if (config.platform !== undefined) {
|
|
80
|
-
if (config.platform !== "
|
|
81
|
-
errors.push('"platform" must be
|
|
124
|
+
if (typeof config.platform !== "string" && !Array.isArray(config.platform)) {
|
|
125
|
+
errors.push('"platform" must be a string or an array of strings');
|
|
82
126
|
}
|
|
127
|
+
else {
|
|
128
|
+
const parsed = parsePlatformList(config.platform);
|
|
129
|
+
if (!parsed.ok)
|
|
130
|
+
errors.push(`"platform": ${parsed.error}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// `promote_schema` is consent for a move that only the add-client path can
|
|
134
|
+
// make; anywhere else it would silently do nothing.
|
|
135
|
+
if (config.promote_schema !== undefined) {
|
|
136
|
+
if (typeof config.promote_schema !== "boolean") {
|
|
137
|
+
errors.push('"promote_schema" must be a boolean (true or false)');
|
|
138
|
+
}
|
|
139
|
+
else if (config.action !== "add-client") {
|
|
140
|
+
errors.push('"promote_schema" is only valid with action = "add-client"');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Validate server if provided. An unusable value must fail here rather than
|
|
144
|
+
// fall through to the current server, which is how #2376 went unnoticed.
|
|
145
|
+
if (config.server !== undefined) {
|
|
146
|
+
const serverValidation = validateServerUrl(config.server);
|
|
147
|
+
if (serverValidation !== true) {
|
|
148
|
+
errors.push(`"server" must be a valid URL (e.g., https://primitiveapi.com): ${serverValidation}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Validate skip_install if provided. The TOML is cast to InitConfig without
|
|
152
|
+
// runtime narrowing, so a non-boolean has to be rejected here rather than
|
|
153
|
+
// reach the resolver, where anything truthy would skip the install.
|
|
154
|
+
if (config.skip_install !== undefined && typeof config.skip_install !== "boolean") {
|
|
155
|
+
errors.push('"skip_install" must be a boolean (true or false)');
|
|
83
156
|
}
|
|
84
157
|
// Validate dev_port if provided
|
|
85
158
|
if (config.dev_port !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-config.js","sourceRoot":"","sources":["../../../src/lib/init-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"init-config.js","sourceRoot":"","sources":["../../../src/lib/init-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether init may add a sign-in callback to an app's magic-link allow-list,
|
|
3
|
+
* and what to write (#2982).
|
|
4
|
+
*
|
|
5
|
+
* A combined iOS + web app emails ONE https link — the web app's
|
|
6
|
+
* `/oauth/callback` — and the server matches that target against
|
|
7
|
+
* `emailRedirectUris` fail-closed. So init only points an environment's
|
|
8
|
+
* `webUrl` at a dev origin whose callback the app actually allows; otherwise it
|
|
9
|
+
* would flip a working code-only email into a request that 400s.
|
|
10
|
+
*
|
|
11
|
+
* A brand-new app is seeded with `http://localhost:5173/oauth/callback` at
|
|
12
|
+
* creation, and the dev-port step merges the chosen port's callback — but an
|
|
13
|
+
* app adopted with `--use-existing-app-id` on the default port has been through
|
|
14
|
+
* neither, and its allow-list is whatever it already was.
|
|
15
|
+
*
|
|
16
|
+
* The one thing this must never do is NARROW that list. An app with no
|
|
17
|
+
* `emailRedirectUris` attribute still behaves by the pre-#2891 app-wide
|
|
18
|
+
* `redirectUris`, and writing a fresh single-entry list would silently replace
|
|
19
|
+
* that fallback with our callback — breaking magic-link sign-in for whichever
|
|
20
|
+
* client was relying on it. An explicitly empty list is a deliberate "reject
|
|
21
|
+
* everything" for the same reason. Both are left alone, and init falls back to
|
|
22
|
+
* printing the manual step.
|
|
23
|
+
*/
|
|
24
|
+
export type EmailRedirectUriMerge = {
|
|
25
|
+
action: "already-listed";
|
|
26
|
+
} | {
|
|
27
|
+
action: "merge";
|
|
28
|
+
uris: string[];
|
|
29
|
+
} | {
|
|
30
|
+
action: "leave-alone";
|
|
31
|
+
reason: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Decide what to do with `existing` (the app's `emailRedirectUris` as the
|
|
35
|
+
* settings API reports it) to make `callbackUri` an allowed target.
|
|
36
|
+
*/
|
|
37
|
+
export declare function planEmailRedirectUriMerge(existing: unknown, callbackUri: string): EmailRedirectUriMerge;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether init may add a sign-in callback to an app's magic-link allow-list,
|
|
3
|
+
* and what to write (#2982).
|
|
4
|
+
*
|
|
5
|
+
* A combined iOS + web app emails ONE https link — the web app's
|
|
6
|
+
* `/oauth/callback` — and the server matches that target against
|
|
7
|
+
* `emailRedirectUris` fail-closed. So init only points an environment's
|
|
8
|
+
* `webUrl` at a dev origin whose callback the app actually allows; otherwise it
|
|
9
|
+
* would flip a working code-only email into a request that 400s.
|
|
10
|
+
*
|
|
11
|
+
* A brand-new app is seeded with `http://localhost:5173/oauth/callback` at
|
|
12
|
+
* creation, and the dev-port step merges the chosen port's callback — but an
|
|
13
|
+
* app adopted with `--use-existing-app-id` on the default port has been through
|
|
14
|
+
* neither, and its allow-list is whatever it already was.
|
|
15
|
+
*
|
|
16
|
+
* The one thing this must never do is NARROW that list. An app with no
|
|
17
|
+
* `emailRedirectUris` attribute still behaves by the pre-#2891 app-wide
|
|
18
|
+
* `redirectUris`, and writing a fresh single-entry list would silently replace
|
|
19
|
+
* that fallback with our callback — breaking magic-link sign-in for whichever
|
|
20
|
+
* client was relying on it. An explicitly empty list is a deliberate "reject
|
|
21
|
+
* everything" for the same reason. Both are left alone, and init falls back to
|
|
22
|
+
* printing the manual step.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Decide what to do with `existing` (the app's `emailRedirectUris` as the
|
|
26
|
+
* settings API reports it) to make `callbackUri` an allowed target.
|
|
27
|
+
*/
|
|
28
|
+
export function planEmailRedirectUriMerge(existing, callbackUri) {
|
|
29
|
+
if (!Array.isArray(existing)) {
|
|
30
|
+
return {
|
|
31
|
+
action: "leave-alone",
|
|
32
|
+
reason: "this app has no emailRedirectUris list of its own, and writing one would replace the allow-list it behaves by today",
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const uris = existing.filter((value) => typeof value === "string");
|
|
36
|
+
if (uris.length === 0) {
|
|
37
|
+
return {
|
|
38
|
+
action: "leave-alone",
|
|
39
|
+
reason: "this app's emailRedirectUris list is empty, which is a deliberate 'reject every link target'",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (uris.includes(callbackUri))
|
|
43
|
+
return { action: "already-listed" };
|
|
44
|
+
return { action: "merge", uris: [...uris, callbackUri] };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=init-email-redirect-uris.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-email-redirect-uris.js","sourceRoot":"","sources":["../../../src/lib/init-email-redirect-uris.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAiB,EACjB,WAAmB;IAEnB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,MAAM,EACJ,qHAAqH;SACxH,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;IACpF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,MAAM,EACJ,8FAA8F;SACjG,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IACpE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;AAC3D,CAAC"}
|