primitive-admin 1.0.62 → 1.0.64
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 +132 -42
- package/assets/skill/skills/primitive-platform/SKILL.md +142 -661
- package/dist/bin/primitive.js +121 -41
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.js +37 -50
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.js +178 -9
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.js +17 -7
- 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.js +76 -116
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.js +2 -1
- package/dist/src/commands/blob-buckets.js.map +1 -1
- package/dist/src/commands/catalog.js +26 -10
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.js +3 -10
- package/dist/src/commands/collection-type-configs.js.map +1 -1
- package/dist/src/commands/collections.js +736 -19
- package/dist/src/commands/collections.js.map +1 -1
- package/dist/src/commands/config.js +13 -27
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/connections.js +8 -9
- package/dist/src/commands/connections.js.map +1 -1
- package/dist/src/commands/cron-triggers.js +2 -1
- package/dist/src/commands/cron-triggers.js.map +1 -1
- package/dist/src/commands/database-type-configs.js +5 -12
- package/dist/src/commands/database-type-configs.js.map +1 -1
- package/dist/src/commands/databases.js +59 -72
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +58 -0
- package/dist/src/commands/documents.js +1623 -95
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.js +5 -4
- package/dist/src/commands/email-templates.js.map +1 -1
- package/dist/src/commands/env.d.ts +1 -1
- package/dist/src/commands/env.js +106 -44
- package/dist/src/commands/env.js.map +1 -1
- package/dist/src/commands/feature-flags.js +2 -1
- package/dist/src/commands/feature-flags.js.map +1 -1
- 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.js +2 -1
- package/dist/src/commands/group-type-configs.js.map +1 -1
- package/dist/src/commands/groups.js +30 -17
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.js +17 -11
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +24 -12
- package/dist/src/commands/init.js +198 -110
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +65 -26
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/locks.js +17 -2
- package/dist/src/commands/locks.js.map +1 -1
- package/dist/src/commands/metadata-category-configs.js +2 -1
- package/dist/src/commands/metadata-category-configs.js.map +1 -1
- package/dist/src/commands/metadata.js +8 -1
- package/dist/src/commands/metadata.js.map +1 -1
- package/dist/src/commands/prompts.js +106 -59
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.js +3 -10
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +10 -0
- package/dist/src/commands/scripts.js +159 -25
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/secrets.js +2 -1
- package/dist/src/commands/secrets.js.map +1 -1
- package/dist/src/commands/sessions.js +10 -9
- package/dist/src/commands/sessions.js.map +1 -1
- package/dist/src/commands/sync-app-settings.js +3 -5
- package/dist/src/commands/sync-app-settings.js.map +1 -1
- package/dist/src/commands/sync.d.ts +391 -44
- package/dist/src/commands/sync.js +2622 -534
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.js +2 -1
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.js +19 -10
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.js +2 -1
- package/dist/src/commands/vars.js.map +1 -1
- package/dist/src/commands/waitlist.js +2 -1
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +29 -0
- package/dist/src/commands/webhooks.js +135 -64
- package/dist/src/commands/webhooks.js.map +1 -1
- package/dist/src/commands/workflows.d.ts +1 -29
- package/dist/src/commands/workflows.js +113 -179
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +628 -14
- package/dist/src/lib/api-client.js +776 -70
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +1 -1
- package/dist/src/lib/app-settings-descriptor.js +9 -1
- package/dist/src/lib/app-settings-descriptor.js.map +1 -1
- 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/codegen-shared/resolveCodegenSourceDir.d.ts +24 -54
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +31 -153
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
- 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.js +88 -6
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/config-payload.d.ts +8 -1
- package/dist/src/lib/config-payload.js +49 -4
- package/dist/src/lib/config-payload.js.map +1 -1
- package/dist/src/lib/config-surface.d.ts +12 -1
- package/dist/src/lib/config-surface.js +71 -3
- package/dist/src/lib/config-surface.js.map +1 -1
- package/dist/src/lib/config.d.ts +31 -13
- package/dist/src/lib/config.js +34 -70
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/credentials-store.d.ts +37 -22
- package/dist/src/lib/credentials-store.js +103 -97
- package/dist/src/lib/credentials-store.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTypeIR.js +8 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -1
- 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 +128 -17
- package/dist/src/lib/env-resolver-core.js +204 -22
- package/dist/src/lib/env-resolver-core.js.map +1 -1
- package/dist/src/lib/env-resolver.d.ts +18 -3
- package/dist/src/lib/env-resolver.js +23 -3
- package/dist/src/lib/env-resolver.js.map +1 -1
- 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.js +4 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +2332 -78
- package/dist/src/lib/generated-config-surfaces.js +6979 -468
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- 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/init-adopt.js +2 -2
- package/dist/src/lib/init-adopt.js.map +1 -1
- package/dist/src/lib/init-assets.js +3 -3
- 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 +1 -1
- package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
- package/dist/src/lib/init-email-redirect-uris.js +46 -0
- package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
- package/dist/src/lib/init-ios-links.d.ts +41 -0
- package/dist/src/lib/init-ios-links.js +67 -1
- package/dist/src/lib/init-ios-links.js.map +1 -1
- package/dist/src/lib/init-plan.d.ts +1 -1
- package/dist/src/lib/init-plan.js +1 -1
- package/dist/src/lib/init-xcode.d.ts +6 -5
- package/dist/src/lib/init-xcode.js +34 -10
- package/dist/src/lib/init-xcode.js.map +1 -1
- 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 +1 -1
- package/dist/src/lib/local-state.js +1 -1
- 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 +152 -5
- package/dist/src/lib/log-inspection.js +179 -2
- package/dist/src/lib/log-inspection.js.map +1 -1
- 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/output.d.ts +15 -0
- package/dist/src/lib/output.js +28 -0
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/paginate.d.ts +15 -0
- package/dist/src/lib/paginate.js +17 -0
- package/dist/src/lib/paginate.js.map +1 -1
- package/dist/src/lib/project-config.d.ts +46 -21
- package/dist/src/lib/project-config.js +74 -47
- package/dist/src/lib/project-config.js.map +1 -1
- 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/refresh-admin-credentials.d.ts +9 -1
- package/dist/src/lib/refresh-admin-credentials.js +22 -2
- package/dist/src/lib/refresh-admin-credentials.js.map +1 -1
- 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/skill-installer.d.ts +49 -3
- package/dist/src/lib/skill-installer.js +275 -100
- package/dist/src/lib/skill-installer.js.map +1 -1
- 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 +8 -9
- package/dist/src/lib/snapshots.js +20 -83
- package/dist/src/lib/snapshots.js.map +1 -1
- 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.js +19 -7
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
- 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 +7 -1
- package/dist/src/lib/swift-codegen/generator.js +28 -11
- package/dist/src/lib/swift-codegen/generator.js.map +1 -1
- package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +15 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js +21 -4
- package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -1
- package/dist/src/lib/sync-paths.d.ts +72 -55
- package/dist/src/lib/sync-paths.js +97 -100
- package/dist/src/lib/sync-paths.js.map +1 -1
- package/dist/src/lib/sync-resource-types.d.ts +23 -4
- package/dist/src/lib/sync-resource-types.js +106 -8
- package/dist/src/lib/sync-resource-types.js.map +1 -1
- package/dist/src/lib/sync-selectors.d.ts +45 -2
- package/dist/src/lib/sync-selectors.js +66 -5
- package/dist/src/lib/sync-selectors.js.map +1 -1
- package/dist/src/lib/template.d.ts +2 -2
- package/dist/src/lib/template.js +2 -2
- 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 +1 -1
- package/dist/src/lib/test-case-keys.js +1 -1
- package/dist/src/lib/test-case-variables.d.ts +14 -0
- package/dist/src/lib/test-case-variables.js +42 -0
- package/dist/src/lib/test-case-variables.js.map +1 -1
- package/dist/src/lib/toml-database-config.js +19 -2
- package/dist/src/lib/toml-database-config.js.map +1 -1
- 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-codegen/generator.d.ts +1 -1
- package/dist/src/lib/workflow-codegen/generator.js +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +17 -8
- package/dist/src/lib/workflow-toml-validator.js +25 -12
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- 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 +12 -2
- package/package.json +5 -4
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app's web counterpart, as a normalized web origin (#2982).
|
|
3
|
+
*
|
|
4
|
+
* One environment value with two jobs on the iOS side: the emailed sign-in
|
|
5
|
+
* link points at `<webUrl>/oauth/callback`, and the same origin is what an
|
|
6
|
+
* incoming universal link is trusted from. Both jobs need an ORIGIN, not just
|
|
7
|
+
* a URL that parses:
|
|
8
|
+
*
|
|
9
|
+
* - https except loopback, the same rule the server applies to every
|
|
10
|
+
* redirect URI (`src/auth/redirect-uri.ts`) — an origin that cannot be
|
|
11
|
+
* allow-listed turns every sign-in request into a 400;
|
|
12
|
+
* - no path, query or fragment: the web client derives its callback from its
|
|
13
|
+
* own origin plus `/oauth/callback` and has no base-path mode, and the
|
|
14
|
+
* `apple-app-site-association` component matches that exact path;
|
|
15
|
+
* - no credentials, which have no business in a link that goes out by email.
|
|
16
|
+
*
|
|
17
|
+
* Returns the `string | true` shape `@inquirer/prompts` expects, like
|
|
18
|
+
* `validateServerUrl`, so the same function backs the flag check, the project
|
|
19
|
+
* config's field validation and any future prompt.
|
|
20
|
+
*
|
|
21
|
+
* This is the surface that EXPLAINS a rejection. The same rule is applied
|
|
22
|
+
* silently — value or nothing — by every reader that feeds `primitive.json`
|
|
23
|
+
* without going through the CLI: `normalizeWebOrigin` in `env-resolver-core.ts`
|
|
24
|
+
* (which cannot import this file; it is copied verbatim into a package that
|
|
25
|
+
* must not depend on the CLI), its bash/python3 port in the Swift template's
|
|
26
|
+
* `resolve-primitive-config.sh`, and `PrimitiveAppState.linksBaseURL` as the
|
|
27
|
+
* app's own floor. `web-url-parity` in the project-config tests pins that the
|
|
28
|
+
* two TypeScript halves accept and normalize exactly the same values.
|
|
29
|
+
*/
|
|
30
|
+
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1"]);
|
|
31
|
+
/** The example every message ends with, so a rejection is actionable. */
|
|
32
|
+
const SHAPE = "e.g. https://app.example.com (or http://localhost:5173 in dev)";
|
|
33
|
+
/**
|
|
34
|
+
* Validates a web origin. Returns `true` when valid, otherwise the message to
|
|
35
|
+
* show the user.
|
|
36
|
+
*/
|
|
37
|
+
export function validateWebUrl(value) {
|
|
38
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
39
|
+
return `Web URL cannot be empty — ${SHAPE}`;
|
|
40
|
+
}
|
|
41
|
+
let url;
|
|
42
|
+
try {
|
|
43
|
+
url = new URL(value);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return `Please enter an absolute URL — ${SHAPE}`;
|
|
47
|
+
}
|
|
48
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
49
|
+
return `Web URL must be http(s) — ${SHAPE}`;
|
|
50
|
+
}
|
|
51
|
+
if (url.protocol === "http:" && !LOOPBACK_HOSTS.has(url.hostname)) {
|
|
52
|
+
return `Web URL must use https outside localhost — the server refuses a non-loopback http redirect URI (${SHAPE})`;
|
|
53
|
+
}
|
|
54
|
+
if (url.username || url.password) {
|
|
55
|
+
return `Web URL must not carry credentials — ${SHAPE}`;
|
|
56
|
+
}
|
|
57
|
+
if (url.pathname !== "/" && url.pathname !== "") {
|
|
58
|
+
return `Web URL must be an origin with no path — the web app serves its sign-in callback on its own origin (${SHAPE})`;
|
|
59
|
+
}
|
|
60
|
+
if (url.search) {
|
|
61
|
+
return `Web URL must not carry a query — ${SHAPE}`;
|
|
62
|
+
}
|
|
63
|
+
if (url.hash) {
|
|
64
|
+
return `Web URL must not carry a fragment — ${SHAPE}`;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The origin form of an already-validated web URL: lowercased host, explicit
|
|
70
|
+
* port kept, no trailing slash — so `https://app.example.com/` and
|
|
71
|
+
* `https://app.example.com` are stored, compared and joined identically.
|
|
72
|
+
*/
|
|
73
|
+
export function normalizeWebUrl(value) {
|
|
74
|
+
return new URL(value).origin;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=web-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-url.js","sourceRoot":"","sources":["../../../src/lib/web-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AAE3D,yEAAyE;AACzE,MAAM,KAAK,GAAG,gEAAgE,CAAC;AAE/E;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/C,OAAO,6BAA6B,KAAK,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kCAAkC,KAAK,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1D,OAAO,6BAA6B,KAAK,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClE,OAAO,mGAAmG,KAAK,GAAG,CAAC;IACrH,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO,wCAAwC,KAAK,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QAChD,OAAO,uGAAuG,KAAK,GAAG,CAAC;IACzH,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,oCAAoC,KAAK,EAAE,CAAC;IACrD,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,uCAAuC,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deliver a signed preview through a webhook's real receive path (#3321).
|
|
3
|
+
*
|
|
4
|
+
* `primitive webhooks test --deliver` adds no server dispatch surface. It
|
|
5
|
+
* composes two capabilities that already exist:
|
|
6
|
+
*
|
|
7
|
+
* 1. the admin-gated preview `POST /admin/api/apps/{appId}/webhooks/{id}/test`,
|
|
8
|
+
* which signs a payload with the same rule the receiver verifies with, and
|
|
9
|
+
* 2. the public receive endpoint `POST /app/{appId}/webhook/{webhookKey}`,
|
|
10
|
+
* the unauthenticated path a provider posts to.
|
|
11
|
+
*
|
|
12
|
+
* So the delivery is a real delivery: the body cap, the availability check, the
|
|
13
|
+
* IP allowlist, signature verification, handshake rules, deduplication, the run
|
|
14
|
+
* row and the delivery log all run exactly as they do for a provider. Nobody
|
|
15
|
+
* gains authority they did not have — only someone who can already administer
|
|
16
|
+
* the app can obtain a signature — and nothing bypasses verification, because
|
|
17
|
+
* the signature is checked for real at the receive endpoint.
|
|
18
|
+
*
|
|
19
|
+
* ── What this module owes the caller ──────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* An honest report. The receive endpoint answers `{received: true}` and
|
|
22
|
+
* discloses nothing else (it must not: it is unauthenticated), so "did the
|
|
23
|
+
* function actually run?" is answered from the delivery log and the runs
|
|
24
|
+
* surface, and only positive evidence may be reported as a dispatch:
|
|
25
|
+
*
|
|
26
|
+
* - **Correlation is one rule.** A delivery-log row NEWER than a baseline
|
|
27
|
+
* snapshot taken before the POST, whose `dedupKey` equals the one the
|
|
28
|
+
* preview returned. That key hashes the whole signed payload including its
|
|
29
|
+
* timestamp prefix, so it is unique to this request rather than a
|
|
30
|
+
* heuristic; the baseline is what keeps a replay of the same signed bytes
|
|
31
|
+
* from being attributed here. There is no body-hash fallback: identical
|
|
32
|
+
* bodies collide, and attributing another request's row is worse than
|
|
33
|
+
* declining to.
|
|
34
|
+
* - **The key names dispatched deliveries only.** The receiver writes
|
|
35
|
+
* `dedupKey` on an `accepted` row that really dispatched and OMITS it
|
|
36
|
+
* everywhere else — on a handshake row, a duplicate, a rejection, a 202
|
|
37
|
+
* non-dispatch, and on the `accepted` row of a delivery whose target was
|
|
38
|
+
* not found (`webhook-receiver.ts`, `logEvent`). That omission is what
|
|
39
|
+
* keeps the `eventsByDedupKey` index holding exactly the deliveries that
|
|
40
|
+
* may suppress a later one, so it is load-bearing, not incidental. The
|
|
41
|
+
* consequence here: a delivery the receiver did not dispatch has no row
|
|
42
|
+
* this correlator can reach, and is reported as unconfirmed — with what
|
|
43
|
+
* the absence of the key means — rather than named from a row.
|
|
44
|
+
* - **A run is confirmed, not assumed.** An `accepted` row names a run id
|
|
45
|
+
* before the run finishes, and the legacy workflow branch keeps its
|
|
46
|
+
* `accepted` row and its HTTP 200 even when the launch is skipped or
|
|
47
|
+
* throws. So the named run is looked up on the authenticated runs surface
|
|
48
|
+
* before dispatch is claimed.
|
|
49
|
+
* - **Everything else is named for what it was** — a suppressed replay, a
|
|
50
|
+
* 410/403/401 refusal, each of which the receive endpoint reports for
|
|
51
|
+
* itself — or reported as "dispatch unconfirmed", which is where a
|
|
52
|
+
* handshake short-circuit (it can legally answer 200 `{received:true}`
|
|
53
|
+
* before any dispatch) and a 202 non-dispatch land, since neither records
|
|
54
|
+
* a correlatable row. Only a confirmed dispatch exits `0`.
|
|
55
|
+
*/
|
|
56
|
+
export type DeliverOutcome = "dispatched" | "refused" | "unconfirmed";
|
|
57
|
+
export interface WebhookPreview {
|
|
58
|
+
success?: boolean;
|
|
59
|
+
payload?: unknown;
|
|
60
|
+
rawBody: string;
|
|
61
|
+
signatureHeaders: Record<string, string>;
|
|
62
|
+
verificationScheme: string;
|
|
63
|
+
timestamp?: number;
|
|
64
|
+
/** #3321 — the receive path's key; absent on a pre-upgrade server. */
|
|
65
|
+
webhookKey?: string | null;
|
|
66
|
+
/** #3321 — the owning server function, or null for a standalone webhook. */
|
|
67
|
+
functionId?: string | null;
|
|
68
|
+
/** #3321 — the correlator; null for scheme `none`. */
|
|
69
|
+
dedupKey?: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface WebhookEventRow {
|
|
72
|
+
eventId: string;
|
|
73
|
+
status?: string | null;
|
|
74
|
+
httpStatus?: number | null;
|
|
75
|
+
rejectionReason?: string | null;
|
|
76
|
+
dedupKey?: string | null;
|
|
77
|
+
workflowRunId?: string | null;
|
|
78
|
+
workflowRunKey?: string | null;
|
|
79
|
+
createdAt?: string | null;
|
|
80
|
+
[key: string]: unknown;
|
|
81
|
+
}
|
|
82
|
+
export interface EventPage {
|
|
83
|
+
items: WebhookEventRow[];
|
|
84
|
+
nextCursor?: string | null;
|
|
85
|
+
}
|
|
86
|
+
export interface RunPage {
|
|
87
|
+
items: any[];
|
|
88
|
+
nextCursor?: string | null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The admin reads and the one admin write this flow needs.
|
|
92
|
+
*
|
|
93
|
+
* `ApiClient` satisfies it as written; the live api test implements the same
|
|
94
|
+
* five methods over the test context's authenticated client, which is what lets
|
|
95
|
+
* this module be proven end to end against a real server.
|
|
96
|
+
*/
|
|
97
|
+
export interface WebhookDeliverClient {
|
|
98
|
+
testWebhook(appId: string, webhookId: string, payload?: any): Promise<any>;
|
|
99
|
+
listWebhookEvents(appId: string, webhookId: string, params?: {
|
|
100
|
+
limit?: number;
|
|
101
|
+
cursor?: string;
|
|
102
|
+
}): Promise<EventPage>;
|
|
103
|
+
getWebhook(appId: string, webhookId: string): Promise<any>;
|
|
104
|
+
listFunctionRuns(appId: string, functionId: string, params?: {
|
|
105
|
+
limit?: number;
|
|
106
|
+
cursor?: string;
|
|
107
|
+
}): Promise<RunPage>;
|
|
108
|
+
listWorkflowRuns(appId: string, workflowId: string, params?: {
|
|
109
|
+
limit?: number;
|
|
110
|
+
cursor?: string;
|
|
111
|
+
}): Promise<RunPage>;
|
|
112
|
+
}
|
|
113
|
+
export type FetchLike = (url: string, init: any) => Promise<any>;
|
|
114
|
+
export interface DeliverInput {
|
|
115
|
+
appId: string;
|
|
116
|
+
webhookId: string;
|
|
117
|
+
/** The payload to sign, passed to the preview endpoint unchanged. */
|
|
118
|
+
payload?: any;
|
|
119
|
+
/** The API base URL — the receive endpoint lives under it. */
|
|
120
|
+
serverUrl: string;
|
|
121
|
+
}
|
|
122
|
+
export interface DeliverDeps {
|
|
123
|
+
client: WebhookDeliverClient;
|
|
124
|
+
fetchImpl?: FetchLike;
|
|
125
|
+
sleep?: (ms: number) => Promise<void>;
|
|
126
|
+
/** Called with the side-effect notice, before anything is delivered. */
|
|
127
|
+
onBeforeDeliver?: (notice: string[]) => void;
|
|
128
|
+
/** Bounds, overridable for tests. */
|
|
129
|
+
pollAttempts?: number;
|
|
130
|
+
pollIntervalMs?: number;
|
|
131
|
+
pageCap?: number;
|
|
132
|
+
pageLimit?: number;
|
|
133
|
+
runPageCap?: number;
|
|
134
|
+
runPageLimit?: number;
|
|
135
|
+
timeoutMs?: number;
|
|
136
|
+
}
|
|
137
|
+
export interface DeliveryAttempt {
|
|
138
|
+
url: string;
|
|
139
|
+
/** True once the request left the CLI, whatever came back. */
|
|
140
|
+
sent: boolean;
|
|
141
|
+
status: number | null;
|
|
142
|
+
body: any;
|
|
143
|
+
duplicate: boolean;
|
|
144
|
+
/** Why no response was observed, when none was. */
|
|
145
|
+
error: string | null;
|
|
146
|
+
}
|
|
147
|
+
export interface RunConfirmation {
|
|
148
|
+
runId: string | null;
|
|
149
|
+
confirmed: boolean;
|
|
150
|
+
surface: "function" | "workflow" | null;
|
|
151
|
+
reason: string | null;
|
|
152
|
+
}
|
|
153
|
+
export interface DeliverResult {
|
|
154
|
+
outcome: DeliverOutcome;
|
|
155
|
+
/** One sentence naming what happened. */
|
|
156
|
+
headline: string;
|
|
157
|
+
/** Further lines worth printing — remediation, inspection hints. */
|
|
158
|
+
details: string[];
|
|
159
|
+
/** The side-effect announcement, printed before the delivery. */
|
|
160
|
+
notice: string[];
|
|
161
|
+
preview: WebhookPreview | null;
|
|
162
|
+
refusal: {
|
|
163
|
+
message: string;
|
|
164
|
+
code: string | null;
|
|
165
|
+
} | null;
|
|
166
|
+
delivery: DeliveryAttempt | null;
|
|
167
|
+
event: WebhookEventRow | null;
|
|
168
|
+
run: RunConfirmation | null;
|
|
169
|
+
}
|
|
170
|
+
/** ~5 attempts over ~4 s: the accepted row is written before execution ends. */
|
|
171
|
+
export declare const DELIVER_POLL_ATTEMPTS = 5;
|
|
172
|
+
export declare const DELIVER_POLL_INTERVAL_MS = 800;
|
|
173
|
+
/** Cursor pages walked per attempt, so a busy log cannot outrun the poll. */
|
|
174
|
+
export declare const DELIVER_PAGE_CAP = 10;
|
|
175
|
+
export declare const DELIVER_PAGE_LIMIT = 25;
|
|
176
|
+
/** The same bound on the runs surface, where runs start while this one waits. */
|
|
177
|
+
export declare const DELIVER_RUN_PAGE_CAP = 5;
|
|
178
|
+
export declare const DELIVER_RUN_PAGE_LIMIT = 50;
|
|
179
|
+
/** Comfortably above the sync-function ceiling. */
|
|
180
|
+
export declare const DELIVER_TIMEOUT_MS = 60000;
|
|
181
|
+
/**
|
|
182
|
+
* What the user is told before a delivery happens, in the terminal rather than
|
|
183
|
+
* only in the guide: a diagnostic that mutates the app has to say so where the
|
|
184
|
+
* user is looking (criterion 4).
|
|
185
|
+
*/
|
|
186
|
+
export declare function deliveryNotice(scheme: string): string[];
|
|
187
|
+
/**
|
|
188
|
+
* The one correlation rule: the newest row above `baselineEventId` whose
|
|
189
|
+
* `dedupKey` equals this preview's.
|
|
190
|
+
*
|
|
191
|
+
* The walk is newest-first and follows `nextCursor`, stopping at the baseline
|
|
192
|
+
* row (every row below it predates this delivery) or at `pageCap`. A null
|
|
193
|
+
* baseline means the log was empty when the snapshot was taken, so every row
|
|
194
|
+
* walked is a candidate.
|
|
195
|
+
*/
|
|
196
|
+
export declare function findDeliveryEvent(input: {
|
|
197
|
+
client: WebhookDeliverClient;
|
|
198
|
+
appId: string;
|
|
199
|
+
webhookId: string;
|
|
200
|
+
dedupKey: string;
|
|
201
|
+
baselineEventId: string | null;
|
|
202
|
+
pageCap?: number;
|
|
203
|
+
pageLimit?: number;
|
|
204
|
+
}): Promise<WebhookEventRow | null>;
|
|
205
|
+
/**
|
|
206
|
+
* Preview, deliver, correlate, confirm — the whole flow, as one result a caller
|
|
207
|
+
* renders however it likes.
|
|
208
|
+
*/
|
|
209
|
+
export declare function deliverWebhookTest(input: DeliverInput, deps: DeliverDeps): Promise<DeliverResult>;
|