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,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asking for a snapshot and, optionally, watching the build that follows
|
|
3
|
+
* (#3666, criterion 7).
|
|
4
|
+
*
|
|
5
|
+
* The request itself is one call; what this module is for is the waiting.
|
|
6
|
+
* The build does not exist when the route answers — a seal arms the alarm and
|
|
7
|
+
* the alarm's first tick begins the build — so the id the caller holds names
|
|
8
|
+
* nothing for a moment, and a read that says "no such build" is `not yet`
|
|
9
|
+
* rather than a failure.
|
|
10
|
+
*
|
|
11
|
+
* Exit codes follow `documents ingest`, as `docs/cli-design.md` records them:
|
|
12
|
+
* 0 the build verified, 1 it failed, 124 a wait that gave up, 130 Ctrl-C.
|
|
13
|
+
* Both ways of giving up on the WATCHING are 124/130 and both say the build
|
|
14
|
+
* keeps running; only the build itself failing is 1. The word `failed`
|
|
15
|
+
* belongs to the build, so nothing this module prints about giving up uses it.
|
|
16
|
+
*/
|
|
17
|
+
const POLL_MS = 2_000;
|
|
18
|
+
/**
|
|
19
|
+
* How long CONSECUTIVE failed build reads may run before the wait gives up,
|
|
20
|
+
* and the backoff between them.
|
|
21
|
+
*
|
|
22
|
+
* #3597's lesson, one route along: a read failing says nothing about the
|
|
23
|
+
* build, and a wait that ends on the first one reports a running build as
|
|
24
|
+
* over. The bound is a wall-clock window and any successful read resets it,
|
|
25
|
+
* so an isolated blip costs nothing and only an outage that never lifts ends
|
|
26
|
+
* the watching — as 124, never 1.
|
|
27
|
+
*/
|
|
28
|
+
const READ_FAILURE_WINDOW_MS = 120_000;
|
|
29
|
+
const READ_RETRY_MS = 2_000;
|
|
30
|
+
/** The answer to a request that sealed nothing. */
|
|
31
|
+
function sealedNothing(response) {
|
|
32
|
+
return response?.sealed === false;
|
|
33
|
+
}
|
|
34
|
+
/** A read that says the build has not begun yet, rather than one that broke. */
|
|
35
|
+
function notStartedYet(error) {
|
|
36
|
+
const status = Number(error?.statusCode ?? error?.status);
|
|
37
|
+
return status === 404;
|
|
38
|
+
}
|
|
39
|
+
/** What a failed build should say, from whichever field carries the reason. */
|
|
40
|
+
function failureLine(build) {
|
|
41
|
+
const detail = build?.verification?.state === "failed" ? build.verification : build?.failure;
|
|
42
|
+
const parts = [detail?.code, detail?.reason].filter(Boolean);
|
|
43
|
+
return parts.length > 0
|
|
44
|
+
? `The snapshot build failed: ${parts.join(" — ")}`
|
|
45
|
+
: "The snapshot build failed.";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Ask for a snapshot, and watch the build if the caller asked to (#3666).
|
|
49
|
+
*/
|
|
50
|
+
export async function driveSnapshotBuild(options) {
|
|
51
|
+
const { client, documentId, wait = false, timeoutMs = null, signal, onProgress, } = options;
|
|
52
|
+
const now = options.now ?? (() => Date.now());
|
|
53
|
+
const sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
54
|
+
const response = await client.requestSnapshot(documentId);
|
|
55
|
+
// Nothing was sealed, so there is no build and nothing to watch. Not a
|
|
56
|
+
// failure: the document already has a base that describes it.
|
|
57
|
+
if (sealedNothing(response)) {
|
|
58
|
+
onProgress?.("The open epoch carried nothing, so it was not sealed and no build was started.");
|
|
59
|
+
return { exitCode: 0, response, build: null };
|
|
60
|
+
}
|
|
61
|
+
const buildId = String(response?.buildId ?? "");
|
|
62
|
+
onProgress?.(`Sealed epoch ${response?.sealedEpoch}; build ${buildId}.`);
|
|
63
|
+
if (!wait || !buildId)
|
|
64
|
+
return { exitCode: 0, response, build: null };
|
|
65
|
+
const startedAt = now();
|
|
66
|
+
const stillRunning = `The build is still running as ${buildId}; ` +
|
|
67
|
+
`follow it with \`documents snapshots get ${documentId} ${buildId}\`.`;
|
|
68
|
+
let failingSince = null;
|
|
69
|
+
for (;;) {
|
|
70
|
+
if (signal?.aborted) {
|
|
71
|
+
return { exitCode: 130, response, build: null, message: stillRunning };
|
|
72
|
+
}
|
|
73
|
+
if (timeoutMs !== null && now() - startedAt >= timeoutMs) {
|
|
74
|
+
return { exitCode: 124, response, build: null, message: stillRunning };
|
|
75
|
+
}
|
|
76
|
+
let build;
|
|
77
|
+
try {
|
|
78
|
+
build = await client.getSnapshot(documentId, buildId);
|
|
79
|
+
failingSince = null;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (notStartedYet(error)) {
|
|
83
|
+
// The alarm has not reached its first tick. Keep waiting, and do NOT
|
|
84
|
+
// count it against the read-failure window: nothing failed.
|
|
85
|
+
failingSince = null;
|
|
86
|
+
await sleep(POLL_MS);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
failingSince ??= now();
|
|
90
|
+
if (now() - failingSince >= READ_FAILURE_WINDOW_MS) {
|
|
91
|
+
return {
|
|
92
|
+
exitCode: 124,
|
|
93
|
+
response,
|
|
94
|
+
build: null,
|
|
95
|
+
message: `The build could not be read for ${Math.round(READ_FAILURE_WINDOW_MS / 1000)}s (${error?.message ?? error}). ${stillRunning}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
await sleep(READ_RETRY_MS);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const verification = build?.verification;
|
|
102
|
+
if (verification?.state === "passed") {
|
|
103
|
+
return { exitCode: 0, response, build };
|
|
104
|
+
}
|
|
105
|
+
if (verification?.state === "failed" || build?.state === "failed") {
|
|
106
|
+
return { exitCode: 1, response, build, message: failureLine(build) };
|
|
107
|
+
}
|
|
108
|
+
await sleep(POLL_MS);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=snapshot-build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-build.js","sourceRoot":"","sources":["../../../src/lib/snapshot-build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a snapshot's chunks are, and where an export puts them (#3432).
|
|
3
|
+
*
|
|
4
|
+
* A manifest entry is addressed within its build's grant by its `path`:
|
|
5
|
+
* `{model}/{n}` for a chunk the build wrote, `{epoch}-{buildId}/{model}/{n}`
|
|
6
|
+
* for one carried forward from an earlier build of the same document. A
|
|
7
|
+
* manifest written before the field existed is addressed by its key. Two
|
|
8
|
+
* entries of one manifest can share `{model}/{n}` (one own, one reused), so
|
|
9
|
+
* an export cannot write them by that pair: it RENUMBERS each model 0..n-1 in
|
|
10
|
+
* manifest order and stores a manifest whose paths and keys say so, which is
|
|
11
|
+
* the layout `documents import` and the ingest CLI read — one on-disk shape
|
|
12
|
+
* whatever the manifest reused.
|
|
13
|
+
*/
|
|
14
|
+
/** The fields of a manifest entry this module reads. */
|
|
15
|
+
export interface ManifestChunkLike {
|
|
16
|
+
key: string;
|
|
17
|
+
path?: string;
|
|
18
|
+
ordinal?: number;
|
|
19
|
+
model: string;
|
|
20
|
+
[field: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/** The fields of a manifest this module reads and rewrites. */
|
|
23
|
+
export interface ManifestLike<Chunk extends ManifestChunkLike = ManifestChunkLike> {
|
|
24
|
+
version: number;
|
|
25
|
+
epoch: number;
|
|
26
|
+
buildId: string;
|
|
27
|
+
chunks: Chunk[];
|
|
28
|
+
[field: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
/** Where one chunk is fetched from, within its build's grant. */
|
|
31
|
+
export interface ChunkAddress {
|
|
32
|
+
model: string;
|
|
33
|
+
index: number;
|
|
34
|
+
/** The download path relative to the grant: `{model}/{n}` or the sourced form. */
|
|
35
|
+
path: string;
|
|
36
|
+
source?: {
|
|
37
|
+
epoch: number;
|
|
38
|
+
buildId: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** A chunk's address: its `path` first, its key for an older manifest. */
|
|
42
|
+
export declare function chunkAddressOf(chunk: ManifestChunkLike): ChunkAddress;
|
|
43
|
+
/** One chunk of an export: where it is fetched from and where it is written. */
|
|
44
|
+
export interface ExportedChunkFile {
|
|
45
|
+
download: string;
|
|
46
|
+
file: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The manifest an export stores, and the file each entry's bytes go to.
|
|
50
|
+
*
|
|
51
|
+
* Numbering is per model in manifest order; the stored entry carries the
|
|
52
|
+
* own-build `path`, a key under the build's own prefix that agrees with it,
|
|
53
|
+
* and its resolved `ordinal`. Everything content-addressed — the digest, the
|
|
54
|
+
* counts, the range — is carried verbatim, and a manifest that reused nothing
|
|
55
|
+
* comes out exactly as it went in. The stored version is 2: on disk every
|
|
56
|
+
* chunk is the build's own.
|
|
57
|
+
*/
|
|
58
|
+
export declare function renumberManifestForExport<Chunk extends ManifestChunkLike, Manifest extends ManifestLike<Chunk>>(manifest: Manifest): {
|
|
59
|
+
manifest: Manifest;
|
|
60
|
+
files: ExportedChunkFile[];
|
|
61
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a snapshot's chunks are, and where an export puts them (#3432).
|
|
3
|
+
*
|
|
4
|
+
* A manifest entry is addressed within its build's grant by its `path`:
|
|
5
|
+
* `{model}/{n}` for a chunk the build wrote, `{epoch}-{buildId}/{model}/{n}`
|
|
6
|
+
* for one carried forward from an earlier build of the same document. A
|
|
7
|
+
* manifest written before the field existed is addressed by its key. Two
|
|
8
|
+
* entries of one manifest can share `{model}/{n}` (one own, one reused), so
|
|
9
|
+
* an export cannot write them by that pair: it RENUMBERS each model 0..n-1 in
|
|
10
|
+
* manifest order and stores a manifest whose paths and keys say so, which is
|
|
11
|
+
* the layout `documents import` and the ingest CLI read — one on-disk shape
|
|
12
|
+
* whatever the manifest reused.
|
|
13
|
+
*/
|
|
14
|
+
import { parseSnapshotChunkPath, resolveChunkOrdinal } from "js-bao";
|
|
15
|
+
/** A chunk's address: its `path` first, its key for an older manifest. */
|
|
16
|
+
export function chunkAddressOf(chunk) {
|
|
17
|
+
if (chunk.path !== undefined) {
|
|
18
|
+
const parsed = parseSnapshotChunkPath(chunk.path);
|
|
19
|
+
if (!parsed) {
|
|
20
|
+
throw new Error(`Snapshot manifest names a chunk this CLI cannot address: ${chunk.path}`);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
model: parsed.model,
|
|
24
|
+
index: parsed.index,
|
|
25
|
+
path: chunk.path,
|
|
26
|
+
...(parsed.source ? { source: parsed.source } : {}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const match = /\/([A-Za-z][A-Za-z0-9_]*)\/(\d+)\.ndjson\.gz$/.exec(String(chunk.key ?? ""));
|
|
30
|
+
if (!match) {
|
|
31
|
+
throw new Error(`Snapshot manifest names a chunk this CLI cannot address: ${chunk.key}`);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
model: match[1],
|
|
35
|
+
index: Number(match[2]),
|
|
36
|
+
path: `${match[1]}/${match[2]}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The manifest an export stores, and the file each entry's bytes go to.
|
|
41
|
+
*
|
|
42
|
+
* Numbering is per model in manifest order; the stored entry carries the
|
|
43
|
+
* own-build `path`, a key under the build's own prefix that agrees with it,
|
|
44
|
+
* and its resolved `ordinal`. Everything content-addressed — the digest, the
|
|
45
|
+
* counts, the range — is carried verbatim, and a manifest that reused nothing
|
|
46
|
+
* comes out exactly as it went in. The stored version is 2: on disk every
|
|
47
|
+
* chunk is the build's own.
|
|
48
|
+
*/
|
|
49
|
+
export function renumberManifestForExport(manifest) {
|
|
50
|
+
const perModel = new Map();
|
|
51
|
+
const files = [];
|
|
52
|
+
const chunks = manifest.chunks.map((chunk, index) => {
|
|
53
|
+
const address = chunkAddressOf(chunk);
|
|
54
|
+
const n = perModel.get(chunk.model) ?? 0;
|
|
55
|
+
perModel.set(chunk.model, n + 1);
|
|
56
|
+
files.push({ download: address.path, file: `${chunk.model}/${n}.ndjson.gz` });
|
|
57
|
+
const prefix = String(chunk.key).replace(/\/snapshots\/.*$/, "");
|
|
58
|
+
return {
|
|
59
|
+
...chunk,
|
|
60
|
+
key: `${prefix}/snapshots/${manifest.epoch}-${manifest.buildId}/${chunk.model}/${n}.ndjson.gz`,
|
|
61
|
+
path: `${chunk.model}/${n}`,
|
|
62
|
+
ordinal: resolveChunkOrdinal(chunk, index),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
manifest: { ...manifest, version: 2, chunks },
|
|
67
|
+
files,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=snapshot-manifest-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-manifest-layout.js","sourceRoot":"","sources":["../../../src/lib/snapshot-manifest-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AA6BrE,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,KAAwB;IACrD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,4DAA4D,KAAK,CAAC,IAAI,EAAE,CACzE,CAAC;QACJ,CAAC;QACD,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,+CAA+C,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,4DAA4D,KAAK,CAAC,GAAG,EAAE,CACxE,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACf,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;KAChC,CAAC;AACJ,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CAGvC,QAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,KAAK,GAAwB,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACjE,OAAO;YACL,GAAG,KAAK;YACR,GAAG,EAAE,GAAG,MAAM,cAAc,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,YAAY;YAC9F,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE;YAC3B,OAAO,EAAE,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC;SAC3C,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO;QACL,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE;QAC7C,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* destructive `config pull` overwrites local TOML state (issue #578, Phase 1).
|
|
4
4
|
*
|
|
5
5
|
* A snapshot is a full recursive copy of the live sync tree (including
|
|
6
|
-
* `.
|
|
6
|
+
* `.sync-state.json`, the content-hash baseline) into a timestamped slot
|
|
7
7
|
* under the snapshots root:
|
|
8
8
|
*
|
|
9
9
|
* <snapshotsRoot>/<YYYY-MM-DDTHH-MM-SS>/
|
|
10
|
-
* <full pre-pull copy of the sync tree, incl. .
|
|
10
|
+
* <full pre-pull copy of the sync tree, incl. .sync-state.json>
|
|
11
11
|
* .snapshot-complete # integrity marker, written LAST
|
|
12
12
|
* .audit-id # ULID cross-link (Phase 2; absent in P1)
|
|
13
13
|
*
|
|
@@ -83,14 +83,13 @@ export declare function resolveSnapshot(snapshotsRoot: string, id: string | unde
|
|
|
83
83
|
* then `syncDir` is atomically replaced, so a mid-restore crash never leaves a
|
|
84
84
|
* half-written tree.
|
|
85
85
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* the
|
|
86
|
+
* Nothing has to survive the swap. Backups live under the project's
|
|
87
|
+
* machine-local `.primitive/`, outside the committed tree entirely, so the
|
|
88
|
+
* `preserveDir` parameter this took went with `--dir` (#3154) — it existed
|
|
89
|
+
* only for the case where the snapshots root sat inside the directory being
|
|
90
|
+
* replaced.
|
|
90
91
|
*/
|
|
91
|
-
export declare function restoreSnapshot(snapshotPath: string, syncDir: string
|
|
92
|
-
preserveDir?: string;
|
|
93
|
-
}): void;
|
|
92
|
+
export declare function restoreSnapshot(snapshotPath: string, syncDir: string): void;
|
|
94
93
|
/**
|
|
95
94
|
* Prune snapshots older than `retentionDays` from `snapshotsRoot`. Only the
|
|
96
95
|
* given slot is touched (cross-slot retention is independent — each slot has
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* destructive `config pull` overwrites local TOML state (issue #578, Phase 1).
|
|
4
4
|
*
|
|
5
5
|
* A snapshot is a full recursive copy of the live sync tree (including
|
|
6
|
-
* `.
|
|
6
|
+
* `.sync-state.json`, the content-hash baseline) into a timestamped slot
|
|
7
7
|
* under the snapshots root:
|
|
8
8
|
*
|
|
9
9
|
* <snapshotsRoot>/<YYYY-MM-DDTHH-MM-SS>/
|
|
10
|
-
* <full pre-pull copy of the sync tree, incl. .
|
|
10
|
+
* <full pre-pull copy of the sync tree, incl. .sync-state.json>
|
|
11
11
|
* .snapshot-complete # integrity marker, written LAST
|
|
12
12
|
* .audit-id # ULID cross-link (Phase 2; absent in P1)
|
|
13
13
|
*
|
|
@@ -22,18 +22,8 @@
|
|
|
22
22
|
* temp dir, then the live `configDir` is atomically replaced, so a mid-restore
|
|
23
23
|
* crash never leaves a half-written tree.
|
|
24
24
|
*/
|
|
25
|
-
import { existsSync, readdirSync, statSync, writeFileSync, readFileSync, cpSync, rmSync, renameSync, mkdirSync,
|
|
26
|
-
import { join, dirname
|
|
27
|
-
/**
|
|
28
|
-
* Returns true if `child` is `parent` or lives somewhere beneath it. Used to
|
|
29
|
-
* detect the legacy `--dir` case where the snapshots root sits INSIDE the sync
|
|
30
|
-
* tree (`<userDir>/.snapshots/`) — we must not copy that subtree into the
|
|
31
|
-
* snapshot, or `cpSync` recurses into itself.
|
|
32
|
-
*/
|
|
33
|
-
function isInside(parent, child) {
|
|
34
|
-
const rel = relative(resolve(parent), resolve(child));
|
|
35
|
-
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
36
|
-
}
|
|
25
|
+
import { existsSync, readdirSync, statSync, writeFileSync, readFileSync, cpSync, rmSync, renameSync, mkdirSync, } from "fs";
|
|
26
|
+
import { join, dirname } from "path";
|
|
37
27
|
/** Marker file written LAST inside a snapshot to prove it completed. */
|
|
38
28
|
export const SNAPSHOT_COMPLETE_MARKER = ".snapshot-complete";
|
|
39
29
|
/** Cross-link to the audit entry that produced the snapshot (Phase 2). */
|
|
@@ -87,40 +77,16 @@ export function createSnapshot(syncDir, snapshotsRoot, opts = {}) {
|
|
|
87
77
|
finalDest = join(snapshotsRoot, finalId);
|
|
88
78
|
suffix += 1;
|
|
89
79
|
}
|
|
90
|
-
//
|
|
91
|
-
// tree
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
const rootIsInside = isInside(syncDir, snapshotsRoot);
|
|
96
|
-
const snapshotsRootResolved = resolve(snapshotsRoot);
|
|
97
|
-
const filter = rootIsInside
|
|
98
|
-
? (src) => !isInside(snapshotsRootResolved, src)
|
|
99
|
-
: undefined;
|
|
100
|
-
let externalStage = null;
|
|
80
|
+
// The backups root is machine-local, under `.primitive/backups/<env>/<appId>/`,
|
|
81
|
+
// and the tree it copies is the committed `primitive/<env>/`. The two are
|
|
82
|
+
// disjoint, so the copy can never recurse into itself — the staged-into-a-
|
|
83
|
+
// temp-dir fork this used to need existed only for `--dir`, whose snapshots
|
|
84
|
+
// root sat INSIDE the tree it was snapshotting (#3154).
|
|
101
85
|
try {
|
|
102
86
|
mkdirSync(snapshotsRoot, { recursive: true });
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// the parent keeps the move same-filesystem (avoids cross-device EXDEV
|
|
107
|
-
// that a tmpdir stage could hit).
|
|
108
|
-
const parent = dirname(resolve(syncDir));
|
|
109
|
-
mkdirSync(parent, { recursive: true });
|
|
110
|
-
externalStage = mkdtempSync(join(parent, ".primitive-snapshot-stage-"));
|
|
111
|
-
const stageTree = join(externalStage, "tree");
|
|
112
|
-
cpSync(syncDir, stageTree, {
|
|
113
|
-
recursive: true,
|
|
114
|
-
dereference: false,
|
|
115
|
-
...(filter ? { filter } : {}),
|
|
116
|
-
});
|
|
117
|
-
renameSync(stageTree, finalDest);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
// Full recursive copy. `dereference: false` keeps symlinks from being
|
|
121
|
-
// silently followed (edge case: symlinks inside the sync tree).
|
|
122
|
-
cpSync(syncDir, finalDest, { recursive: true, dereference: false });
|
|
123
|
-
}
|
|
87
|
+
// Full recursive copy. `dereference: false` keeps symlinks from being
|
|
88
|
+
// silently followed (edge case: symlinks inside the sync tree).
|
|
89
|
+
cpSync(syncDir, finalDest, { recursive: true, dereference: false });
|
|
124
90
|
if (opts.auditId) {
|
|
125
91
|
writeFileSync(join(finalDest, SNAPSHOT_AUDIT_ID_MARKER), opts.auditId);
|
|
126
92
|
}
|
|
@@ -138,16 +104,6 @@ export function createSnapshot(syncDir, snapshotsRoot, opts = {}) {
|
|
|
138
104
|
}
|
|
139
105
|
throw err;
|
|
140
106
|
}
|
|
141
|
-
finally {
|
|
142
|
-
if (externalStage) {
|
|
143
|
-
try {
|
|
144
|
-
rmSync(externalStage, { recursive: true, force: true });
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
// ignore
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
107
|
return { id: finalId, path: finalDest };
|
|
152
108
|
}
|
|
153
109
|
/**
|
|
@@ -246,12 +202,13 @@ export function resolveSnapshot(snapshotsRoot, id, minPrefix = 8) {
|
|
|
246
202
|
* then `syncDir` is atomically replaced, so a mid-restore crash never leaves a
|
|
247
203
|
* half-written tree.
|
|
248
204
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* the
|
|
205
|
+
* Nothing has to survive the swap. Backups live under the project's
|
|
206
|
+
* machine-local `.primitive/`, outside the committed tree entirely, so the
|
|
207
|
+
* `preserveDir` parameter this took went with `--dir` (#3154) — it existed
|
|
208
|
+
* only for the case where the snapshots root sat inside the directory being
|
|
209
|
+
* replaced.
|
|
253
210
|
*/
|
|
254
|
-
export function restoreSnapshot(snapshotPath, syncDir
|
|
211
|
+
export function restoreSnapshot(snapshotPath, syncDir) {
|
|
255
212
|
if (!existsSync(snapshotPath)) {
|
|
256
213
|
throw new Error(`Snapshot not found: ${snapshotPath}`);
|
|
257
214
|
}
|
|
@@ -263,15 +220,6 @@ export function restoreSnapshot(snapshotPath, syncDir, opts = {}) {
|
|
|
263
220
|
const unique = `${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
264
221
|
const stageDir = join(parent, `.primitive-restore-stage-${unique}`);
|
|
265
222
|
const oldDir = join(parent, `.primitive-restore-old-${unique}`);
|
|
266
|
-
// Determine whether a backups dir living inside syncDir needs preserving.
|
|
267
|
-
const preserve = opts.preserveDir &&
|
|
268
|
-
isInside(syncDir, opts.preserveDir) &&
|
|
269
|
-
!isInside(snapshotPath, opts.preserveDir) // don't preserve a dir that's part of the snapshot
|
|
270
|
-
? resolve(opts.preserveDir)
|
|
271
|
-
: null;
|
|
272
|
-
const preserveStash = preserve
|
|
273
|
-
? join(parent, `.primitive-restore-keep-${unique}`)
|
|
274
|
-
: null;
|
|
275
223
|
try {
|
|
276
224
|
// Materialize the snapshot into the staging dir.
|
|
277
225
|
cpSync(snapshotPath, stageDir, { recursive: true, dereference: false });
|
|
@@ -303,25 +251,14 @@ export function restoreSnapshot(snapshotPath, syncDir, opts = {}) {
|
|
|
303
251
|
}
|
|
304
252
|
throw err;
|
|
305
253
|
}
|
|
306
|
-
// Re-attach the preserved backups dir (Fork-4 `--dir` mode) into the
|
|
307
|
-
// freshly-restored tree, pulling it out of the displaced original.
|
|
308
|
-
if (preserve && preserveStash) {
|
|
309
|
-
const rel = relative(resolve(syncDir), preserve);
|
|
310
|
-
const fromOld = join(oldDir, rel);
|
|
311
|
-
const intoNew = join(syncDir, rel);
|
|
312
|
-
if (existsSync(fromOld) && !existsSync(intoNew)) {
|
|
313
|
-
mkdirSync(dirname(intoNew), { recursive: true });
|
|
314
|
-
renameSync(fromOld, intoNew);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
254
|
// Success — remove the displaced original.
|
|
318
255
|
if (existsSync(oldDir)) {
|
|
319
256
|
rmSync(oldDir, { recursive: true, force: true });
|
|
320
257
|
}
|
|
321
258
|
}
|
|
322
259
|
finally {
|
|
323
|
-
// Clean up any leftover staging/old
|
|
324
|
-
for (const dir of [stageDir, oldDir
|
|
260
|
+
// Clean up any leftover staging/old dirs on failure.
|
|
261
|
+
for (const dir of [stageDir, oldDir]) {
|
|
325
262
|
if (existsSync(dir)) {
|
|
326
263
|
try {
|
|
327
264
|
rmSync(dir, { recursive: true, force: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshots.js","sourceRoot":"","sources":["../../../src/lib/snapshots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,MAAM,EACN,MAAM,EACN,UAAU,EACV,SAAS,
|
|
1
|
+
{"version":3,"file":"snapshots.js","sourceRoot":"","sources":["../../../src/lib/snapshots.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The step table — one renderer, two commands.
|
|
3
|
+
*
|
|
4
|
+
* Extracted in #3348, when `functions runs steps` joined `workflows runs
|
|
5
|
+
* steps`. A durable function run's steps are the SAME rows in the same
|
|
6
|
+
* envelope, and the issue's ask is that they read "in the same shape a DSL
|
|
7
|
+
* workflow run's steps come back in": two hand-kept tables would have made that
|
|
8
|
+
* a resemblance, and this makes it the same code.
|
|
9
|
+
*
|
|
10
|
+
* `annotateStepGaps` (#1367) and `stepRunDisplayDurationMs` (#2771) moved here
|
|
11
|
+
* with it and are re-exported from `commands/workflows.ts`, which is where they
|
|
12
|
+
* were first exported for testability.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* #2771 — how long a step row has been going.
|
|
16
|
+
*
|
|
17
|
+
* A step that is still executing is persisted with status `running` and a
|
|
18
|
+
* `durationMs` of 0 (the column is required; the real value is written when the
|
|
19
|
+
* step ends). Printing that 0 hides the one number that matters while a run is
|
|
20
|
+
* in flight — how long the current step has been stuck — so a running row is
|
|
21
|
+
* measured from its `startedAt` instead. Finished rows keep their stored
|
|
22
|
+
* duration.
|
|
23
|
+
*/
|
|
24
|
+
export declare function stepRunDisplayDurationMs(step: any, now?: number): number | null;
|
|
25
|
+
/**
|
|
26
|
+
* #1367 — annotate step-run rows with the inter-step gap: the wall-clock time
|
|
27
|
+
* between the previous step's `endedAt` and this step's `startedAt`. Sorts by
|
|
28
|
+
* `startedAt` when every row has a parseable one (tie-break `stepIndex`),
|
|
29
|
+
* otherwise by `stepIndex` for the whole list — the ordering mode must be
|
|
30
|
+
* chosen once for all rows, not per pair: a per-pair timestamp-vs-index
|
|
31
|
+
* fallback is not transitive when some rows lack a timestamp (A<B by index,
|
|
32
|
+
* B<C by index, C<A by time), and a non-transitive comparator leaves
|
|
33
|
+
* Array.prototype.sort free to return an arbitrary order, computing gaps
|
|
34
|
+
* against the wrong predecessor. The first step has no predecessor, so its
|
|
35
|
+
* `gapMs` is `null`. A gap is only meaningful when both adjacent timestamps
|
|
36
|
+
* parse and the gap is positive. When the immediate predecessor lacks a valid
|
|
37
|
+
* `endedAt`, the gap is left `null` rather than measured from an older,
|
|
38
|
+
* non-adjacent step — otherwise a later step could raise a false stall
|
|
39
|
+
* warning against a step it does not actually follow.
|
|
40
|
+
*/
|
|
41
|
+
export declare function annotateStepGaps(steps: any[]): any[];
|
|
42
|
+
/** The step table both `runs steps` verbs print. */
|
|
43
|
+
export declare function renderStepRunTable(items: any[]): string;
|