primitive-admin 1.1.0-alpha.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +523 -109
- package/assets/skill/skills/primitive-platform/SKILL.md +289 -0
- package/dist/bin/primitive.d.ts +2 -0
- package/dist/bin/primitive.js +372 -21
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.d.ts +2 -0
- package/dist/src/commands/admins.js +136 -30
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +2 -0
- package/dist/src/commands/analytics.js +713 -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 +65 -100
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth-sessions.d.ts +7 -0
- package/dist/src/commands/auth-sessions.js +144 -0
- package/dist/src/commands/auth-sessions.js.map +1 -0
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +238 -108
- 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 +331 -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 +63 -48
- 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 +85 -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 +1282 -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 +465 -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 +99 -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 +266 -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 +164 -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 +1887 -243
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +60 -0
- package/dist/src/commands/documents.js +2888 -22
- 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 +175 -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 +395 -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 +117 -0
- package/dist/src/commands/feature-flags.js.map +1 -0
- package/dist/src/commands/functions.d.ts +20 -0
- package/dist/src/commands/functions.js +1630 -0
- package/dist/src/commands/functions.js.map +1 -0
- package/dist/src/commands/group-type-configs.d.ts +2 -0
- package/dist/src/commands/group-type-configs.js +87 -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 +65 -113
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.d.ts +223 -0
- package/dist/src/commands/guides.js +627 -69
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +37 -0
- package/dist/src/commands/init.js +1693 -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 +428 -187
- 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 +175 -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 +113 -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 +288 -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 +322 -634
- 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 +139 -148
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +30 -0
- package/dist/src/commands/scripts.js +688 -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 +109 -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 +76 -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 +328 -0
- package/dist/src/commands/sync-app-settings.js.map +1 -0
- package/dist/src/commands/sync.d.ts +2670 -0
- package/dist/src/commands/sync.js +17144 -834
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.d.ts +2 -0
- package/dist/src/commands/tokens.js +132 -22
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.d.ts +2 -0
- package/dist/src/commands/users.js +542 -24
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.d.ts +8 -0
- package/dist/src/commands/vars.js +97 -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 +12 -11
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +31 -0
- package/dist/src/commands/webhooks.js +633 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.d.ts +88 -0
- package/dist/src/commands/workflows.js +1568 -742
- 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 +2550 -0
- package/dist/src/lib/api-client.js +2503 -160
- 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 +583 -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/block-selector.d.ts +58 -0
- package/dist/src/lib/block-selector.js +92 -0
- package/dist/src/lib/block-selector.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 +38 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +46 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
- package/dist/src/lib/collection-export.d.ts +184 -0
- package/dist/src/lib/collection-export.js +252 -0
- package/dist/src/lib/collection-export.js.map +1 -0
- package/dist/src/lib/config-json-field.d.ts +28 -0
- package/dist/src/lib/config-json-field.js +56 -0
- package/dist/src/lib/config-json-field.js.map +1 -0
- package/dist/src/lib/config-object-descriptor.d.ts +127 -0
- package/dist/src/lib/config-object-descriptor.js +740 -0
- package/dist/src/lib/config-object-descriptor.js.map +1 -0
- package/dist/src/lib/config-payload.d.ts +92 -0
- package/dist/src/lib/config-payload.js +161 -0
- package/dist/src/lib/config-payload.js.map +1 -0
- package/dist/src/lib/config-surface.d.ts +141 -0
- package/dist/src/lib/config-surface.js +368 -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 +71 -0
- package/dist/src/lib/config.js +71 -68
- 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 +104 -0
- package/dist/src/lib/credentials-store.js +336 -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 +525 -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/deprecation.d.ts +22 -0
- package/dist/src/lib/deprecation.js +43 -0
- package/dist/src/lib/deprecation.js.map +1 -0
- package/dist/src/lib/document-export-permissions.d.ts +30 -0
- package/dist/src/lib/document-export-permissions.js +54 -0
- package/dist/src/lib/document-export-permissions.js.map +1 -0
- package/dist/src/lib/document-ingest-artifact.d.ts +120 -0
- package/dist/src/lib/document-ingest-artifact.js +505 -0
- package/dist/src/lib/document-ingest-artifact.js.map +1 -0
- package/dist/src/lib/document-ingest-input.d.ts +51 -0
- package/dist/src/lib/document-ingest-input.js +132 -0
- package/dist/src/lib/document-ingest-input.js.map +1 -0
- package/dist/src/lib/document-ingest-rows.d.ts +137 -0
- package/dist/src/lib/document-ingest-rows.js +181 -0
- package/dist/src/lib/document-ingest-rows.js.map +1 -0
- package/dist/src/lib/document-ingest.d.ts +101 -0
- package/dist/src/lib/document-ingest.js +384 -0
- package/dist/src/lib/document-ingest.js.map +1 -0
- package/dist/src/lib/env-resolver-core.d.ts +258 -0
- package/dist/src/lib/env-resolver-core.js +447 -0
- package/dist/src/lib/env-resolver-core.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +99 -0
- package/dist/src/lib/env-resolver.js +153 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/fetch.d.ts +5 -0
- package/dist/src/lib/function-bundle.d.ts +147 -0
- package/dist/src/lib/function-bundle.js +341 -0
- package/dist/src/lib/function-bundle.js.map +1 -0
- package/dist/src/lib/function-collect.d.ts +123 -0
- package/dist/src/lib/function-collect.js +610 -0
- package/dist/src/lib/function-collect.js.map +1 -0
- package/dist/src/lib/function-db-types.d.ts +202 -0
- package/dist/src/lib/function-db-types.js +870 -0
- package/dist/src/lib/function-db-types.js.map +1 -0
- package/dist/src/lib/function-document-types.d.ts +144 -0
- package/dist/src/lib/function-document-types.js +370 -0
- package/dist/src/lib/function-document-types.js.map +1 -0
- package/dist/src/lib/function-grants-preflight.d.ts +64 -0
- package/dist/src/lib/function-grants-preflight.js +105 -0
- package/dist/src/lib/function-grants-preflight.js.map +1 -0
- package/dist/src/lib/function-log-lines.d.ts +76 -0
- package/dist/src/lib/function-log-lines.js +160 -0
- package/dist/src/lib/function-log-lines.js.map +1 -0
- package/dist/src/lib/function-log-row.d.ts +29 -0
- package/dist/src/lib/function-log-row.js +73 -0
- package/dist/src/lib/function-log-row.js.map +1 -0
- package/dist/src/lib/function-log-tail.d.ts +132 -0
- package/dist/src/lib/function-log-tail.js +262 -0
- package/dist/src/lib/function-log-tail.js.map +1 -0
- package/dist/src/lib/function-run.d.ts +289 -0
- package/dist/src/lib/function-run.js +389 -0
- package/dist/src/lib/function-run.js.map +1 -0
- package/dist/src/lib/function-schema-codegen.d.ts +143 -0
- package/dist/src/lib/function-schema-codegen.js +420 -0
- package/dist/src/lib/function-schema-codegen.js.map +1 -0
- package/dist/src/lib/function-sync.d.ts +459 -0
- package/dist/src/lib/function-sync.js +1258 -0
- package/dist/src/lib/function-sync.js.map +1 -0
- package/dist/src/lib/function-trigger-listing.d.ts +27 -0
- package/dist/src/lib/function-trigger-listing.js +70 -0
- package/dist/src/lib/function-trigger-listing.js.map +1 -0
- package/dist/src/lib/function-typecheck.d.ts +86 -0
- package/dist/src/lib/function-typecheck.js +370 -0
- package/dist/src/lib/function-typecheck.js.map +1 -0
- package/dist/src/lib/function-versions.d.ts +122 -0
- package/dist/src/lib/function-versions.js +182 -0
- package/dist/src/lib/function-versions.js.map +1 -0
- package/dist/src/lib/generated-allowlist.d.ts +28 -0
- package/dist/src/lib/generated-allowlist.js +281 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -0
- package/dist/src/lib/generated-config-surfaces.d.ts +2936 -0
- package/dist/src/lib/generated-config-surfaces.js +10569 -0
- package/dist/src/lib/generated-config-surfaces.js.map +1 -0
- package/dist/src/lib/generated-sdk-types.d.ts +12 -0
- package/dist/src/lib/generated-sdk-types.js +13 -0
- package/dist/src/lib/generated-sdk-types.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 +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-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 +91 -0
- package/dist/src/lib/init-ios-links.js +219 -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 +34 -0
- package/dist/src/lib/init-xcode.js +138 -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/ios-app-id.d.ts +34 -0
- package/dist/src/lib/ios-app-id.js +69 -0
- package/dist/src/lib/ios-app-id.js.map +1 -0
- package/dist/src/lib/list-options.d.ts +68 -0
- package/dist/src/lib/list-options.js +89 -0
- package/dist/src/lib/list-options.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 +136 -0
- package/dist/src/lib/local-test-cases.js.map +1 -0
- package/dist/src/lib/log-inspection.d.ts +715 -0
- package/dist/src/lib/log-inspection.js +816 -0
- package/dist/src/lib/log-inspection.js.map +1 -0
- package/dist/src/lib/logout-admin-session.d.ts +33 -0
- package/dist/src/lib/logout-admin-session.js +70 -0
- package/dist/src/lib/logout-admin-session.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 +124 -0
- package/dist/src/lib/output.js +219 -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 +98 -0
- package/dist/src/lib/paginate.js +112 -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 +122 -0
- package/dist/src/lib/project-config.js +244 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/prompt-cost-format.d.ts +11 -0
- package/dist/src/lib/prompt-cost-format.js +41 -0
- package/dist/src/lib/prompt-cost-format.js.map +1 -0
- package/dist/src/lib/prompt-schema-codegen.d.ts +147 -0
- package/dist/src/lib/prompt-schema-codegen.js +462 -0
- package/dist/src/lib/prompt-schema-codegen.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 +73 -0
- package/dist/src/lib/refresh-admin-credentials.js +123 -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-owner.d.ts +19 -0
- package/dist/src/lib/resolve-owner.js +20 -0
- package/dist/src/lib/resolve-owner.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 +71 -0
- package/dist/src/lib/skill-installer.js +441 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/snapshot-audit-source.d.ts +45 -0
- package/dist/src/lib/snapshot-audit-source.js +58 -0
- package/dist/src/lib/snapshot-audit-source.js.map +1 -0
- package/dist/src/lib/snapshot-audit-store.d.ts +52 -0
- package/dist/src/lib/snapshot-audit-store.js +196 -0
- package/dist/src/lib/snapshot-audit-store.js.map +1 -0
- package/dist/src/lib/snapshot-audit.d.ts +207 -0
- package/dist/src/lib/snapshot-audit.js +431 -0
- package/dist/src/lib/snapshot-audit.js.map +1 -0
- package/dist/src/lib/snapshot-build-rows.d.ts +60 -0
- package/dist/src/lib/snapshot-build-rows.js +87 -0
- package/dist/src/lib/snapshot-build-rows.js.map +1 -0
- package/dist/src/lib/snapshot-build.d.ts +50 -0
- package/dist/src/lib/snapshot-build.js +111 -0
- package/dist/src/lib/snapshot-build.js.map +1 -0
- package/dist/src/lib/snapshot-manifest-layout.d.ts +61 -0
- package/dist/src/lib/snapshot-manifest-layout.js +70 -0
- package/dist/src/lib/snapshot-manifest-layout.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +98 -0
- package/dist/src/lib/snapshots.js +294 -0
- package/dist/src/lib/snapshots.js.map +1 -0
- package/dist/src/lib/step-run-table.d.ts +43 -0
- package/dist/src/lib/step-run-table.js +129 -0
- package/dist/src/lib/step-run-table.js.map +1 -0
- package/dist/src/lib/storage-pending-retry.d.ts +26 -0
- package/dist/src/lib/storage-pending-retry.js +42 -0
- package/dist/src/lib/storage-pending-retry.js.map +1 -0
- package/dist/src/lib/swift-codegen/agentGenerator.d.ts +42 -0
- package/dist/src/lib/swift-codegen/agentGenerator.js +118 -0
- package/dist/src/lib/swift-codegen/agentGenerator.js.map +1 -0
- package/dist/src/lib/swift-codegen/banners.d.ts +24 -0
- package/dist/src/lib/swift-codegen/banners.js +25 -0
- package/dist/src/lib/swift-codegen/banners.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +113 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js +926 -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/functionGenerator.d.ts +139 -0
- package/dist/src/lib/swift-codegen/functionGenerator.js +462 -0
- package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -0
- package/dist/src/lib/swift-codegen/generator.d.ts +100 -0
- package/dist/src/lib/swift-codegen/generator.js +457 -0
- package/dist/src/lib/swift-codegen/generator.js.map +1 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +87 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js +661 -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 +128 -0
- package/dist/src/lib/sync-paths.js +195 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/sync-resource-types.d.ts +563 -0
- package/dist/src/lib/sync-resource-types.js +1073 -0
- package/dist/src/lib/sync-resource-types.js.map +1 -0
- package/dist/src/lib/sync-selectors.d.ts +138 -0
- package/dist/src/lib/sync-selectors.js +289 -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-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 +29 -0
- package/dist/src/lib/test-case-variables.js +71 -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 +544 -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/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/webhook-deliver.d.ts +209 -0
- package/dist/src/lib/webhook-deliver.js +519 -0
- package/dist/src/lib/webhook-deliver.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 +211 -0
- package/dist/src/lib/workflow-toml-validator.js +770 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- package/dist/src/lib/workflow-usage.d.ts +196 -0
- package/dist/src/lib/workflow-usage.js +310 -0
- package/dist/src/lib/workflow-usage.js.map +1 -0
- package/dist/src/types/index.d.ts +591 -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 +34 -9
|
@@ -1,18 +1,38 @@
|
|
|
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 { requireTestCaseInputVariables, testCaseInputVariables, } from "../lib/test-case-variables.js";
|
|
9
|
+
import { resolveIntegrationSelector } from "../lib/integration-selector.js";
|
|
10
|
+
import { normalizeCliListEnvelope } from "../lib/paginate.js";
|
|
11
|
+
import { pageCursorOption, pageLimitOption, parsePageLimit, printEmptyPage, printPageHint, } from "../lib/list-options.js";
|
|
6
12
|
export function registerIntegrationsCommands(program) {
|
|
7
13
|
const integrations = program
|
|
8
14
|
.command("integrations")
|
|
9
|
-
.description("Configure external HTTP API connections
|
|
15
|
+
.description("Configure external HTTP API connections")
|
|
10
16
|
.addHelpText("after", `
|
|
11
17
|
Examples:
|
|
12
18
|
$ primitive integrations list
|
|
13
|
-
$ primitive
|
|
19
|
+
$ primitive config create integration weather-api # scaffold integrations/weather-api.toml
|
|
20
|
+
$ primitive config push --only integration/weather-api # apply it
|
|
14
21
|
$ primitive integrations test 01HXY...
|
|
15
|
-
$ primitive integrations
|
|
22
|
+
$ primitive integrations archive 01HXY... # retire it (soft delete)
|
|
23
|
+
|
|
24
|
+
Storing credentials for an integration:
|
|
25
|
+
$ primitive secrets set MY_API_KEY --value <value>
|
|
26
|
+
# then reference it in integration config via {{secrets.MY_API_KEY}}
|
|
27
|
+
`);
|
|
28
|
+
// Server-side configuration is authored in TOML and applied with `config push`
|
|
29
|
+
// (issue #2645) — this group no longer carries config-setting flags.
|
|
30
|
+
integrations.addHelpText("after", `
|
|
31
|
+
Configuration lives in integrations/<key>.toml:
|
|
32
|
+
$ primitive config fields integration # the file's keys, types and defaults
|
|
33
|
+
$ primitive config create integration <key> # scaffold one locally
|
|
34
|
+
$ primitive config set integration/<key> <path>=<value>
|
|
35
|
+
$ primitive config push --only integration/<key>
|
|
16
36
|
`);
|
|
17
37
|
// List integrations
|
|
18
38
|
integrations
|
|
@@ -20,21 +40,33 @@ Examples:
|
|
|
20
40
|
.description("List integrations")
|
|
21
41
|
.argument("[app-id]", "App ID (uses current app if not specified)")
|
|
22
42
|
.option("--app <app-id>", "App ID")
|
|
23
|
-
.option("--status <status>", "Filter by status:
|
|
43
|
+
.option("--status <status>", "Filter by status: active, inactive, archived")
|
|
44
|
+
.addOption(pageLimitOption())
|
|
45
|
+
.addOption(pageCursorOption())
|
|
24
46
|
.option("--json", "Output as JSON")
|
|
25
47
|
.action(async (appId, options) => {
|
|
48
|
+
const limit = parsePageLimit(options.limit);
|
|
26
49
|
const resolvedAppId = resolveAppId(appId, options);
|
|
27
50
|
const client = new ApiClient();
|
|
28
51
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
52
|
+
// #2803 — `draft` is gone; refuse it by name rather than returning the
|
|
53
|
+
// empty list a canonical filter would produce.
|
|
54
|
+
const page = normalizeCliListEnvelope(await client.listIntegrations(resolvedAppId, {
|
|
55
|
+
status: parseStatusFilter("integrations", options.status, [
|
|
56
|
+
"active",
|
|
57
|
+
"inactive",
|
|
58
|
+
"archived",
|
|
59
|
+
]),
|
|
60
|
+
limit,
|
|
61
|
+
cursor: options.cursor,
|
|
62
|
+
}));
|
|
63
|
+
const items = page.items;
|
|
32
64
|
if (options.json) {
|
|
33
|
-
json(
|
|
65
|
+
json(page);
|
|
34
66
|
return;
|
|
35
67
|
}
|
|
36
|
-
if (
|
|
37
|
-
|
|
68
|
+
if (items.length === 0) {
|
|
69
|
+
printEmptyPage(page, "integrations");
|
|
38
70
|
return;
|
|
39
71
|
}
|
|
40
72
|
console.log(formatTable(items, [
|
|
@@ -44,201 +76,168 @@ Examples:
|
|
|
44
76
|
{ header: "STATUS", key: "status", format: formatStatus },
|
|
45
77
|
{ header: "MODIFIED", key: "modifiedAt", format: formatDate },
|
|
46
78
|
]));
|
|
79
|
+
printPageHint(page);
|
|
47
80
|
}
|
|
48
81
|
catch (err) {
|
|
49
82
|
error(err.message);
|
|
50
83
|
process.exit(1);
|
|
51
84
|
}
|
|
52
85
|
});
|
|
53
|
-
//
|
|
86
|
+
// #2645 criterion 9 / #2803 — the operational verbs. They are the only
|
|
87
|
+
// writers of `status`, which is server-owned and no longer a TOML key.
|
|
54
88
|
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")
|
|
89
|
+
.command("disable")
|
|
90
|
+
.description("Take integration out of service now. Operational, not configuration: `status` is server-owned and 'config push' can neither set nor clear it.")
|
|
91
|
+
.argument("<integration-id>", "Integration ID")
|
|
92
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
67
93
|
.option("--json", "Output as JSON")
|
|
68
|
-
.action(async (
|
|
69
|
-
const resolvedAppId = resolveAppId(
|
|
94
|
+
.action(async (id, options) => {
|
|
95
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
70
96
|
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
97
|
try {
|
|
107
|
-
const result = await client.
|
|
98
|
+
const result = await client.setIntegrationAvailability(resolvedAppId, id, "disable");
|
|
108
99
|
if (options.json) {
|
|
109
100
|
json(result);
|
|
110
101
|
return;
|
|
111
102
|
}
|
|
112
|
-
success(`Integration
|
|
113
|
-
keyValue("Integration ID", result.integrationId);
|
|
114
|
-
keyValue("Key", result.integrationKey);
|
|
103
|
+
success(`Integration disabled: ${result.integrationKey || id}`);
|
|
115
104
|
}
|
|
116
105
|
catch (err) {
|
|
117
106
|
error(err.message);
|
|
118
107
|
process.exit(1);
|
|
119
108
|
}
|
|
120
109
|
});
|
|
121
|
-
// Get integration
|
|
122
110
|
integrations
|
|
123
|
-
.command("
|
|
124
|
-
.description("
|
|
111
|
+
.command("enable")
|
|
112
|
+
.description("Put integration back in service.")
|
|
125
113
|
.argument("<integration-id>", "Integration ID")
|
|
126
114
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
127
115
|
.option("--json", "Output as JSON")
|
|
128
|
-
.action(async (
|
|
116
|
+
.action(async (id, options) => {
|
|
129
117
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
130
118
|
const client = new ApiClient();
|
|
131
119
|
try {
|
|
132
|
-
const result = await client.
|
|
120
|
+
const result = await client.setIntegrationAvailability(resolvedAppId, id, "enable");
|
|
133
121
|
if (options.json) {
|
|
134
122
|
json(result);
|
|
135
123
|
return;
|
|
136
124
|
}
|
|
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
|
-
}
|
|
125
|
+
success(`Integration enabled: ${result.integrationKey || id}`);
|
|
159
126
|
}
|
|
160
127
|
catch (err) {
|
|
161
128
|
error(err.message);
|
|
162
129
|
process.exit(1);
|
|
163
130
|
}
|
|
164
131
|
});
|
|
165
|
-
//
|
|
132
|
+
// #2907 — the delete flow's CLI spelling. Not a second writer of `status`:
|
|
133
|
+
// this is the plain `DELETE` the server has always answered by writing the
|
|
134
|
+
// tombstone, which until now only the admin API and the console could reach.
|
|
135
|
+
// Named `archive`, not `delete`, because a configuration noun gets no
|
|
136
|
+
// `delete` verb (docs/cli-design.md) and prune-by-push stays the only CLI
|
|
137
|
+
// hard-delete path.
|
|
166
138
|
integrations
|
|
167
|
-
.command("
|
|
168
|
-
.description("
|
|
139
|
+
.command("archive")
|
|
140
|
+
.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
141
|
.argument("<integration-id>", "Integration ID")
|
|
170
142
|
.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")
|
|
143
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
175
144
|
.option("--json", "Output as JSON")
|
|
176
|
-
.
|
|
145
|
+
.addHelpText("after", `
|
|
146
|
+
What archiving an integration costs:
|
|
147
|
+
The proxy refuses it, and so does every workflow step that calls it.
|
|
148
|
+
The archived row still holds its integrationKey, so a push cannot re-create
|
|
149
|
+
one under the same key.
|
|
150
|
+
\`primitive integrations enable\` refuses an archived integration; there is no
|
|
151
|
+
un-archive.
|
|
152
|
+
|
|
153
|
+
Reclaiming the key means hard-deleting the row:
|
|
154
|
+
$ rm integrations/<key>.toml
|
|
155
|
+
$ primitive config push --prune # confirmed; hard-deletes the row
|
|
156
|
+
# or hard-delete it in the console, then re-add the file and push.
|
|
157
|
+
`)
|
|
158
|
+
.action(async (id, options) => {
|
|
177
159
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
160
|
+
if (!options.yes) {
|
|
161
|
+
let confirmed;
|
|
162
|
+
try {
|
|
163
|
+
confirmed = await confirmPrompt(`Archive integration ${id}? It is retired, goes on holding its key, ` +
|
|
164
|
+
`and there is no un-archive.`);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
error(err.message);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
if (!confirmed) {
|
|
171
|
+
info("Cancelled.");
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
190
174
|
}
|
|
191
175
|
const client = new ApiClient();
|
|
192
176
|
try {
|
|
193
|
-
|
|
177
|
+
// The soft delete: no `hard`, so the server writes the tombstone and
|
|
178
|
+
// keeps the row (and its canonical block mirror) in step.
|
|
179
|
+
const result = await client.deleteIntegration(resolvedAppId, id);
|
|
194
180
|
if (options.json) {
|
|
195
181
|
json(result);
|
|
196
182
|
return;
|
|
197
183
|
}
|
|
198
|
-
success(
|
|
184
|
+
success(`Integration archived: ${id}`);
|
|
185
|
+
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
186
|
}
|
|
200
187
|
catch (err) {
|
|
201
188
|
error(err.message);
|
|
202
189
|
process.exit(1);
|
|
203
190
|
}
|
|
204
191
|
});
|
|
205
|
-
// Delete integration
|
|
206
192
|
integrations
|
|
207
|
-
.command("
|
|
208
|
-
.description("
|
|
193
|
+
.command("get")
|
|
194
|
+
.description("Get integration details")
|
|
209
195
|
.argument("<integration-id>", "Integration ID")
|
|
210
196
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
211
|
-
.option("--
|
|
212
|
-
.option("-y, --yes", "Skip confirmation prompt")
|
|
197
|
+
.option("--json", "Output as JSON")
|
|
213
198
|
.action(async (integrationId, options) => {
|
|
214
199
|
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
200
|
const client = new ApiClient();
|
|
232
201
|
try {
|
|
233
|
-
await client.
|
|
234
|
-
|
|
202
|
+
const result = await client.getIntegration(resolvedAppId, integrationId);
|
|
203
|
+
if (options.json) {
|
|
204
|
+
json(result);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
printResult("Integration ID", result.integrationId);
|
|
208
|
+
printResult("Key", result.integrationKey);
|
|
209
|
+
printResult("Name", result.displayName);
|
|
210
|
+
printResult("Description", result.description);
|
|
211
|
+
printResult("Status", formatStatus(result.status));
|
|
212
|
+
printResult("Timeout", result.timeoutMs ? `${result.timeoutMs}ms` : "-");
|
|
213
|
+
// #2631: no rule means every non-admin call is denied. Print that in
|
|
214
|
+
// words — a blank or "-" would read as "unrestricted" and hide an
|
|
215
|
+
// integration that was never given a rule.
|
|
216
|
+
printResult("Access Rule", typeof result.accessRule === "string" && result.accessRule !== ""
|
|
217
|
+
? result.accessRule
|
|
218
|
+
: "(none — all non-admin calls are denied; set one to allow callers)");
|
|
219
|
+
if (result.requestConfig) {
|
|
220
|
+
divider();
|
|
221
|
+
info("Request Config:");
|
|
222
|
+
printResult(" Base URL", result.requestConfig.baseUrl);
|
|
223
|
+
printResult(" Allowed Methods", result.requestConfig.allowedMethods?.join(", ") || "all");
|
|
224
|
+
printResult(" Allowed Paths", result.requestConfig.allowedPaths?.join(", ") || "all");
|
|
225
|
+
printResult(" Response Passthrough", result.requestConfig.responsePassthrough);
|
|
226
|
+
if (result.requestConfig.bodyMode) {
|
|
227
|
+
printResult(" Body Mode", result.requestConfig.bodyMode);
|
|
228
|
+
}
|
|
229
|
+
if (result.requestConfig.multipartFieldMapping?.length) {
|
|
230
|
+
printResult(" Multipart Fields", result.requestConfig.multipartFieldMapping
|
|
231
|
+
.map((f) => `${f.fieldName} (${f.type}${f.attachmentIndex != null ? `, attachment[${f.attachmentIndex}]` : ""})`)
|
|
232
|
+
.join(", "));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
235
|
}
|
|
236
236
|
catch (err) {
|
|
237
237
|
error(err.message);
|
|
238
238
|
process.exit(1);
|
|
239
239
|
}
|
|
240
240
|
});
|
|
241
|
-
// Test integration
|
|
242
241
|
integrations
|
|
243
242
|
.command("test")
|
|
244
243
|
.description("Test an integration by making a request")
|
|
@@ -304,20 +303,37 @@ Examples:
|
|
|
304
303
|
// List integration logs
|
|
305
304
|
integrations
|
|
306
305
|
.command("logs")
|
|
307
|
-
.description("View integration request logs")
|
|
306
|
+
.description("View integration request logs (includes workflow-initiated calls; filter with --source workflow|user|admin|test)")
|
|
308
307
|
.argument("<integration-id>", "Integration ID")
|
|
309
308
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
310
309
|
.option("--limit <n>", "Number of logs to show", "20")
|
|
310
|
+
.option("--source <source>", "Filter by call source: user, admin, test, or workflow")
|
|
311
|
+
.option("--run <run-id>", "Only the calls this run made (a workflow run or a function run)")
|
|
312
|
+
.option("--status <status>", "Filter by upstream HTTP status (e.g. 200, 500)")
|
|
313
|
+
.option("--from <iso>", "Only logs at or after this ISO timestamp")
|
|
314
|
+
.option("--to <iso>", "Only logs at or before this ISO timestamp")
|
|
311
315
|
.option("--json", "Output as JSON")
|
|
312
316
|
.action(async (integrationId, options) => {
|
|
313
317
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
314
318
|
const client = new ApiClient();
|
|
315
319
|
try {
|
|
320
|
+
const validSources = new Set(["user", "admin", "test", "workflow"]);
|
|
321
|
+
if (options.source && !validSources.has(options.source)) {
|
|
322
|
+
error(`Invalid --source value '${options.source}'. Must be one of: user, admin, test, workflow.`);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
316
325
|
const logs = await client.listIntegrationLogs(resolvedAppId, integrationId, {
|
|
317
326
|
limit: parseInt(options.limit),
|
|
327
|
+
...(options.source && { source: options.source }),
|
|
328
|
+
// #3691 — the run pivot. A function run's id and a workflow run's
|
|
329
|
+
// are read the same way, because a row names its run either way.
|
|
330
|
+
...(options.run && { runId: options.run }),
|
|
331
|
+
...(options.status && { status: options.status }),
|
|
332
|
+
...(options.from && { from: options.from }),
|
|
333
|
+
...(options.to && { to: options.to }),
|
|
318
334
|
});
|
|
319
335
|
if (options.json) {
|
|
320
|
-
json(logs);
|
|
336
|
+
json(buildIntegrationEnvelope(logs));
|
|
321
337
|
return;
|
|
322
338
|
}
|
|
323
339
|
if (!logs || logs.length === 0) {
|
|
@@ -326,10 +342,13 @@ Examples:
|
|
|
326
342
|
}
|
|
327
343
|
console.log(formatTable(logs, [
|
|
328
344
|
{ header: "TIME", key: "timestamp", format: formatDate },
|
|
345
|
+
{ header: "SOURCE", key: "source", format: (v) => v || "user" },
|
|
329
346
|
{ header: "METHOD", key: "method" },
|
|
330
347
|
{ header: "PATH", key: "path" },
|
|
331
348
|
{ header: "STATUS", key: "status" },
|
|
332
349
|
{ header: "DURATION", key: "durationMs", format: formatDuration },
|
|
350
|
+
{ header: "WORKFLOW", key: "workflowKey", format: (v) => v || "" },
|
|
351
|
+
{ header: "RUN", key: "runId", format: (v) => (v ? formatId(v) : "") },
|
|
333
352
|
{ header: "TRACE", key: "traceId", format: formatId },
|
|
334
353
|
]));
|
|
335
354
|
}
|
|
@@ -338,96 +357,318 @@ Examples:
|
|
|
338
357
|
process.exit(1);
|
|
339
358
|
}
|
|
340
359
|
});
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
//
|
|
344
|
-
|
|
360
|
+
// ============================================
|
|
361
|
+
// TESTS SUBCOMMAND
|
|
362
|
+
// ============================================
|
|
363
|
+
const tests = integrations
|
|
364
|
+
.command("tests")
|
|
365
|
+
.description("Run and inspect integration test cases")
|
|
366
|
+
.addHelpText("after", `
|
|
367
|
+
Test cases are authored in TOML at integrations/<key>.tests/<name>.toml and
|
|
368
|
+
applied with \`primitive config push\` (issue #2769); \`config fields integration\`
|
|
369
|
+
lists the fields. Deleting a case is removing its file and running
|
|
370
|
+
\`config push --prune\`.
|
|
371
|
+
|
|
372
|
+
Every verb here takes the integration's KEY or its ID (#3000). An identifier
|
|
373
|
+
that names no integration in the app fails; \`Total Tests: 0\` only ever means
|
|
374
|
+
the integration exists and has no cases.
|
|
375
|
+
|
|
376
|
+
Examples:
|
|
377
|
+
$ primitive integrations tests list <integration>
|
|
378
|
+
$ primitive integrations tests run <integration> <test-case-id>
|
|
379
|
+
$ primitive integrations tests run-all <integration>
|
|
380
|
+
$ primitive integrations tests run-all <integration> --test-cases 01ABC,01DEF,01GHI
|
|
381
|
+
`);
|
|
382
|
+
// List test cases
|
|
383
|
+
tests
|
|
345
384
|
.command("list")
|
|
346
|
-
.description("List
|
|
347
|
-
.argument("<integration
|
|
385
|
+
.description("List test cases for an integration")
|
|
386
|
+
.argument("<integration>", "Integration key or ID")
|
|
348
387
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
388
|
+
.addOption(pageLimitOption())
|
|
389
|
+
.addOption(pageCursorOption())
|
|
349
390
|
.option("--json", "Output as JSON")
|
|
350
|
-
.action(async (
|
|
391
|
+
.action(async (integration, options) => {
|
|
392
|
+
const limit = parsePageLimit(options.limit);
|
|
351
393
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
352
394
|
const client = new ApiClient();
|
|
353
395
|
try {
|
|
354
|
-
|
|
396
|
+
// #3000 — resolve BEFORE listing: the test-case endpoint answers an
|
|
397
|
+
// unknown block with an empty page, so an unresolved identifier would
|
|
398
|
+
// print "No test cases found." and exit 0.
|
|
399
|
+
const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
|
|
400
|
+
const page = normalizeCliListEnvelope(await client.listTestCases(resolvedAppId, "integration", integrationId, {
|
|
401
|
+
limit,
|
|
402
|
+
cursor: options.cursor,
|
|
403
|
+
}));
|
|
404
|
+
const items = page.items;
|
|
355
405
|
if (options.json) {
|
|
356
|
-
json(
|
|
406
|
+
json(page);
|
|
357
407
|
return;
|
|
358
408
|
}
|
|
359
|
-
if (
|
|
360
|
-
|
|
409
|
+
if (items.length === 0) {
|
|
410
|
+
printEmptyPage(page, "test cases");
|
|
361
411
|
return;
|
|
362
412
|
}
|
|
363
|
-
console.log(formatTable(
|
|
364
|
-
{ header: "ID", key: "
|
|
365
|
-
{ header: "
|
|
366
|
-
{ header: "
|
|
367
|
-
{ header: "STATUS", key: "status", format: formatStatus },
|
|
413
|
+
console.log(formatTable(items, [
|
|
414
|
+
{ header: "ID", key: "testCaseId", format: formatId },
|
|
415
|
+
{ header: "NAME", key: "name" },
|
|
416
|
+
{ header: "CONFIG", key: "configId", format: (v) => v ? formatId(v) : "-" },
|
|
368
417
|
{ header: "CREATED", key: "createdAt", format: formatDate },
|
|
369
418
|
]));
|
|
419
|
+
printPageHint(page);
|
|
370
420
|
}
|
|
371
421
|
catch (err) {
|
|
372
422
|
error(err.message);
|
|
373
423
|
process.exit(1);
|
|
374
424
|
}
|
|
375
425
|
});
|
|
376
|
-
//
|
|
377
|
-
|
|
378
|
-
.command("
|
|
379
|
-
.description("
|
|
380
|
-
.argument("<integration
|
|
426
|
+
// Get test case
|
|
427
|
+
tests
|
|
428
|
+
.command("get")
|
|
429
|
+
.description("Get test case details")
|
|
430
|
+
.argument("<integration>", "Integration key or ID")
|
|
431
|
+
.argument("<test-case-id>", "Test Case ID")
|
|
381
432
|
.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
433
|
.option("--json", "Output as JSON")
|
|
385
|
-
.action(async (
|
|
434
|
+
.action(async (integration, testCaseId, options) => {
|
|
386
435
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
387
|
-
|
|
388
|
-
|
|
436
|
+
const client = new ApiClient();
|
|
437
|
+
try {
|
|
438
|
+
const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
|
|
439
|
+
const result = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
|
|
440
|
+
if (options.json) {
|
|
441
|
+
json(result);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
printResult("Test Case ID", result.testCaseId);
|
|
445
|
+
printResult("Name", result.name);
|
|
446
|
+
printResult("Config ID", result.configId || "-");
|
|
447
|
+
printResult("Created", formatDate(result.createdAt));
|
|
448
|
+
divider();
|
|
449
|
+
info("Input Variables:");
|
|
450
|
+
console.log(JSON.stringify(testCaseInputVariables(result.inputVariables), null, 2));
|
|
451
|
+
if (result.expectedOutputPattern) {
|
|
452
|
+
divider();
|
|
453
|
+
printResult("Expected Pattern", result.expectedOutputPattern);
|
|
454
|
+
}
|
|
455
|
+
if (result.expectedOutputContains) {
|
|
456
|
+
divider();
|
|
457
|
+
info("Expected Contains:");
|
|
458
|
+
try {
|
|
459
|
+
console.log(JSON.stringify(JSON.parse(result.expectedOutputContains), null, 2));
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
console.log(result.expectedOutputContains);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (result.expectedJsonSubset) {
|
|
466
|
+
divider();
|
|
467
|
+
info("Expected JSON Subset:");
|
|
468
|
+
try {
|
|
469
|
+
console.log(JSON.stringify(JSON.parse(result.expectedJsonSubset), null, 2));
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
console.log(result.expectedJsonSubset);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (result.evaluatorPromptId) {
|
|
476
|
+
divider();
|
|
477
|
+
printResult("Evaluator Prompt", result.evaluatorPromptId);
|
|
478
|
+
printResult("Evaluator Config", result.evaluatorConfigId || "-");
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
catch (err) {
|
|
482
|
+
error(err.message);
|
|
389
483
|
process.exit(1);
|
|
390
484
|
}
|
|
391
|
-
|
|
485
|
+
});
|
|
486
|
+
// Run a single test case
|
|
487
|
+
tests
|
|
488
|
+
.command("run")
|
|
489
|
+
.description("Run a single test case")
|
|
490
|
+
.argument("<integration>", "Integration key or ID")
|
|
491
|
+
.argument("<test-case-id>", "Test Case ID")
|
|
492
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
493
|
+
.option("--config <config-id>", "Override config ID")
|
|
494
|
+
.option("--json", "Output as JSON")
|
|
495
|
+
.action(async (integration, testCaseId, options) => {
|
|
496
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
497
|
+
const client = new ApiClient();
|
|
392
498
|
try {
|
|
393
|
-
|
|
499
|
+
const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
|
|
500
|
+
// Get test case to retrieve its variables
|
|
501
|
+
const testCase = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
|
|
502
|
+
// #2968 — the case's variables ARE the request the run issues, so a
|
|
503
|
+
// dropped `inputVariables` here is the config's bare defaults instead
|
|
504
|
+
// of the case's method, path and body. The server hands them back
|
|
505
|
+
// parsed; older servers hand back JSON text. #3158 — an input that
|
|
506
|
+
// cannot be read stops the run and says why, rather than issuing a
|
|
507
|
+
// request the case never authored.
|
|
508
|
+
const variables = requireTestCaseInputVariables(testCase.inputVariables, testCaseId);
|
|
509
|
+
const result = await client.executeBlockTest(resolvedAppId, "integration", integrationId, {
|
|
510
|
+
variables,
|
|
511
|
+
testCaseId,
|
|
512
|
+
configId: options.config || testCase.configId,
|
|
513
|
+
});
|
|
514
|
+
if (options.json) {
|
|
515
|
+
json(result);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const passed = result.verification?.passed;
|
|
519
|
+
if (passed) {
|
|
520
|
+
success("Test PASSED");
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
error("Test FAILED");
|
|
524
|
+
}
|
|
525
|
+
keyValue("Duration", formatDuration(result.metrics?.durationMs));
|
|
526
|
+
if (result.verification) {
|
|
527
|
+
divider();
|
|
528
|
+
info("Verification:");
|
|
529
|
+
const v = result.verification;
|
|
530
|
+
keyValue(" Passed", v.passed ? chalk.green("Yes") : chalk.red("No"));
|
|
531
|
+
keyValue(" Checks", `${v.summary?.passed || 0}/${v.summary?.total || 0} passed`);
|
|
532
|
+
if (v.checks && v.checks.length > 0) {
|
|
533
|
+
console.log();
|
|
534
|
+
for (const check of v.checks) {
|
|
535
|
+
const icon = check.passed ? chalk.green("\u2713") : chalk.red("\u2717");
|
|
536
|
+
console.log(` ${icon} ${check.name}`);
|
|
537
|
+
if (!check.passed && check.message) {
|
|
538
|
+
console.log(` ${chalk.dim(check.message)}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (result.output) {
|
|
544
|
+
divider();
|
|
545
|
+
info("Output:");
|
|
546
|
+
console.log(typeof result.output === "string" ? result.output : JSON.stringify(result.output, null, 2));
|
|
547
|
+
}
|
|
548
|
+
if (result.error) {
|
|
549
|
+
divider();
|
|
550
|
+
error(`Error: ${result.error}`);
|
|
551
|
+
}
|
|
552
|
+
if (!passed) {
|
|
553
|
+
process.exit(1);
|
|
554
|
+
}
|
|
394
555
|
}
|
|
395
|
-
catch {
|
|
396
|
-
error(
|
|
556
|
+
catch (err) {
|
|
557
|
+
error(err.message);
|
|
397
558
|
process.exit(1);
|
|
398
559
|
}
|
|
560
|
+
});
|
|
561
|
+
// Run all test cases (or a specific group)
|
|
562
|
+
tests
|
|
563
|
+
.command("run-all")
|
|
564
|
+
.description("Run all test cases for an integration, or a specific subset")
|
|
565
|
+
.argument("<integration>", "Integration key or ID")
|
|
566
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
567
|
+
.option("--config <config-id>", "Override config ID for all tests")
|
|
568
|
+
.option("--test-cases <ids>", "Comma-separated list of test case IDs to run (runs only these)")
|
|
569
|
+
.option("--json", "Output as JSON")
|
|
570
|
+
.action(async (integration, options) => {
|
|
571
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
399
572
|
const client = new ApiClient();
|
|
400
573
|
try {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
574
|
+
// #3000 — resolve BEFORE announcing the run: an unresolved identifier
|
|
575
|
+
// came back as `Total Tests: 0 / Failed: 0` and exit 0, which reads as
|
|
576
|
+
// a pass in CI.
|
|
577
|
+
const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
|
|
578
|
+
// Parse test case IDs if provided
|
|
579
|
+
let testCaseIds;
|
|
580
|
+
if (options.testCases) {
|
|
581
|
+
testCaseIds = options.testCases.split(",").map((id) => id.trim()).filter(Boolean);
|
|
582
|
+
if (testCaseIds.length === 0) {
|
|
583
|
+
error("No valid test case IDs provided in --test-cases");
|
|
584
|
+
process.exit(1);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (!options.json) {
|
|
588
|
+
if (testCaseIds) {
|
|
589
|
+
info(`Running ${testCaseIds.length} selected test case(s)...`);
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
info("Running all test cases...");
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
const result = await client.runAllTestCases(resolvedAppId, "integration", integrationId, {
|
|
596
|
+
overrideConfigId: options.config,
|
|
597
|
+
testCaseIds,
|
|
404
598
|
});
|
|
405
599
|
if (options.json) {
|
|
406
600
|
json(result);
|
|
407
601
|
return;
|
|
408
602
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
keyValue("
|
|
603
|
+
const { summary, runs, comparisonGroup } = result;
|
|
604
|
+
divider();
|
|
605
|
+
keyValue("Comparison Group", comparisonGroup);
|
|
606
|
+
keyValue("Total Tests", summary.total);
|
|
607
|
+
keyValue("Passed", chalk.green(summary.passed));
|
|
608
|
+
keyValue("Failed", summary.failed > 0 ? chalk.red(summary.failed) : "0");
|
|
609
|
+
divider();
|
|
610
|
+
if (runs && runs.length > 0) {
|
|
611
|
+
for (const r of runs) {
|
|
612
|
+
const passed = r.verification?.passed;
|
|
613
|
+
const icon = passed ? chalk.green("\u2713") : chalk.red("\u2717");
|
|
614
|
+
const status = passed ? "PASSED" : "FAILED";
|
|
615
|
+
console.log(`${icon} ${r.testCaseName} - ${status}`);
|
|
616
|
+
if (!passed && r.verification?.details?.reason) {
|
|
617
|
+
console.log(` ${chalk.dim(r.verification.details.reason)}`);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
// Exit with error code if any tests failed
|
|
622
|
+
if (summary.failed > 0) {
|
|
623
|
+
process.exit(1);
|
|
624
|
+
}
|
|
412
625
|
}
|
|
413
626
|
catch (err) {
|
|
414
627
|
error(err.message);
|
|
415
628
|
process.exit(1);
|
|
416
629
|
}
|
|
417
630
|
});
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
.command("
|
|
421
|
-
.description("
|
|
422
|
-
.argument("<integration
|
|
423
|
-
.argument("<secret-id>", "Secret ID")
|
|
631
|
+
// List test runs
|
|
632
|
+
tests
|
|
633
|
+
.command("runs")
|
|
634
|
+
.description("List recent test runs for an integration")
|
|
635
|
+
.argument("<integration>", "Integration key or ID")
|
|
424
636
|
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
425
|
-
.
|
|
637
|
+
.option("--limit <n>", "Maximum number of runs to show", "20")
|
|
638
|
+
.option("--group <group>", "Filter by comparison group")
|
|
639
|
+
.option("--json", "Output as JSON")
|
|
640
|
+
.action(async (integration, options) => {
|
|
426
641
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
427
642
|
const client = new ApiClient();
|
|
428
643
|
try {
|
|
429
|
-
await client
|
|
430
|
-
|
|
644
|
+
const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
|
|
645
|
+
const { items } = await client.listTestRuns(resolvedAppId, "integration", integrationId, {
|
|
646
|
+
limit: parseInt(options.limit),
|
|
647
|
+
comparisonGroup: options.group,
|
|
648
|
+
});
|
|
649
|
+
if (options.json) {
|
|
650
|
+
json(items);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
if (!items || items.length === 0) {
|
|
654
|
+
info("No test runs found.");
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
console.log(formatTable(items, [
|
|
658
|
+
{ header: "RUN ID", key: "runId", format: formatId },
|
|
659
|
+
{ header: "TEST CASE ID", key: "testCaseId", format: (v) => v ? formatId(v) : "-" },
|
|
660
|
+
{
|
|
661
|
+
header: "PASSED",
|
|
662
|
+
key: "verificationPassed",
|
|
663
|
+
format: (v) => v === true
|
|
664
|
+
? chalk.green("Yes")
|
|
665
|
+
: v === false
|
|
666
|
+
? chalk.red("No")
|
|
667
|
+
: "-",
|
|
668
|
+
},
|
|
669
|
+
{ header: "DURATION", key: "durationMs", format: formatDuration },
|
|
670
|
+
{ header: "STARTED", key: "startedAt", format: formatDate },
|
|
671
|
+
]));
|
|
431
672
|
}
|
|
432
673
|
catch (err) {
|
|
433
674
|
error(err.message);
|