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,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Building a server function's bundle, in the CLI (#3179, project
|
|
3
|
+
* `server-functions`).
|
|
4
|
+
*
|
|
5
|
+
* The intent decides that the build happens here and never on the server:
|
|
6
|
+
* `config push` runs esbuild over the authored `entry`, inlines the npm
|
|
7
|
+
* dependencies, and ships the built bundle next to the authored source bytes
|
|
8
|
+
* in one envelope. The server verifies the hash and stores the object; it does
|
|
9
|
+
* not compile anything.
|
|
10
|
+
*
|
|
11
|
+
* ── The two import rules ─────────────────────────────────────────────────
|
|
12
|
+
*
|
|
13
|
+
* They look contradictory and are not (F-005):
|
|
14
|
+
*
|
|
15
|
+
* - A **filesystem import** — relative or absolute — must stay inside the
|
|
16
|
+
* config tree. `entry`, every import it reaches, and every symlink they
|
|
17
|
+
* traverse are realpath-resolved and checked against the tree root, so a
|
|
18
|
+
* push can never read a file off a developer's disk that the tree does not
|
|
19
|
+
* contain.
|
|
20
|
+
* - A **bare package specifier** is exempt. It resolves through Node into an
|
|
21
|
+
* ancestor `node_modules`, which is outside every config tree by
|
|
22
|
+
* construction; esbuild inlines it into the bundle, and it is never
|
|
23
|
+
* captured as an authored source (so `config pull` never writes
|
|
24
|
+
* `node_modules` content back).
|
|
25
|
+
*
|
|
26
|
+
* The exemption follows the specifier, not the path a file happens to sit at.
|
|
27
|
+
* A resolver plugin records the files a BARE specifier reached (and the files
|
|
28
|
+
* those reach in turn), so `import "../../node_modules/private/index.js"` — a
|
|
29
|
+
* relative filesystem import that merely lands in a `node_modules` directory —
|
|
30
|
+
* is still an escape and still refused. Deciding by path would have let that
|
|
31
|
+
* one specifier read any file on the disk and upload it.
|
|
32
|
+
*
|
|
33
|
+
* `primitive-functions` is the one bare specifier left EXTERNAL: the loader
|
|
34
|
+
* (#3180) supplies it at invoke time, so baking a copy into every bundle would
|
|
35
|
+
* pin the SDK version to whenever the function was last pushed.
|
|
36
|
+
*
|
|
37
|
+
* ── The retired specifier ────────────────────────────────────────────────
|
|
38
|
+
*
|
|
39
|
+
* That module was called `primitive-sdk` until #3209. This file is the one
|
|
40
|
+
* place in the repo that still writes the old name on purpose: without a
|
|
41
|
+
* detector, an author who copied an older example gets esbuild's generic
|
|
42
|
+
* `Could not resolve "primitive-sdk"`, which reads as a missing dependency
|
|
43
|
+
* rather than a rename. `RETIRED_SDK_MODULE` below is that detector, and
|
|
44
|
+
* `cli/tests/unit/retired-sdk-name-guard-3209.test.ts` allowlists exactly this
|
|
45
|
+
* site while proving the name appears nowhere else.
|
|
46
|
+
*
|
|
47
|
+
* The refusal is made TWICE, because one mechanism cannot see both halves:
|
|
48
|
+
*
|
|
49
|
+
* - the resolver plugin catches a runtime import, which is the one that
|
|
50
|
+
* would otherwise reach the loader and fail there;
|
|
51
|
+
* - a scan of the authored source catches the TYPE-ONLY spellings —
|
|
52
|
+
* `import type … from`, `export type … from`, and a plain named import
|
|
53
|
+
* used only in type position. TypeScript erases all three, and esbuild
|
|
54
|
+
* erases them before any resolver callback runs, so the plugin never sees
|
|
55
|
+
* a specifier to compare. Those imports build and push silently, leaving
|
|
56
|
+
* the stored source teaching an import that no longer exists.
|
|
57
|
+
*
|
|
58
|
+
* The scan is anchored at the start of a line so that prose about the retired
|
|
59
|
+
* name — a `//` comment, a `*` doc-comment line, a string holding an example —
|
|
60
|
+
* does not refuse a push. Missing an import someone hid mid-line is the safe
|
|
61
|
+
* direction to be wrong in; refusing a valid push is not.
|
|
62
|
+
*
|
|
63
|
+
* ── The canonical envelope encoding ──────────────────────────────────────
|
|
64
|
+
*
|
|
65
|
+
* `canonicalFunctionEnvelopeBytes` reproduces `canonicalEnvelopeBytes` in
|
|
66
|
+
* `src/services/function-bundle-storage.ts` byte for byte. The server hashes
|
|
67
|
+
* the envelope to decide whether a push is a no-op; the CLI hashes it to decide
|
|
68
|
+
* whether to make the call at all, and the two answers have to agree or a push
|
|
69
|
+
* the CLI called unchanged lands as a new version (or worse, the reverse).
|
|
70
|
+
* `cli/tests/unit/function-bundle-3179.test.ts` pins them against each other.
|
|
71
|
+
*/
|
|
72
|
+
import * as esbuild from "esbuild";
|
|
73
|
+
import { createHash } from "crypto";
|
|
74
|
+
import { existsSync, readFileSync, realpathSync } from "fs";
|
|
75
|
+
import { isAbsolute, relative, resolve, sep } from "path";
|
|
76
|
+
/** The module the loader supplies; never bundled. */
|
|
77
|
+
export const PRIMITIVE_FUNCTIONS_MODULE = "primitive-functions";
|
|
78
|
+
/** What that module was called before #3209. Refused at push, by name. */
|
|
79
|
+
export const RETIRED_SDK_MODULE = "primitive-sdk";
|
|
80
|
+
/** The refusal both detectors report, so an author reads one sentence. */
|
|
81
|
+
const retiredModuleRefusal = () => `the '${RETIRED_SDK_MODULE}' module was renamed: import from ` +
|
|
82
|
+
`'${PRIMITIVE_FUNCTIONS_MODULE}' instead`;
|
|
83
|
+
/**
|
|
84
|
+
* Import and export forms naming the retired module, in the type-only
|
|
85
|
+
* spellings esbuild erases before the resolver plugin can see them (see the
|
|
86
|
+
* module note). Anchored at the start of a line, and the specifier must be the
|
|
87
|
+
* WHOLE quoted string, so `primitive-sdk-utils` and `./primitive-sdk.js` are
|
|
88
|
+
* untouched — the same exact match the plugin makes.
|
|
89
|
+
*/
|
|
90
|
+
const RETIRED_IMPORT_FORMS = [
|
|
91
|
+
// `import type { X } from "…"`, `export type { X } from "…"`, `export * from
|
|
92
|
+
// "…"`, and every value spelling in between, on one line.
|
|
93
|
+
new RegExp(`^[ \\t]*(?:import|export)[ \\t\\w*{},$]*[ \\t]from[ \\t]*(['"])${RETIRED_SDK_MODULE}\\1`, "m"),
|
|
94
|
+
// The tail of a multi-line named list: `} from "…"`.
|
|
95
|
+
new RegExp(`^[ \\t]*\\}[ \\t]*from[ \\t]*(['"])${RETIRED_SDK_MODULE}\\1`, "m"),
|
|
96
|
+
// A bare side-effect import. The plugin catches this one too; it costs
|
|
97
|
+
// nothing to be sure the scan agrees with it.
|
|
98
|
+
new RegExp(`^[ \\t]*import[ \\t]*(['"])${RETIRED_SDK_MODULE}\\1`, "m"),
|
|
99
|
+
];
|
|
100
|
+
/** Whether an authored source imports the retired module in any spelling. */
|
|
101
|
+
export function importsRetiredModule(source) {
|
|
102
|
+
return RETIRED_IMPORT_FORMS.some((pattern) => pattern.test(source));
|
|
103
|
+
}
|
|
104
|
+
/** Matches the server's `FUNCTION_ENVELOPE_SCHEMA_VERSION`. */
|
|
105
|
+
/**
|
|
106
|
+
* 2 since #3187: the envelope carries the collected query MANIFEST.
|
|
107
|
+
*
|
|
108
|
+
* Bumped rather than added quietly, because the encoding the hash is taken
|
|
109
|
+
* over changed: the manifest is part of config-version identity (D3187-SO-005)
|
|
110
|
+
* precisely so a manifest change makes a new version and a collector fix can
|
|
111
|
+
* reach a tree that was pushed before it.
|
|
112
|
+
*/
|
|
113
|
+
export const FUNCTION_ENVELOPE_SCHEMA_VERSION = 2;
|
|
114
|
+
/** A push that cannot proceed: a missing entry, a build error, or an escape. */
|
|
115
|
+
export class FunctionBuildError extends Error {
|
|
116
|
+
constructor(message) {
|
|
117
|
+
super(message);
|
|
118
|
+
this.name = "FunctionBuildError";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The canonical encoding both sides hash. Fixed key order, sources sorted by
|
|
123
|
+
* path — see the module note; this must stay identical to the server's.
|
|
124
|
+
*/
|
|
125
|
+
export function canonicalFunctionEnvelopeBytes(envelope) {
|
|
126
|
+
const canonical = {
|
|
127
|
+
schemaVersion: envelope.schemaVersion,
|
|
128
|
+
entry: envelope.entry,
|
|
129
|
+
toml: envelope.toml,
|
|
130
|
+
sources: [...envelope.sources]
|
|
131
|
+
.map((s) => ({ path: s.path, content: s.content }))
|
|
132
|
+
.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0)),
|
|
133
|
+
bundle: envelope.bundle,
|
|
134
|
+
// #3187 — inside the hash, so a manifest change is a new version.
|
|
135
|
+
// `null` rather than absent when there is none, so the encoding of a
|
|
136
|
+
// manifest-less push is stable rather than depending on a missing key.
|
|
137
|
+
manifest: envelope.manifest ?? null,
|
|
138
|
+
// #3455 — the twin of the server's rule: the key is emitted ONLY when
|
|
139
|
+
// there is a schema, so a tree with no `models/models.toml` builds the
|
|
140
|
+
// same bytes it built before this change and its no-op detection is
|
|
141
|
+
// intact. `undefined` would be dropped by `JSON.stringify` anyway; the
|
|
142
|
+
// spread says the rule rather than relying on that.
|
|
143
|
+
...(typeof envelope.documentSchema === "string" && envelope.documentSchema
|
|
144
|
+
? { documentSchema: envelope.documentSchema }
|
|
145
|
+
: {}),
|
|
146
|
+
};
|
|
147
|
+
return new TextEncoder().encode(JSON.stringify(canonical));
|
|
148
|
+
}
|
|
149
|
+
export function functionEnvelopeHash(envelope) {
|
|
150
|
+
return createHash("sha256")
|
|
151
|
+
.update(Buffer.from(canonicalFunctionEnvelopeBytes(envelope)))
|
|
152
|
+
.digest("hex");
|
|
153
|
+
}
|
|
154
|
+
/** POSIX spelling, so a Windows push stores the same paths a macOS one does. */
|
|
155
|
+
const toPosix = (value) => value.split(sep).join("/");
|
|
156
|
+
/** Whether a tree-relative path names a `node_modules` file. */
|
|
157
|
+
export function isDependencyPath(path) {
|
|
158
|
+
return path.split("/").includes("node_modules");
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* `null` when `candidate` is inside `root`, else the tree-relative-ish spelling
|
|
162
|
+
* to name in the refusal. Lexical only — the caller realpaths first.
|
|
163
|
+
*/
|
|
164
|
+
function outsideRoot(root, candidate) {
|
|
165
|
+
const rel = relative(root, candidate);
|
|
166
|
+
if (rel === "" || (!rel.startsWith("..") && !isAbsolute(rel)))
|
|
167
|
+
return null;
|
|
168
|
+
return toPosix(rel);
|
|
169
|
+
}
|
|
170
|
+
function escapeRefusal(what, path) {
|
|
171
|
+
return new FunctionBuildError(`${what} '${path}' resolves outside the config tree root. ` +
|
|
172
|
+
"Filesystem imports must stay inside the config tree; npm packages are " +
|
|
173
|
+
"imported by name and inlined into the bundle.");
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Build one function's bundle and collect its authored sources.
|
|
177
|
+
*
|
|
178
|
+
* Throws `FunctionBuildError` — never a raw esbuild error — so `config push`
|
|
179
|
+
* has one thing to report and nothing is pushed for that function.
|
|
180
|
+
*/
|
|
181
|
+
export async function buildFunctionBundle(options) {
|
|
182
|
+
const { configDir, entry, functionKey } = options;
|
|
183
|
+
const treeRoot = realpathSync(resolve(configDir));
|
|
184
|
+
// 1. The entry, lexically. An escaping entry is refused as an escape even
|
|
185
|
+
// when the file it names does not exist — "no such file" would be a
|
|
186
|
+
// misleading answer to `entry = "../../etc/passwd"`.
|
|
187
|
+
const entryAbs = resolve(treeRoot, entry);
|
|
188
|
+
const entryEscape = outsideRoot(treeRoot, entryAbs);
|
|
189
|
+
if (entryEscape !== null)
|
|
190
|
+
throw escapeRefusal("entry", toPosix(entry));
|
|
191
|
+
if (!existsSync(entryAbs)) {
|
|
192
|
+
throw new FunctionBuildError(`function '${functionKey}': entry file '${toPosix(entry)}' does not exist`);
|
|
193
|
+
}
|
|
194
|
+
// 2. …and after symlinks.
|
|
195
|
+
const entryReal = realpathSync(entryAbs);
|
|
196
|
+
if (outsideRoot(treeRoot, entryReal) !== null) {
|
|
197
|
+
throw escapeRefusal("entry", toPosix(entry));
|
|
198
|
+
}
|
|
199
|
+
const entryRelative = toPosix(relative(treeRoot, entryReal));
|
|
200
|
+
// Which files a BARE specifier reached. Membership — not the presence of a
|
|
201
|
+
// `node_modules` segment in the path — is what exempts a file from the tree
|
|
202
|
+
// boundary, so a relative or absolute import can never buy the exemption by
|
|
203
|
+
// pointing at a `node_modules` directory (see the module note).
|
|
204
|
+
const dependencyFiles = new Set();
|
|
205
|
+
const rememberDependency = (path) => {
|
|
206
|
+
if (!path)
|
|
207
|
+
return;
|
|
208
|
+
dependencyFiles.add(path);
|
|
209
|
+
try {
|
|
210
|
+
dependencyFiles.add(realpathSync(path));
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
/* a virtual or already-resolved path; the raw spelling is enough */
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const isDependencyFile = (path) => {
|
|
217
|
+
if (dependencyFiles.has(path))
|
|
218
|
+
return true;
|
|
219
|
+
try {
|
|
220
|
+
return dependencyFiles.has(realpathSync(path));
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const importBoundaryPlugin = {
|
|
227
|
+
name: "primitive-function-import-boundary",
|
|
228
|
+
setup(build) {
|
|
229
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
230
|
+
// The nested `build.resolve` below re-enters this callback; the marker
|
|
231
|
+
// is what stops it recursing forever.
|
|
232
|
+
if (args.pluginData?.primitiveBoundaryResolved)
|
|
233
|
+
return null;
|
|
234
|
+
if (args.kind === "entry-point")
|
|
235
|
+
return null;
|
|
236
|
+
// The retired specifier, refused before esbuild can report it as a
|
|
237
|
+
// missing package (#3209). An EXACT match only: `primitive-sdk-utils`
|
|
238
|
+
// is a different package and `./primitive-sdk.ts` is a tree-local file,
|
|
239
|
+
// and both still resolve normally.
|
|
240
|
+
if (args.path === RETIRED_SDK_MODULE) {
|
|
241
|
+
return { errors: [{ text: retiredModuleRefusal() }] };
|
|
242
|
+
}
|
|
243
|
+
const bare = !args.path.startsWith(".") && !isAbsolute(args.path);
|
|
244
|
+
// A dependency's own relative imports are dependency files too — the
|
|
245
|
+
// exemption is inherited down the package's internal graph.
|
|
246
|
+
const fromDependency = !!args.importer && isDependencyFile(args.importer);
|
|
247
|
+
if (!bare && !fromDependency)
|
|
248
|
+
return null;
|
|
249
|
+
const resolved = await build.resolve(args.path, {
|
|
250
|
+
importer: args.importer,
|
|
251
|
+
namespace: args.namespace,
|
|
252
|
+
resolveDir: args.resolveDir,
|
|
253
|
+
kind: args.kind,
|
|
254
|
+
pluginData: { primitiveBoundaryResolved: true },
|
|
255
|
+
});
|
|
256
|
+
// Let esbuild resolve (and report) it the way it would have; nothing
|
|
257
|
+
// was recorded, so an unresolvable import stays esbuild's error.
|
|
258
|
+
if (resolved.errors.length > 0)
|
|
259
|
+
return null;
|
|
260
|
+
if (!resolved.external && resolved.path) {
|
|
261
|
+
rememberDependency(resolved.path);
|
|
262
|
+
}
|
|
263
|
+
return resolved;
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
let result;
|
|
268
|
+
try {
|
|
269
|
+
result = await esbuild.build({
|
|
270
|
+
entryPoints: [entryRelative],
|
|
271
|
+
absWorkingDir: treeRoot,
|
|
272
|
+
bundle: true,
|
|
273
|
+
write: false,
|
|
274
|
+
metafile: true,
|
|
275
|
+
format: "esm",
|
|
276
|
+
platform: "neutral",
|
|
277
|
+
target: "es2022",
|
|
278
|
+
// The loader supplies it; see the module note.
|
|
279
|
+
external: [PRIMITIVE_FUNCTIONS_MODULE],
|
|
280
|
+
plugins: [importBoundaryPlugin],
|
|
281
|
+
logLevel: "silent",
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
const messages = Array.isArray(error?.errors)
|
|
286
|
+
? error.errors.map((e) => {
|
|
287
|
+
const where = e?.location?.file
|
|
288
|
+
? toPosix(String(e.location.file))
|
|
289
|
+
: toPosix(entry);
|
|
290
|
+
const line = e?.location?.line ? `:${e.location.line}` : "";
|
|
291
|
+
return ` ${where}${line}: ${e?.text ?? "build error"}`;
|
|
292
|
+
})
|
|
293
|
+
: [` ${toPosix(entry)}: ${error?.message ?? String(error)}`];
|
|
294
|
+
throw new FunctionBuildError(`function '${functionKey}' failed to build:\n${messages.join("\n")}`);
|
|
295
|
+
}
|
|
296
|
+
const output = result.outputFiles?.[0];
|
|
297
|
+
if (!output) {
|
|
298
|
+
throw new FunctionBuildError(`function '${functionKey}': the build produced no output for '${toPosix(entry)}'`);
|
|
299
|
+
}
|
|
300
|
+
const bundle = Buffer.from(output.contents);
|
|
301
|
+
// 3. Every file the build actually read, from the metafile — the honest list,
|
|
302
|
+
// rather than a re-parse of the imports. A file a BARE specifier reached is
|
|
303
|
+
// an inlined dependency and is dropped; every other input is a filesystem
|
|
304
|
+
// import, and one outside the tree is an escape esbuild followed that the
|
|
305
|
+
// push refuses.
|
|
306
|
+
const sources = [];
|
|
307
|
+
for (const input of Object.keys(result.metafile?.inputs ?? {})) {
|
|
308
|
+
const path = toPosix(input);
|
|
309
|
+
const absolute = resolve(treeRoot, input);
|
|
310
|
+
if (isDependencyFile(absolute))
|
|
311
|
+
continue;
|
|
312
|
+
if (path.startsWith("..") || isAbsolute(input)) {
|
|
313
|
+
throw escapeRefusal("import", path);
|
|
314
|
+
}
|
|
315
|
+
if (outsideRoot(treeRoot, realpathSync(absolute)) !== null) {
|
|
316
|
+
throw escapeRefusal("import", path);
|
|
317
|
+
}
|
|
318
|
+
// In-tree `node_modules` reached by a filesystem import: inside the
|
|
319
|
+
// boundary, so it builds — but `config pull` refuses to write a stored
|
|
320
|
+
// `node_modules` path, so capturing it would promise a round trip that
|
|
321
|
+
// cannot be kept.
|
|
322
|
+
if (isDependencyPath(path))
|
|
323
|
+
continue;
|
|
324
|
+
const content = readFileSync(absolute);
|
|
325
|
+
// The type-only half of the retired-specifier refusal (see the module
|
|
326
|
+
// note): esbuild erased these imports before the plugin could see them,
|
|
327
|
+
// so the build succeeded and the source would have been stored as pushed.
|
|
328
|
+
if (importsRetiredModule(content.toString("utf-8"))) {
|
|
329
|
+
throw new FunctionBuildError(`function '${functionKey}' failed to build:\n ${path}: ${retiredModuleRefusal()}`);
|
|
330
|
+
}
|
|
331
|
+
sources.push({ path, content });
|
|
332
|
+
}
|
|
333
|
+
sources.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
334
|
+
return {
|
|
335
|
+
entry: entryRelative,
|
|
336
|
+
bundle,
|
|
337
|
+
contentHash: createHash("sha256").update(bundle).digest("hex"),
|
|
338
|
+
sources,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=function-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-bundle.js","sourceRoot":"","sources":["../../../src/lib/function-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collecting a function's query manifest at push time (#3187, project
|
|
3
|
+
* `server-functions` phase 5).
|
|
4
|
+
*
|
|
5
|
+
* ── Why the tree has to RUN ──────────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* `defineQuery(name, { models, params, cache, run })` is a registration
|
|
8
|
+
* helper, and registrations are ordinary code: a name can be computed, a
|
|
9
|
+
* models list can come from a constant another file exports, a whole set can
|
|
10
|
+
* be registered in a loop. Static extraction would see none of that. So the
|
|
11
|
+
* manifest is collected by BUILDING the tree a second time with
|
|
12
|
+
* `primitive-functions` aliased to a recording stub and executing the result.
|
|
13
|
+
*
|
|
14
|
+
* ── Why it runs somewhere else ───────────────────────────────────────────
|
|
15
|
+
*
|
|
16
|
+
* D3187-SO-006. A function bundle inlines its tree-local and npm imports, so
|
|
17
|
+
* "execute the bundle" means "run arbitrary module scope" — with, if it ran
|
|
18
|
+
* inside the CLI, the developer's environment, credentials, filesystem and
|
|
19
|
+
* network. That is a large step up from what `config push` did before, which
|
|
20
|
+
* was to type-erase and bundle the same code without running it.
|
|
21
|
+
*
|
|
22
|
+
* So collection runs in a spawned child `node` with:
|
|
23
|
+
*
|
|
24
|
+
* - a SCRUBBED environment: an explicit minimal pass-through, so a token in
|
|
25
|
+
* the developer's shell is not readable by a project's module scope;
|
|
26
|
+
* - the config tree as the working directory;
|
|
27
|
+
* - a hard timeout, killed with `SIGKILL`, so a loop in a tree is a named
|
|
28
|
+
* refusal rather than a hung push;
|
|
29
|
+
* - its result read back over a structured pipe (a sentinel-framed line on
|
|
30
|
+
* stdout), so a tree that prints is not mistaken for a tree that reported.
|
|
31
|
+
*
|
|
32
|
+
* What remains is the trust a developer already extends to their own tree by
|
|
33
|
+
* running its build: this is npm-postinstall-equivalent, and the docs say so.
|
|
34
|
+
* Full network denial was considered and not taken (Node offers no reliable
|
|
35
|
+
* in-process cutoff), and so was static extraction (it cannot see computed
|
|
36
|
+
* registrations).
|
|
37
|
+
*
|
|
38
|
+
* ── What the manifest is, and is not ─────────────────────────────────────
|
|
39
|
+
*
|
|
40
|
+
* Documentation. Since #3279 function code acts as the system, so the
|
|
41
|
+
* manifest authorizes nothing anywhere: its one job is telling an operator
|
|
42
|
+
* what a version registered and what it TOUCHES — the models its code names
|
|
43
|
+
* and the families it reaches — through `primitive functions get`. That
|
|
44
|
+
* second half (schema version 2) comes from a STATIC SCAN of the built
|
|
45
|
+
* bundle: the direct records API names a model in a literal request argument
|
|
46
|
+
* with neither a registration nor `.model()` (D3279-006), so the run above
|
|
47
|
+
* cannot see it and the text can. A name the scan cannot resolve — a computed
|
|
48
|
+
* `modelName`, a `.model(variable)` — is marked `dynamicModels` rather than
|
|
49
|
+
* dropped, which is the difference between "names none" and "names these,
|
|
50
|
+
* and possibly more".
|
|
51
|
+
*/
|
|
52
|
+
/** The manifest encoding, versioned with the envelope that carries it. */
|
|
53
|
+
export declare const FUNCTION_MANIFEST_SCHEMA_VERSION = 2;
|
|
54
|
+
/** How long a tree's module scope may run before collection gives up. */
|
|
55
|
+
export declare const COLLECT_TIMEOUT_MS = 20000;
|
|
56
|
+
/** A push that cannot proceed because its manifest could not be collected. */
|
|
57
|
+
export declare class FunctionCollectError extends Error {
|
|
58
|
+
constructor(message: string);
|
|
59
|
+
}
|
|
60
|
+
export interface CollectedQuery {
|
|
61
|
+
name: string;
|
|
62
|
+
/** `query` or `mutation` — which helper registered it. */
|
|
63
|
+
kind: "query" | "mutation";
|
|
64
|
+
/** The models the author declared it touches. */
|
|
65
|
+
models: string[];
|
|
66
|
+
/** Declared parameters, by name. `$caller` params are marked here. */
|
|
67
|
+
params: Record<string, {
|
|
68
|
+
type?: string;
|
|
69
|
+
caller?: boolean;
|
|
70
|
+
default?: unknown;
|
|
71
|
+
}>;
|
|
72
|
+
/** The declared cache policy, or null when caching is off. */
|
|
73
|
+
cache: {
|
|
74
|
+
ttlMs: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/** True when every declared parameter binding is `$caller`-scoped. */
|
|
77
|
+
callerScoped: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface FunctionManifest {
|
|
80
|
+
schemaVersion: number;
|
|
81
|
+
queries: CollectedQuery[];
|
|
82
|
+
/** Every model the bundle names, deduplicated and sorted (#3279). */
|
|
83
|
+
models: string[];
|
|
84
|
+
/** Every `ctx.api.<family>` and ctx-helper family the bundle reaches. */
|
|
85
|
+
families: string[];
|
|
86
|
+
/** A model name the scan could not resolve; "and possibly more". */
|
|
87
|
+
dynamicModels: boolean;
|
|
88
|
+
}
|
|
89
|
+
export declare function scanBundleForManifest(bundle: string): {
|
|
90
|
+
models: string[];
|
|
91
|
+
families: string[];
|
|
92
|
+
dynamicModels: boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The recording stub the collect build substitutes for
|
|
96
|
+
* `primitive-functions`.
|
|
97
|
+
*
|
|
98
|
+
* It records what was registered and does nothing else: `defineFunction` and
|
|
99
|
+
* every other export are inert, so a module that calls one at import time
|
|
100
|
+
* neither fails nor has an effect.
|
|
101
|
+
*/
|
|
102
|
+
export declare const COLLECT_STUB_SOURCE = "\nconst registry = (globalThis.__PRIMITIVE_COLLECT_REGISTRY__ ||= []);\n\n// The default-coercion rule the SDK applies at registration (#3281,\n// D3281-SO-005), spelled here too so a default the declared type cannot\n// coerce is refused at PUSH \u2014 this stub is what push runs \u2014 rather than at\n// the first invocation. The vendored grammar (`coerceParamDefault` in\n// generated-config-surfaces.ts) is the same rule and re-checks the manifest.\nconst SCALAR_TYPES = [\"string\", \"number\", \"boolean\", \"any\"];\nfunction coerceScalar(type, value) {\n if (type === \"number\") {\n const n = typeof value === \"number\" ? value : Number(value);\n if (typeof value === \"boolean\" || value === null || value === \"\" || !Number.isFinite(n)) {\n return { ok: false, reason: \"must be a number\" };\n }\n return { ok: true, value: n };\n }\n if (type === \"boolean\") {\n if (typeof value === \"boolean\") return { ok: true, value };\n if (value === \"true\") return { ok: true, value: true };\n if (value === \"false\") return { ok: true, value: false };\n return { ok: false, reason: \"must be a boolean\" };\n }\n if (type === \"string\") {\n if (typeof value !== \"string\") return { ok: false, reason: \"must be a string\" };\n return { ok: true, value };\n }\n return { ok: true, value };\n}\nfunction coerceDefault(spec, value) {\n if (spec.type === \"array\") {\n if (!Array.isArray(value)) return { ok: false, reason: \"must be an array\" };\n const itemType = spec.items && spec.items.type ? String(spec.items.type) : \"any\";\n const out = [];\n for (const element of value) {\n const coerced = coerceScalar(itemType, element);\n if (!coerced.ok) return { ok: false, reason: \"every element \" + coerced.reason };\n out.push(coerced.value);\n }\n return { ok: true, value: out };\n }\n return coerceScalar(spec.type === undefined ? \"any\" : String(spec.type), value);\n}\n\nfunction record(kind, name, config) {\n const c = config || {};\n const params = {};\n for (const [key, value] of Object.entries(c.params || {})) {\n const spec = value && typeof value === \"object\" ? value : { type: String(value) };\n const entry = {};\n const fail = (message) => {\n throw new Error(\"'\" + name + \"': parameter '\" + key + \"' \" + message);\n };\n if (spec.type !== undefined) entry.type = String(spec.type);\n if (entry.type === \"array\") {\n if (spec.items !== undefined && spec.items !== null) {\n const itemType =\n spec.items && typeof spec.items === \"object\" ? String(spec.items.type ?? \"\") : \"\";\n if (!SCALAR_TYPES.includes(itemType)) {\n fail(\"declares an `items` type outside \" + SCALAR_TYPES.join(\", \") + \".\");\n }\n entry.items = { type: itemType };\n }\n if (spec.caller === true) fail(\"is an array bound to $caller; `caller` is a scalar binding.\");\n }\n if (spec.default !== undefined) {\n const coerced = coerceDefault(entry, spec.default);\n if (!coerced.ok) fail(\"has a default that \" + coerced.reason + \".\");\n entry.default = coerced.value;\n }\n if (spec.caller === true || spec === \"$caller\" || spec.type === \"$caller\") {\n entry.caller = true;\n }\n params[String(key)] = entry;\n }\n const declaredCaller = Object.values(params).some((p) => p.caller === true);\n registry.push({\n kind,\n name: String(name),\n models: Array.isArray(c.models) ? c.models.map(String) : [],\n params,\n cache:\n c.cache && typeof c.cache === \"object\" && Number(c.cache.ttlMs) > 0\n ? { ttlMs: Number(c.cache.ttlMs) }\n : null,\n callerScoped: declaredCaller,\n });\n return async () => {\n throw new Error(\n \"'\" + name + \"' was called during manifest collection; a registration's \" +\n \"`run` only executes inside a real invocation.\"\n );\n };\n}\n\n// The PUBLIC surface, all of it. An ESM import of a name a module does not\n// export is a build error, so a stub missing one export refuses a tree the\n// sandbox would have run \u2014 collection is mandatory, so that is a valid\n// function that cannot be pushed at all (CR3187-007). The constants carry the\n// runtime's own values so a registration computed from one collects the same\n// way it will run.\nexport const SDK_STUB_VERSION = \"collect\";\nexport const MAX_QUERY_CACHE_TTL_MS = 60000;\nexport const PMAP_DEFAULT_CONCURRENCY = 8;\nexport function defineQuery(name, config) { return record(\"query\", name, config); }\nexport function defineMutation(name, config) { return record(\"mutation\", name, config); }\nexport function defineFunction(keyOrHandler, maybeHandler) {\n // The KEYED form (#3281) returns a wrapper CARRYING its key, exactly as the\n // baked SDK's does. That is what push reads: the child resolves the callable\n // the bootstrap would select and compares THAT key to the file's\n // (D3281-SO-006). The registry entry is the child's report of what the\n // module scope did; it is not what the check consults, because a keyed\n // handler an entry merely imports for composition registers here too.\n if (typeof keyOrHandler === \"string\" || maybeHandler !== undefined) {\n registry.push({ kind: \"function\", name: String(keyOrHandler) });\n const wrapped = function (...args) {\n return maybeHandler(...args);\n };\n wrapped.functionKey = String(keyOrHandler);\n return wrapped;\n }\n return keyOrHandler;\n}\nexport function pMap(items, mapper) { return Promise.all((items || []).map(mapper)); }\nexport function ulid() { return \"00000000000000000000000000\"; }\nexport const stepPolicy = new Proxy({}, { get: () => ({}) });\n// #3482 \u2014 the runtime surface, and `assertRuntime` is INERT here on purpose.\n// Collection has no runtime: this child process exists to learn what a tree\n// registers, and there is nothing for an assertion to be about. A stub that\n// threw would refuse exactly the functions the assertion exists for \u2014 and the\n// placement the guide teaches is module scope, which collection runs.\nexport function assertRuntime() {}\nexport class FunctionRuntimeError extends Error {\n constructor(message, runtime, required) {\n super(message);\n this.name = \"FUNCTION_RUNTIME_REFUSED\";\n this.runtime = runtime;\n this.required = required;\n }\n}\nexport default {\n SDK_STUB_VERSION,\n defineFunction,\n defineQuery,\n defineMutation,\n pMap,\n ulid,\n assertRuntime,\n FunctionRuntimeError,\n};\n";
|
|
103
|
+
/**
|
|
104
|
+
* Collect one function's manifest.
|
|
105
|
+
*
|
|
106
|
+
* Throws `FunctionCollectError` for every failure — a build error, a module
|
|
107
|
+
* that throws at import, a loop that outlives the bound, or output that is not
|
|
108
|
+
* the framed result — because a push whose manifest could not be collected is
|
|
109
|
+
* refused rather than pushed without one (D3187-SO-005: the manifest is part
|
|
110
|
+
* of the envelope, so "later" would mean a different version).
|
|
111
|
+
*/
|
|
112
|
+
export declare function collectFunctionManifest(options: {
|
|
113
|
+
configDir: string;
|
|
114
|
+
entry: string;
|
|
115
|
+
functionKey: string;
|
|
116
|
+
timeoutMs?: number;
|
|
117
|
+
/**
|
|
118
|
+
* The BUILT bundle's source, for the static scan (#3279). The collect
|
|
119
|
+
* bundle below aliases the SDK to a stub and is not what the platform
|
|
120
|
+
* runs; the real bundle is, and its literals are what the scan reads.
|
|
121
|
+
*/
|
|
122
|
+
bundle?: string;
|
|
123
|
+
}): Promise<FunctionManifest>;
|