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
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as TOML from "@iarna/toml";
|
|
1
|
+
import chalk from "chalk";
|
|
3
2
|
import { ApiClient } from "../lib/api-client.js";
|
|
4
3
|
import { resolveAppId } from "../lib/config.js";
|
|
5
|
-
import { success, error, info, keyValue, formatTable, formatId, formatDate, formatStatus, formatDuration, json, divider, } from "../lib/output.js";
|
|
4
|
+
import { success, error, info, keyValue, result as printResult, formatTable, formatId, formatDate, formatStatus, formatDuration, json, divider, } from "../lib/output.js";
|
|
5
|
+
import { buildIntegrationEnvelope } from "../lib/log-inspection.js";
|
|
6
|
+
import { confirmPrompt } from "../lib/confirm-prompt.js";
|
|
7
|
+
import { parseStatusFilter } from "../lib/object-status-filter.js";
|
|
8
|
+
import { testCaseInputVariables } from "../lib/test-case-variables.js";
|
|
6
9
|
export function registerIntegrationsCommands(program) {
|
|
7
10
|
const integrations = program
|
|
8
11
|
.command("integrations")
|
|
9
|
-
.description("Configure external HTTP API connections
|
|
12
|
+
.description("Configure external HTTP API connections")
|
|
10
13
|
.addHelpText("after", `
|
|
11
14
|
Examples:
|
|
12
15
|
$ primitive integrations list
|
|
13
|
-
$ primitive
|
|
16
|
+
$ primitive config create integration weather-api # scaffold integrations/weather-api.toml
|
|
17
|
+
$ primitive config push --only integration/weather-api # apply it
|
|
14
18
|
$ primitive integrations test 01HXY...
|
|
15
|
-
$ primitive integrations
|
|
19
|
+
$ primitive integrations archive 01HXY... # retire it (soft delete)
|
|
20
|
+
|
|
21
|
+
Storing credentials for an integration:
|
|
22
|
+
$ primitive secrets set MY_API_KEY --value <value>
|
|
23
|
+
# then reference it in integration config via {{secrets.MY_API_KEY}}
|
|
24
|
+
`);
|
|
25
|
+
// Server-side configuration is authored in TOML and applied with `config push`
|
|
26
|
+
// (issue #2645) — this group no longer carries config-setting flags.
|
|
27
|
+
integrations.addHelpText("after", `
|
|
28
|
+
Configuration lives in integrations/<key>.toml:
|
|
29
|
+
$ primitive config fields integration # the file's keys, types and defaults
|
|
30
|
+
$ primitive config create integration <key> # scaffold one locally
|
|
31
|
+
$ primitive config set integration/<key> <path>=<value>
|
|
32
|
+
$ primitive config push --only integration/<key>
|
|
16
33
|
`);
|
|
17
34
|
// List integrations
|
|
18
35
|
integrations
|
|
@@ -20,14 +37,20 @@ Examples:
|
|
|
20
37
|
.description("List integrations")
|
|
21
38
|
.argument("[app-id]", "App ID (uses current app if not specified)")
|
|
22
39
|
.option("--app <app-id>", "App ID")
|
|
23
|
-
.option("--status <status>", "Filter by status:
|
|
40
|
+
.option("--status <status>", "Filter by status: active, inactive, archived")
|
|
24
41
|
.option("--json", "Output as JSON")
|
|
25
42
|
.action(async (appId, options) => {
|
|
26
43
|
const resolvedAppId = resolveAppId(appId, options);
|
|
27
44
|
const client = new ApiClient();
|
|
28
45
|
try {
|
|
46
|
+
// #2803 — `draft` is gone; refuse it by name rather than returning the
|
|
47
|
+
// empty list a canonical filter would produce.
|
|
29
48
|
const { items } = await client.listIntegrations(resolvedAppId, {
|
|
30
|
-
status: options.status,
|
|
49
|
+
status: parseStatusFilter("integrations", options.status, [
|
|
50
|
+
"active",
|
|
51
|
+
"inactive",
|
|
52
|
+
"archived",
|
|
53
|
+
]),
|
|
31
54
|
});
|
|
32
55
|
if (options.json) {
|
|
33
56
|
json(items);
|
|
@@ -50,195 +73,161 @@ Examples:
|
|
|
50
73
|
process.exit(1);
|
|
51
74
|
}
|
|
52
75
|
});
|
|
53
|
-
//
|
|
76
|
+
// #2645 criterion 9 / #2803 — the operational verbs. They are the only
|
|
77
|
+
// writers of `status`, which is server-owned and no longer a TOML key.
|
|
54
78
|
integrations
|
|
55
|
-
.command("
|
|
56
|
-
.description("
|
|
57
|
-
.argument("
|
|
58
|
-
.option("--app <app-id>", "App ID")
|
|
59
|
-
.option("--key <key>", "Integration key (unique identifier)")
|
|
60
|
-
.option("--name <name>", "Display name")
|
|
61
|
-
.option("--description <desc>", "Description")
|
|
62
|
-
.option("--base-url <url>", "Base URL for API requests")
|
|
63
|
-
.option("--allowed-methods <methods>", "Comma-separated list of allowed HTTP methods")
|
|
64
|
-
.option("--allowed-paths <paths>", "Comma-separated list of allowed paths")
|
|
65
|
-
.option("--timeout-ms <ms>", "Request timeout in milliseconds")
|
|
66
|
-
.option("--from-file <path>", "Load integration from TOML file")
|
|
79
|
+
.command("disable")
|
|
80
|
+
.description("Take integration out of service now. Operational, not configuration: `status` is server-owned and 'config push' can neither set nor clear it.")
|
|
81
|
+
.argument("<integration-id>", "Integration ID")
|
|
82
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
67
83
|
.option("--json", "Output as JSON")
|
|
68
|
-
.action(async (
|
|
69
|
-
const resolvedAppId = resolveAppId(
|
|
84
|
+
.action(async (id, options) => {
|
|
85
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
70
86
|
const client = new ApiClient();
|
|
71
|
-
let payload;
|
|
72
|
-
if (options.fromFile) {
|
|
73
|
-
try {
|
|
74
|
-
const content = readFileSync(options.fromFile, "utf-8");
|
|
75
|
-
const tomlData = TOML.parse(content);
|
|
76
|
-
payload = {
|
|
77
|
-
integrationKey: tomlData.integration?.key || tomlData.key,
|
|
78
|
-
displayName: tomlData.integration?.displayName || tomlData.displayName,
|
|
79
|
-
description: tomlData.integration?.description || tomlData.description,
|
|
80
|
-
requestConfig: tomlData.requestConfig || {},
|
|
81
|
-
timeoutMs: tomlData.integration?.timeoutMs || tomlData.timeoutMs,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
error(`Failed to read TOML file: ${err.message}`);
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
if (!options.key || !options.name || !options.baseUrl) {
|
|
91
|
-
error("Required: --key, --name, --base-url (or use --from-file)");
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
payload = {
|
|
95
|
-
integrationKey: options.key,
|
|
96
|
-
displayName: options.name,
|
|
97
|
-
description: options.description,
|
|
98
|
-
requestConfig: {
|
|
99
|
-
baseUrl: options.baseUrl,
|
|
100
|
-
allowedMethods: options.allowedMethods?.split(",").map((s) => s.trim()),
|
|
101
|
-
allowedPaths: options.allowedPaths?.split(",").map((s) => s.trim()),
|
|
102
|
-
},
|
|
103
|
-
timeoutMs: options.timeoutMs ? parseInt(options.timeoutMs) : undefined,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
87
|
try {
|
|
107
|
-
const result = await client.
|
|
88
|
+
const result = await client.setIntegrationAvailability(resolvedAppId, id, "disable");
|
|
108
89
|
if (options.json) {
|
|
109
90
|
json(result);
|
|
110
91
|
return;
|
|
111
92
|
}
|
|
112
|
-
success(`Integration
|
|
113
|
-
keyValue("Integration ID", result.integrationId);
|
|
114
|
-
keyValue("Key", result.integrationKey);
|
|
93
|
+
success(`Integration disabled: ${result.integrationKey || id}`);
|
|
115
94
|
}
|
|
116
95
|
catch (err) {
|
|
117
96
|
error(err.message);
|
|
118
97
|
process.exit(1);
|
|
119
98
|
}
|
|
120
99
|
});
|
|
121
|
-
// Get integration
|
|
122
100
|
integrations
|
|
123
|
-
.command("
|
|
124
|
-
.description("
|
|
101
|
+
.command("enable")
|
|
102
|
+
.description("Put integration back in service.")
|
|
125
103
|
.argument("<integration-id>", "Integration ID")
|
|
126
104
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
127
105
|
.option("--json", "Output as JSON")
|
|
128
|
-
.action(async (
|
|
106
|
+
.action(async (id, options) => {
|
|
129
107
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
130
108
|
const client = new ApiClient();
|
|
131
109
|
try {
|
|
132
|
-
const result = await client.
|
|
110
|
+
const result = await client.setIntegrationAvailability(resolvedAppId, id, "enable");
|
|
133
111
|
if (options.json) {
|
|
134
112
|
json(result);
|
|
135
113
|
return;
|
|
136
114
|
}
|
|
137
|
-
|
|
138
|
-
keyValue("Key", result.integrationKey);
|
|
139
|
-
keyValue("Name", result.displayName);
|
|
140
|
-
keyValue("Description", result.description);
|
|
141
|
-
keyValue("Status", formatStatus(result.status));
|
|
142
|
-
keyValue("Timeout", result.timeoutMs ? `${result.timeoutMs}ms` : "-");
|
|
143
|
-
if (result.requestConfig) {
|
|
144
|
-
divider();
|
|
145
|
-
info("Request Config:");
|
|
146
|
-
keyValue(" Base URL", result.requestConfig.baseUrl);
|
|
147
|
-
keyValue(" Allowed Methods", result.requestConfig.allowedMethods?.join(", ") || "all");
|
|
148
|
-
keyValue(" Allowed Paths", result.requestConfig.allowedPaths?.join(", ") || "all");
|
|
149
|
-
keyValue(" Response Passthrough", result.requestConfig.responsePassthrough);
|
|
150
|
-
if (result.requestConfig.bodyMode) {
|
|
151
|
-
keyValue(" Body Mode", result.requestConfig.bodyMode);
|
|
152
|
-
}
|
|
153
|
-
if (result.requestConfig.multipartFieldMapping?.length) {
|
|
154
|
-
keyValue(" Multipart Fields", result.requestConfig.multipartFieldMapping
|
|
155
|
-
.map((f) => `${f.fieldName} (${f.type}${f.attachmentIndex != null ? `, attachment[${f.attachmentIndex}]` : ""})`)
|
|
156
|
-
.join(", "));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
115
|
+
success(`Integration enabled: ${result.integrationKey || id}`);
|
|
159
116
|
}
|
|
160
117
|
catch (err) {
|
|
161
118
|
error(err.message);
|
|
162
119
|
process.exit(1);
|
|
163
120
|
}
|
|
164
121
|
});
|
|
165
|
-
//
|
|
122
|
+
// #2907 — the delete flow's CLI spelling. Not a second writer of `status`:
|
|
123
|
+
// this is the plain `DELETE` the server has always answered by writing the
|
|
124
|
+
// tombstone, which until now only the admin API and the console could reach.
|
|
125
|
+
// Named `archive`, not `delete`, because a configuration noun gets no
|
|
126
|
+
// `delete` verb (docs/cli-design.md) and prune-by-push stays the only CLI
|
|
127
|
+
// hard-delete path.
|
|
166
128
|
integrations
|
|
167
|
-
.command("
|
|
168
|
-
.description("
|
|
129
|
+
.command("archive")
|
|
130
|
+
.description("Retire an integration (soft delete). Delete-lifecycle, not `disable`: the row is kept, goes on holding its key, and there is no un-archive.")
|
|
169
131
|
.argument("<integration-id>", "Integration ID")
|
|
170
132
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
171
|
-
.option("--
|
|
172
|
-
.option("--description <desc>", "Description")
|
|
173
|
-
.option("--status <status>", "Status: draft, active, archived")
|
|
174
|
-
.option("--timeout-ms <ms>", "Request timeout in milliseconds")
|
|
133
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
175
134
|
.option("--json", "Output as JSON")
|
|
176
|
-
.
|
|
135
|
+
.addHelpText("after", `
|
|
136
|
+
What archiving an integration costs:
|
|
137
|
+
The proxy refuses it, and so does every workflow step that calls it.
|
|
138
|
+
The archived row still holds its integrationKey, so a push cannot re-create
|
|
139
|
+
one under the same key.
|
|
140
|
+
\`primitive integrations enable\` refuses an archived integration; there is no
|
|
141
|
+
un-archive.
|
|
142
|
+
|
|
143
|
+
Reclaiming the key means hard-deleting the row:
|
|
144
|
+
$ rm integrations/<key>.toml
|
|
145
|
+
$ primitive config push --prune # confirmed; hard-deletes the row
|
|
146
|
+
# or hard-delete it in the console, then re-add the file and push.
|
|
147
|
+
`)
|
|
148
|
+
.action(async (id, options) => {
|
|
177
149
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
150
|
+
if (!options.yes) {
|
|
151
|
+
let confirmed;
|
|
152
|
+
try {
|
|
153
|
+
confirmed = await confirmPrompt(`Archive integration ${id}? It is retired, goes on holding its key, ` +
|
|
154
|
+
`and there is no un-archive.`);
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
error(err.message);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
if (!confirmed) {
|
|
161
|
+
info("Cancelled.");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
190
164
|
}
|
|
191
165
|
const client = new ApiClient();
|
|
192
166
|
try {
|
|
193
|
-
|
|
167
|
+
// The soft delete: no `hard`, so the server writes the tombstone and
|
|
168
|
+
// keeps the row (and its canonical block mirror) in step.
|
|
169
|
+
const result = await client.deleteIntegration(resolvedAppId, id);
|
|
194
170
|
if (options.json) {
|
|
195
171
|
json(result);
|
|
196
172
|
return;
|
|
197
173
|
}
|
|
198
|
-
success(
|
|
174
|
+
success(`Integration archived: ${id}`);
|
|
175
|
+
info("It is retired and still holds its key — reclaim the key by removing its file and running a confirmed `primitive config push --prune`.");
|
|
199
176
|
}
|
|
200
177
|
catch (err) {
|
|
201
178
|
error(err.message);
|
|
202
179
|
process.exit(1);
|
|
203
180
|
}
|
|
204
181
|
});
|
|
205
|
-
// Delete integration
|
|
206
182
|
integrations
|
|
207
|
-
.command("
|
|
208
|
-
.description("
|
|
183
|
+
.command("get")
|
|
184
|
+
.description("Get integration details")
|
|
209
185
|
.argument("<integration-id>", "Integration ID")
|
|
210
186
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
211
|
-
.option("--
|
|
212
|
-
.option("-y, --yes", "Skip confirmation prompt")
|
|
187
|
+
.option("--json", "Output as JSON")
|
|
213
188
|
.action(async (integrationId, options) => {
|
|
214
189
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
215
|
-
if (!options.yes) {
|
|
216
|
-
const action = options.hard ? "permanently delete" : "archive";
|
|
217
|
-
const inquirer = await import("inquirer");
|
|
218
|
-
const { confirm } = await inquirer.default.prompt([
|
|
219
|
-
{
|
|
220
|
-
type: "confirm",
|
|
221
|
-
name: "confirm",
|
|
222
|
-
message: `Are you sure you want to ${action} integration ${integrationId}?`,
|
|
223
|
-
default: false,
|
|
224
|
-
},
|
|
225
|
-
]);
|
|
226
|
-
if (!confirm) {
|
|
227
|
-
info("Cancelled.");
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
190
|
const client = new ApiClient();
|
|
232
191
|
try {
|
|
233
|
-
await client.
|
|
234
|
-
|
|
192
|
+
const result = await client.getIntegration(resolvedAppId, integrationId);
|
|
193
|
+
if (options.json) {
|
|
194
|
+
json(result);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
printResult("Integration ID", result.integrationId);
|
|
198
|
+
printResult("Key", result.integrationKey);
|
|
199
|
+
printResult("Name", result.displayName);
|
|
200
|
+
printResult("Description", result.description);
|
|
201
|
+
printResult("Status", formatStatus(result.status));
|
|
202
|
+
printResult("Timeout", result.timeoutMs ? `${result.timeoutMs}ms` : "-");
|
|
203
|
+
// #2631: no rule means every non-admin call is denied. Print that in
|
|
204
|
+
// words — a blank or "-" would read as "unrestricted" and hide an
|
|
205
|
+
// integration that was never given a rule.
|
|
206
|
+
printResult("Access Rule", typeof result.accessRule === "string" && result.accessRule !== ""
|
|
207
|
+
? result.accessRule
|
|
208
|
+
: "(none — all non-admin calls are denied; set one to allow callers)");
|
|
209
|
+
if (result.requestConfig) {
|
|
210
|
+
divider();
|
|
211
|
+
info("Request Config:");
|
|
212
|
+
printResult(" Base URL", result.requestConfig.baseUrl);
|
|
213
|
+
printResult(" Allowed Methods", result.requestConfig.allowedMethods?.join(", ") || "all");
|
|
214
|
+
printResult(" Allowed Paths", result.requestConfig.allowedPaths?.join(", ") || "all");
|
|
215
|
+
printResult(" Response Passthrough", result.requestConfig.responsePassthrough);
|
|
216
|
+
if (result.requestConfig.bodyMode) {
|
|
217
|
+
printResult(" Body Mode", result.requestConfig.bodyMode);
|
|
218
|
+
}
|
|
219
|
+
if (result.requestConfig.multipartFieldMapping?.length) {
|
|
220
|
+
printResult(" Multipart Fields", result.requestConfig.multipartFieldMapping
|
|
221
|
+
.map((f) => `${f.fieldName} (${f.type}${f.attachmentIndex != null ? `, attachment[${f.attachmentIndex}]` : ""})`)
|
|
222
|
+
.join(", "));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
235
225
|
}
|
|
236
226
|
catch (err) {
|
|
237
227
|
error(err.message);
|
|
238
228
|
process.exit(1);
|
|
239
229
|
}
|
|
240
230
|
});
|
|
241
|
-
// Test integration
|
|
242
231
|
integrations
|
|
243
232
|
.command("test")
|
|
244
233
|
.description("Test an integration by making a request")
|
|
@@ -304,20 +293,33 @@ Examples:
|
|
|
304
293
|
// List integration logs
|
|
305
294
|
integrations
|
|
306
295
|
.command("logs")
|
|
307
|
-
.description("View integration request logs")
|
|
296
|
+
.description("View integration request logs (includes workflow-initiated calls; filter with --source workflow|user|admin|test)")
|
|
308
297
|
.argument("<integration-id>", "Integration ID")
|
|
309
298
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
310
299
|
.option("--limit <n>", "Number of logs to show", "20")
|
|
300
|
+
.option("--source <source>", "Filter by call source: user, admin, test, or workflow")
|
|
301
|
+
.option("--status <status>", "Filter by upstream HTTP status (e.g. 200, 500)")
|
|
302
|
+
.option("--from <iso>", "Only logs at or after this ISO timestamp")
|
|
303
|
+
.option("--to <iso>", "Only logs at or before this ISO timestamp")
|
|
311
304
|
.option("--json", "Output as JSON")
|
|
312
305
|
.action(async (integrationId, options) => {
|
|
313
306
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
314
307
|
const client = new ApiClient();
|
|
315
308
|
try {
|
|
309
|
+
const validSources = new Set(["user", "admin", "test", "workflow"]);
|
|
310
|
+
if (options.source && !validSources.has(options.source)) {
|
|
311
|
+
error(`Invalid --source value '${options.source}'. Must be one of: user, admin, test, workflow.`);
|
|
312
|
+
process.exit(1);
|
|
313
|
+
}
|
|
316
314
|
const logs = await client.listIntegrationLogs(resolvedAppId, integrationId, {
|
|
317
315
|
limit: parseInt(options.limit),
|
|
316
|
+
...(options.source && { source: options.source }),
|
|
317
|
+
...(options.status && { status: options.status }),
|
|
318
|
+
...(options.from && { from: options.from }),
|
|
319
|
+
...(options.to && { to: options.to }),
|
|
318
320
|
});
|
|
319
321
|
if (options.json) {
|
|
320
|
-
json(logs);
|
|
322
|
+
json(buildIntegrationEnvelope(logs));
|
|
321
323
|
return;
|
|
322
324
|
}
|
|
323
325
|
if (!logs || logs.length === 0) {
|
|
@@ -326,10 +328,13 @@ Examples:
|
|
|
326
328
|
}
|
|
327
329
|
console.log(formatTable(logs, [
|
|
328
330
|
{ header: "TIME", key: "timestamp", format: formatDate },
|
|
331
|
+
{ header: "SOURCE", key: "source", format: (v) => v || "user" },
|
|
329
332
|
{ header: "METHOD", key: "method" },
|
|
330
333
|
{ header: "PATH", key: "path" },
|
|
331
334
|
{ header: "STATUS", key: "status" },
|
|
332
335
|
{ header: "DURATION", key: "durationMs", format: formatDuration },
|
|
336
|
+
{ header: "WORKFLOW", key: "workflowKey", format: (v) => v || "" },
|
|
337
|
+
{ header: "RUN", key: "runId", format: (v) => (v ? formatId(v) : "") },
|
|
333
338
|
{ header: "TRACE", key: "traceId", format: formatId },
|
|
334
339
|
]));
|
|
335
340
|
}
|
|
@@ -338,12 +343,28 @@ Examples:
|
|
|
338
343
|
process.exit(1);
|
|
339
344
|
}
|
|
340
345
|
});
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
//
|
|
344
|
-
|
|
346
|
+
// ============================================
|
|
347
|
+
// TESTS SUBCOMMAND
|
|
348
|
+
// ============================================
|
|
349
|
+
const tests = integrations
|
|
350
|
+
.command("tests")
|
|
351
|
+
.description("Run and inspect integration test cases")
|
|
352
|
+
.addHelpText("after", `
|
|
353
|
+
Test cases are authored in TOML at integrations/<key>.tests/<name>.toml and
|
|
354
|
+
applied with \`primitive config push\` (issue #2769); \`config fields integration\`
|
|
355
|
+
lists the fields. Deleting a case is removing its file and running
|
|
356
|
+
\`config push --prune\`.
|
|
357
|
+
|
|
358
|
+
Examples:
|
|
359
|
+
$ primitive integrations tests list <integration-id>
|
|
360
|
+
$ primitive integrations tests run <integration-id> <test-case-id>
|
|
361
|
+
$ primitive integrations tests run-all <integration-id>
|
|
362
|
+
$ primitive integrations tests run-all <integration-id> --test-cases 01ABC,01DEF,01GHI
|
|
363
|
+
`);
|
|
364
|
+
// List test cases
|
|
365
|
+
tests
|
|
345
366
|
.command("list")
|
|
346
|
-
.description("List
|
|
367
|
+
.description("List test cases for an integration")
|
|
347
368
|
.argument("<integration-id>", "Integration ID")
|
|
348
369
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
349
370
|
.option("--json", "Output as JSON")
|
|
@@ -351,20 +372,19 @@ Examples:
|
|
|
351
372
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
352
373
|
const client = new ApiClient();
|
|
353
374
|
try {
|
|
354
|
-
const
|
|
375
|
+
const { items } = await client.listTestCases(resolvedAppId, "integration", integrationId);
|
|
355
376
|
if (options.json) {
|
|
356
|
-
json(
|
|
377
|
+
json(items);
|
|
357
378
|
return;
|
|
358
379
|
}
|
|
359
|
-
if (!
|
|
360
|
-
info("No
|
|
380
|
+
if (!items || items.length === 0) {
|
|
381
|
+
info("No test cases found.");
|
|
361
382
|
return;
|
|
362
383
|
}
|
|
363
|
-
console.log(formatTable(
|
|
364
|
-
{ header: "ID", key: "
|
|
365
|
-
{ header: "
|
|
366
|
-
{ header: "
|
|
367
|
-
{ header: "STATUS", key: "status", format: formatStatus },
|
|
384
|
+
console.log(formatTable(items, [
|
|
385
|
+
{ header: "ID", key: "testCaseId", format: formatId },
|
|
386
|
+
{ header: "NAME", key: "name" },
|
|
387
|
+
{ header: "CONFIG", key: "configId", format: (v) => v ? formatId(v) : "-" },
|
|
368
388
|
{ header: "CREATED", key: "createdAt", format: formatDate },
|
|
369
389
|
]));
|
|
370
390
|
}
|
|
@@ -373,61 +393,243 @@ Examples:
|
|
|
373
393
|
process.exit(1);
|
|
374
394
|
}
|
|
375
395
|
});
|
|
376
|
-
//
|
|
377
|
-
|
|
378
|
-
.command("
|
|
379
|
-
.description("
|
|
396
|
+
// Get test case
|
|
397
|
+
tests
|
|
398
|
+
.command("get")
|
|
399
|
+
.description("Get test case details")
|
|
380
400
|
.argument("<integration-id>", "Integration ID")
|
|
401
|
+
.argument("<test-case-id>", "Test Case ID")
|
|
381
402
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
382
|
-
.option("--data <json>", "Secret data as JSON (e.g., '{\"apiKey\":\"...\"}' )")
|
|
383
|
-
.option("--summary <text>", "Description of the secret")
|
|
384
403
|
.option("--json", "Output as JSON")
|
|
385
|
-
.action(async (integrationId, options) => {
|
|
404
|
+
.action(async (integrationId, testCaseId, options) => {
|
|
386
405
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
387
|
-
|
|
388
|
-
|
|
406
|
+
const client = new ApiClient();
|
|
407
|
+
try {
|
|
408
|
+
const result = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
|
|
409
|
+
if (options.json) {
|
|
410
|
+
json(result);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
printResult("Test Case ID", result.testCaseId);
|
|
414
|
+
printResult("Name", result.name);
|
|
415
|
+
printResult("Config ID", result.configId || "-");
|
|
416
|
+
printResult("Created", formatDate(result.createdAt));
|
|
417
|
+
divider();
|
|
418
|
+
info("Input Variables:");
|
|
419
|
+
console.log(JSON.stringify(testCaseInputVariables(result.inputVariables), null, 2));
|
|
420
|
+
if (result.expectedOutputPattern) {
|
|
421
|
+
divider();
|
|
422
|
+
printResult("Expected Pattern", result.expectedOutputPattern);
|
|
423
|
+
}
|
|
424
|
+
if (result.expectedOutputContains) {
|
|
425
|
+
divider();
|
|
426
|
+
info("Expected Contains:");
|
|
427
|
+
try {
|
|
428
|
+
console.log(JSON.stringify(JSON.parse(result.expectedOutputContains), null, 2));
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
console.log(result.expectedOutputContains);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (result.expectedJsonSubset) {
|
|
435
|
+
divider();
|
|
436
|
+
info("Expected JSON Subset:");
|
|
437
|
+
try {
|
|
438
|
+
console.log(JSON.stringify(JSON.parse(result.expectedJsonSubset), null, 2));
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
console.log(result.expectedJsonSubset);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (result.evaluatorPromptId) {
|
|
445
|
+
divider();
|
|
446
|
+
printResult("Evaluator Prompt", result.evaluatorPromptId);
|
|
447
|
+
printResult("Evaluator Config", result.evaluatorConfigId || "-");
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
catch (err) {
|
|
451
|
+
error(err.message);
|
|
389
452
|
process.exit(1);
|
|
390
453
|
}
|
|
391
|
-
|
|
454
|
+
});
|
|
455
|
+
// Run a single test case
|
|
456
|
+
tests
|
|
457
|
+
.command("run")
|
|
458
|
+
.description("Run a single test case")
|
|
459
|
+
.argument("<integration-id>", "Integration ID")
|
|
460
|
+
.argument("<test-case-id>", "Test Case ID")
|
|
461
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
462
|
+
.option("--config <config-id>", "Override config ID")
|
|
463
|
+
.option("--json", "Output as JSON")
|
|
464
|
+
.action(async (integrationId, testCaseId, options) => {
|
|
465
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
466
|
+
const client = new ApiClient();
|
|
392
467
|
try {
|
|
393
|
-
|
|
468
|
+
// Get test case to retrieve its variables
|
|
469
|
+
const testCase = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
|
|
470
|
+
// #2968 — the case's variables ARE the request the run issues, so a
|
|
471
|
+
// dropped `inputVariables` here is the config's bare defaults instead
|
|
472
|
+
// of the case's method, path and body. The server hands them back
|
|
473
|
+
// parsed; older servers hand back JSON text.
|
|
474
|
+
const variables = testCaseInputVariables(testCase.inputVariables);
|
|
475
|
+
const result = await client.executeBlockTest(resolvedAppId, "integration", integrationId, {
|
|
476
|
+
variables,
|
|
477
|
+
testCaseId,
|
|
478
|
+
configId: options.config || testCase.configId,
|
|
479
|
+
});
|
|
480
|
+
if (options.json) {
|
|
481
|
+
json(result);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
const passed = result.verification?.passed;
|
|
485
|
+
if (passed) {
|
|
486
|
+
success("Test PASSED");
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
error("Test FAILED");
|
|
490
|
+
}
|
|
491
|
+
keyValue("Duration", formatDuration(result.metrics?.durationMs));
|
|
492
|
+
if (result.verification) {
|
|
493
|
+
divider();
|
|
494
|
+
info("Verification:");
|
|
495
|
+
const v = result.verification;
|
|
496
|
+
keyValue(" Passed", v.passed ? chalk.green("Yes") : chalk.red("No"));
|
|
497
|
+
keyValue(" Checks", `${v.summary?.passed || 0}/${v.summary?.total || 0} passed`);
|
|
498
|
+
if (v.checks && v.checks.length > 0) {
|
|
499
|
+
console.log();
|
|
500
|
+
for (const check of v.checks) {
|
|
501
|
+
const icon = check.passed ? chalk.green("\u2713") : chalk.red("\u2717");
|
|
502
|
+
console.log(` ${icon} ${check.name}`);
|
|
503
|
+
if (!check.passed && check.message) {
|
|
504
|
+
console.log(` ${chalk.dim(check.message)}`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if (result.output) {
|
|
510
|
+
divider();
|
|
511
|
+
info("Output:");
|
|
512
|
+
console.log(typeof result.output === "string" ? result.output : JSON.stringify(result.output, null, 2));
|
|
513
|
+
}
|
|
514
|
+
if (result.error) {
|
|
515
|
+
divider();
|
|
516
|
+
error(`Error: ${result.error}`);
|
|
517
|
+
}
|
|
518
|
+
if (!passed) {
|
|
519
|
+
process.exit(1);
|
|
520
|
+
}
|
|
394
521
|
}
|
|
395
|
-
catch {
|
|
396
|
-
error(
|
|
522
|
+
catch (err) {
|
|
523
|
+
error(err.message);
|
|
397
524
|
process.exit(1);
|
|
398
525
|
}
|
|
526
|
+
});
|
|
527
|
+
// Run all test cases (or a specific group)
|
|
528
|
+
tests
|
|
529
|
+
.command("run-all")
|
|
530
|
+
.description("Run all test cases for an integration, or a specific subset")
|
|
531
|
+
.argument("<integration-id>", "Integration ID")
|
|
532
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
533
|
+
.option("--config <config-id>", "Override config ID for all tests")
|
|
534
|
+
.option("--test-cases <ids>", "Comma-separated list of test case IDs to run (runs only these)")
|
|
535
|
+
.option("--json", "Output as JSON")
|
|
536
|
+
.action(async (integrationId, options) => {
|
|
537
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
399
538
|
const client = new ApiClient();
|
|
400
539
|
try {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
540
|
+
// Parse test case IDs if provided
|
|
541
|
+
let testCaseIds;
|
|
542
|
+
if (options.testCases) {
|
|
543
|
+
testCaseIds = options.testCases.split(",").map((id) => id.trim()).filter(Boolean);
|
|
544
|
+
if (testCaseIds.length === 0) {
|
|
545
|
+
error("No valid test case IDs provided in --test-cases");
|
|
546
|
+
process.exit(1);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (!options.json) {
|
|
550
|
+
if (testCaseIds) {
|
|
551
|
+
info(`Running ${testCaseIds.length} selected test case(s)...`);
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
info("Running all test cases...");
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
const result = await client.runAllTestCases(resolvedAppId, "integration", integrationId, {
|
|
558
|
+
overrideConfigId: options.config,
|
|
559
|
+
testCaseIds,
|
|
404
560
|
});
|
|
405
561
|
if (options.json) {
|
|
406
562
|
json(result);
|
|
407
563
|
return;
|
|
408
564
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
keyValue("
|
|
565
|
+
const { summary, runs, comparisonGroup } = result;
|
|
566
|
+
divider();
|
|
567
|
+
keyValue("Comparison Group", comparisonGroup);
|
|
568
|
+
keyValue("Total Tests", summary.total);
|
|
569
|
+
keyValue("Passed", chalk.green(summary.passed));
|
|
570
|
+
keyValue("Failed", summary.failed > 0 ? chalk.red(summary.failed) : "0");
|
|
571
|
+
divider();
|
|
572
|
+
if (runs && runs.length > 0) {
|
|
573
|
+
for (const r of runs) {
|
|
574
|
+
const passed = r.verification?.passed;
|
|
575
|
+
const icon = passed ? chalk.green("\u2713") : chalk.red("\u2717");
|
|
576
|
+
const status = passed ? "PASSED" : "FAILED";
|
|
577
|
+
console.log(`${icon} ${r.testCaseName} - ${status}`);
|
|
578
|
+
if (!passed && r.verification?.details?.reason) {
|
|
579
|
+
console.log(` ${chalk.dim(r.verification.details.reason)}`);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
// Exit with error code if any tests failed
|
|
584
|
+
if (summary.failed > 0) {
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
412
587
|
}
|
|
413
588
|
catch (err) {
|
|
414
589
|
error(err.message);
|
|
415
590
|
process.exit(1);
|
|
416
591
|
}
|
|
417
592
|
});
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
.command("
|
|
421
|
-
.description("
|
|
593
|
+
// List test runs
|
|
594
|
+
tests
|
|
595
|
+
.command("runs")
|
|
596
|
+
.description("List recent test runs for an integration")
|
|
422
597
|
.argument("<integration-id>", "Integration ID")
|
|
423
|
-
.argument("<secret-id>", "Secret ID")
|
|
424
598
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
425
|
-
.
|
|
599
|
+
.option("--limit <n>", "Maximum number of runs to show", "20")
|
|
600
|
+
.option("--group <group>", "Filter by comparison group")
|
|
601
|
+
.option("--json", "Output as JSON")
|
|
602
|
+
.action(async (integrationId, options) => {
|
|
426
603
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
427
604
|
const client = new ApiClient();
|
|
428
605
|
try {
|
|
429
|
-
await client.
|
|
430
|
-
|
|
606
|
+
const { items } = await client.listTestRuns(resolvedAppId, "integration", integrationId, {
|
|
607
|
+
limit: parseInt(options.limit),
|
|
608
|
+
comparisonGroup: options.group,
|
|
609
|
+
});
|
|
610
|
+
if (options.json) {
|
|
611
|
+
json(items);
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
if (!items || items.length === 0) {
|
|
615
|
+
info("No test runs found.");
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
console.log(formatTable(items, [
|
|
619
|
+
{ header: "RUN ID", key: "runId", format: formatId },
|
|
620
|
+
{ header: "TEST CASE ID", key: "testCaseId", format: (v) => v ? formatId(v) : "-" },
|
|
621
|
+
{
|
|
622
|
+
header: "PASSED",
|
|
623
|
+
key: "verificationPassed",
|
|
624
|
+
format: (v) => v === true
|
|
625
|
+
? chalk.green("Yes")
|
|
626
|
+
: v === false
|
|
627
|
+
? chalk.red("No")
|
|
628
|
+
: "-",
|
|
629
|
+
},
|
|
630
|
+
{ header: "DURATION", key: "durationMs", format: formatDuration },
|
|
631
|
+
{ header: "STARTED", key: "startedAt", format: formatDate },
|
|
632
|
+
]));
|
|
431
633
|
}
|
|
432
634
|
catch (err) {
|
|
433
635
|
error(err.message);
|