@runeditrun/rer 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -2
- package/bin/rer.mjs +3 -0
- package/cli/README.md +243 -0
- package/cli/adapter.mjs +10 -0
- package/cli/ai-local.mjs +65 -0
- package/cli/archive-path.mjs +52 -0
- package/cli/archive-vite.mjs +55 -0
- package/cli/archive.mjs +8 -0
- package/cli/auth-copy.mjs +80 -0
- package/cli/bounded.mjs +70 -0
- package/cli/cache-doctor.mjs +63 -0
- package/cli/container-transfer.mjs +35 -0
- package/cli/container.mjs +62 -0
- package/cli/contract.mjs +25 -0
- package/cli/dependencies.mjs +45 -0
- package/cli/dependency-approval.mjs +33 -0
- package/cli/dependency-doctor.mjs +34 -0
- package/cli/dependency-input.mjs +43 -0
- package/cli/deploy-config.mjs +118 -0
- package/cli/deploy.mjs +37 -0
- package/cli/dev-identity.mjs +80 -0
- package/cli/errors.mjs +14 -0
- package/cli/export.mjs +42 -0
- package/cli/font-cache.mjs +29 -0
- package/cli/hosted-output.mjs +110 -0
- package/cli/independent.mjs +29 -0
- package/cli/inspect.mjs +174 -0
- package/cli/jsonc.mjs +111 -0
- package/cli/lifecycle.mjs +148 -0
- package/cli/local.mjs +100 -0
- package/cli/main.mjs +57 -0
- package/cli/managed-server.mjs +143 -0
- package/cli/node-runtime-cache.mjs +68 -0
- package/cli/node-runtime-discovery.mjs +56 -0
- package/cli/node-runtime-download.mjs +59 -0
- package/cli/node-runtime.mjs +50 -0
- package/cli/output.mjs +22 -0
- package/cli/parse.mjs +77 -0
- package/cli/port.mjs +52 -0
- package/cli/portability-worker.mjs +56 -0
- package/cli/portability.mjs +66 -0
- package/cli/preview-cache.mjs +99 -0
- package/cli/project.mjs +48 -0
- package/cli/release.mjs +24 -0
- package/cli/runtime-front-door.mjs +46 -0
- package/cli/scheduled.mjs +81 -0
- package/cli/server-activity.mjs +12 -0
- package/cli/server-proxy.mjs +93 -0
- package/cli/server-registry.mjs +177 -0
- package/cli/server-resources.mjs +22 -0
- package/cli/settings.mjs +15 -0
- package/cli/setup-answers.mjs +29 -0
- package/cli/setup-input.mjs +113 -0
- package/cli/shared.mjs +7 -0
- package/cli/transfers.mjs +33 -0
- package/cli/version.mjs +36 -0
- package/composition/git-source.mjs +111 -0
- package/edition-authoring/files.mjs +81 -0
- package/edition-authoring/manifest.mjs +65 -0
- package/global/README.md +155 -0
- package/global/checkout.mjs +72 -0
- package/global/cli/command.mjs +13 -0
- package/global/cli/install.mjs +75 -0
- package/global/cli/layout.mjs +45 -0
- package/global/cli/status.mjs +54 -0
- package/global/cli/uninstall.mjs +36 -0
- package/global/delegate.mjs +13 -0
- package/global/launch/capacity.mjs +72 -0
- package/global/launch/dev.mjs +129 -0
- package/global/launch/facts.mjs +93 -0
- package/global/launch/failure.mjs +5 -0
- package/global/launch/local-defaults.mjs +4 -0
- package/global/launch/prepare.mjs +61 -0
- package/global/launch/render.mjs +44 -0
- package/global/launch/state.mjs +97 -0
- package/global/launch/steps.mjs +81 -0
- package/global/launch/worker.mjs +43 -0
- package/global/list.mjs +59 -0
- package/global/main.mjs +53 -0
- package/global/package-info.mjs +38 -0
- package/global/registry.mjs +24 -0
- package/global/rer.mjs +29 -0
- package/global/update/archive.mjs +89 -0
- package/global/update/command.mjs +90 -0
- package/global/update/latest.mjs +6 -0
- package/global/update/notice.mjs +58 -0
- package/global/update/registry.mjs +47 -0
- package/global/version.mjs +29 -0
- package/install.sh +144 -0
- package/modules/ai/LICENSE +21 -0
- package/modules/ai/README.md +90 -0
- package/modules/ai/client.mjs +71 -0
- package/modules/ai/config.mjs +39 -0
- package/modules/ai/dev/index.d.mts +6 -0
- package/modules/ai/dev/index.mjs +64 -0
- package/modules/ai/dev/outbox.mjs +33 -0
- package/modules/ai/errors.mjs +28 -0
- package/modules/ai/fake/index.d.mts +3 -0
- package/modules/ai/fake/index.mjs +82 -0
- package/modules/ai/index.d.mts +10 -0
- package/modules/ai/index.mjs +3 -0
- package/modules/ai/package.json +6 -0
- package/modules/container/README.md +156 -0
- package/modules/container/adapters/d1.mjs +34 -0
- package/modules/container/adapters/egress.mjs +40 -0
- package/modules/container/adapters/jobs.mjs +47 -0
- package/modules/container/adapters/objects.mjs +84 -0
- package/modules/container/adapters/retained.mjs +14 -0
- package/modules/container/adapters/sqlite-error.mjs +7 -0
- package/modules/container/adapters/sqlite-worker.mjs +26 -0
- package/modules/container/assets.mjs +14 -0
- package/modules/container/bindings.mjs +1 -0
- package/modules/container/boundary.mjs +38 -0
- package/modules/container/build.mjs +65 -0
- package/modules/container/deploy-input.mjs +17 -0
- package/modules/container/entrypoint.sh +5 -0
- package/modules/container/host.mjs +43 -0
- package/modules/container/ingress.mjs +23 -0
- package/modules/container/lock.mjs +11 -0
- package/modules/container/migrations.mjs +16 -0
- package/modules/container/node-engine.mjs +39 -0
- package/modules/container/portability-schema.mjs +14 -0
- package/modules/container/remote/deploy.py +76 -0
- package/modules/container/remote/files.py +275 -0
- package/modules/container/remote/resources.py +157 -0
- package/modules/container/runner.mjs +10 -0
- package/modules/container/ssh-plan.mjs +44 -0
- package/modules/container/ssh.mjs +63 -0
- package/modules/container/transfer.mjs +27 -0
- package/modules/container/worker-engine.mjs +32 -0
- package/modules/dependencies/README.md +211 -0
- package/modules/dependencies/approval.mjs +51 -0
- package/modules/dependencies/auth.mjs +40 -0
- package/modules/dependencies/authority.mjs +14 -0
- package/modules/dependencies/crypto.mjs +13 -0
- package/modules/dependencies/index.d.mts +23 -0
- package/modules/dependencies/index.mjs +113 -0
- package/modules/dependencies/logout.mjs +42 -0
- package/modules/dependencies/native.mjs +9 -0
- package/modules/dependencies/protocol.mjs +23 -0
- package/modules/dependencies/schema/approval-attempt.sql +3 -0
- package/modules/dependencies/schema/dependencies.sql +15 -0
- package/modules/dependencies/store.mjs +19 -0
- package/modules/deploy-kit/README.md +308 -0
- package/modules/deploy-kit/artifact.mjs +47 -0
- package/modules/deploy-kit/build-modules.mjs +21 -0
- package/modules/deploy-kit/check.mjs +13 -0
- package/modules/deploy-kit/cli.mjs +50 -0
- package/modules/deploy-kit/container-config.mjs +8 -0
- package/modules/deploy-kit/default-stage.mjs +14 -0
- package/modules/deploy-kit/deploy.mjs +80 -0
- package/modules/deploy-kit/health-request.mjs +86 -0
- package/modules/deploy-kit/health.mjs +99 -0
- package/modules/deploy-kit/index.mjs +12 -0
- package/modules/deploy-kit/local-only.mjs +10 -0
- package/modules/deploy-kit/migrations.mjs +48 -0
- package/modules/deploy-kit/owner-cli.mjs +63 -0
- package/modules/deploy-kit/owner.mjs +297 -0
- package/modules/deploy-kit/prepare.mjs +62 -0
- package/modules/deploy-kit/provider.mjs +99 -0
- package/modules/deploy-kit/queue-consumer.mjs +10 -0
- package/modules/deploy-kit/receipt.mjs +16 -0
- package/modules/deploy-kit/render.mjs +47 -0
- package/modules/deploy-kit/resources.mjs +106 -0
- package/modules/deploy-kit/service-grants.mjs +25 -0
- package/modules/deploy-kit/sql-safety.mjs +94 -0
- package/modules/deploy-kit/sql-tokens.mjs +49 -0
- package/modules/deploy-kit/teardown.mjs +100 -0
- package/modules/deploy-kit/templates.mjs +31 -0
- package/modules/deploy-kit/validation.mjs +58 -0
- package/modules/deploy-kit/worker.mjs +105 -0
- package/modules/erasure/CONTRACT.md +90 -0
- package/modules/erasure/README.md +221 -0
- package/modules/erasure/audit.mjs +23 -0
- package/modules/erasure/blobs.mjs +45 -0
- package/modules/erasure/cascade.mjs +91 -0
- package/modules/erasure/completion.mjs +62 -0
- package/modules/erasure/declaration.mjs +51 -0
- package/modules/erasure/fence.mjs +19 -0
- package/modules/erasure/index.d.mts +62 -0
- package/modules/erasure/index.mjs +85 -0
- package/modules/erasure/order.mjs +56 -0
- package/modules/erasure/plan.mjs +121 -0
- package/modules/erasure/rate.mjs +57 -0
- package/modules/erasure/receipt.mjs +32 -0
- package/modules/erasure/root.mjs +21 -0
- package/modules/erasure/schema/erasure-rates.sql +5 -0
- package/modules/erasure/schema/erasure.sql +27 -0
- package/modules/erasure/scope.mjs +29 -0
- package/modules/erasure/sql.mjs +23 -0
- package/modules/erasure/verification.mjs +69 -0
- package/modules/integrations/core/CONTRACT.md +50 -0
- package/modules/integrations/core/README.md +27 -0
- package/modules/integrations/core/crypto.ts +19 -0
- package/modules/integrations/core/database.ts +21 -0
- package/modules/integrations/core/delivery.ts +97 -0
- package/modules/integrations/core/destination.ts +13 -0
- package/modules/integrations/core/index.ts +7 -0
- package/modules/integrations/core/node-transport.ts +72 -0
- package/modules/integrations/core/public-address.ts +57 -0
- package/modules/integrations/core/repository.ts +74 -0
- package/modules/integrations/core/schema.sql +36 -0
- package/modules/integrations/core/sqlite.ts +20 -0
- package/modules/integrations/core/timestamped-body-signature.ts +38 -0
- package/modules/integrations/core/tokens.ts +71 -0
- package/modules/integrations/core/types.ts +52 -0
- package/modules/integrations/core/upgrade-token-usage-context.sql +5 -0
- package/modules/integrations/core/webhook.ts +73 -0
- package/modules/job-queue/README.md +173 -0
- package/modules/job-queue/cli.mjs +64 -0
- package/modules/job-queue/command.mjs +64 -0
- package/modules/job-queue/config.mjs +48 -0
- package/modules/job-queue/identity.mjs +48 -0
- package/modules/job-queue/index.mjs +135 -0
- package/modules/job-queue/membership.mjs +30 -0
- package/modules/job-queue/module.json +10 -0
- package/modules/job-queue/policy.mjs +29 -0
- package/modules/job-queue/processes.mjs +80 -0
- package/modules/job-queue/resources.mjs +37 -0
- package/modules/job-queue/storage.mjs +64 -0
- package/modules/job-queue/supervisor.mjs +30 -0
- package/modules/job-queue/waiting.mjs +16 -0
- package/modules/mail/LICENSE +21 -0
- package/modules/mail/README.md +336 -0
- package/modules/mail/doctor.mjs +81 -0
- package/modules/mail/index.mjs +8 -0
- package/modules/mail/live-proof/README.md +113 -0
- package/modules/mail/live-proof/run.mjs +55 -0
- package/modules/mail/package.json +19 -0
- package/modules/mail/pnpm-lock.yaml +537 -0
- package/modules/mail/src/adapters/cloudflare/README.md +84 -0
- package/modules/mail/src/adapters/cloudflare/headers.mjs +63 -0
- package/modules/mail/src/adapters/cloudflare/index.mjs +47 -0
- package/modules/mail/src/adapters/cloudflare/response.mjs +99 -0
- package/modules/mail/src/adapters/messaging/README.md +92 -0
- package/modules/mail/src/adapters/messaging/contract.mjs +66 -0
- package/modules/mail/src/adapters/messaging/event-schema.mjs +28 -0
- package/modules/mail/src/adapters/messaging/index.mjs +61 -0
- package/modules/mail/src/adapters/messaging/jws.mjs +68 -0
- package/modules/mail/src/adapters/messaging/request.mjs +52 -0
- package/modules/mail/src/adapters/messaging/serialize.mjs +21 -0
- package/modules/mail/src/adapters/resend/README.md +120 -0
- package/modules/mail/src/adapters/resend/index.mjs +22 -0
- package/modules/mail/src/adapters/resend/response.mjs +54 -0
- package/modules/mail/src/adapters/resend/serialize.mjs +46 -0
- package/modules/mail/src/adapters/resend/size.mjs +99 -0
- package/modules/mail/src/adapters/sendgrid/README.md +75 -0
- package/modules/mail/src/adapters/sendgrid/index.mjs +35 -0
- package/modules/mail/src/adapters/sendgrid/serialize.mjs +104 -0
- package/modules/mail/src/core/errors.mjs +9 -0
- package/modules/mail/src/core/transport.mjs +33 -0
- package/modules/mail/src/core/validation.mjs +172 -0
- package/modules/mail/src/development/index.d.mts +37 -0
- package/modules/mail/src/development/index.mjs +35 -0
- package/modules/mail/src/development/outbox.mjs +78 -0
- package/modules/mail/src/development/schema.sql +9 -0
- package/modules/mail/src/development/viewer-html.mjs +42 -0
- package/modules/mail/src/development/viewer.mjs +65 -0
- package/modules/mail/src/doctor/README.md +107 -0
- package/modules/mail/src/doctor/common.mjs +64 -0
- package/modules/mail/src/doctor/dns.mjs +102 -0
- package/modules/mail/src/doctor/index.mjs +28 -0
- package/modules/mail/src/doctor/probe.mjs +66 -0
- package/modules/mail/src/doctor/receive.mjs +81 -0
- package/modules/mail/src/doctor/records.mjs +45 -0
- package/modules/mail/src/events/README.md +268 -0
- package/modules/mail/src/events/d1-schema.sql +25 -0
- package/modules/mail/src/events/d1-storage.mjs +76 -0
- package/modules/mail/src/events/index.mjs +3 -0
- package/modules/mail/src/events/intake.mjs +201 -0
- package/modules/mail/src/events/storage.mjs +52 -0
- package/modules/mail/src/events/verify.mjs +92 -0
- package/modules/mail/src/inbound/README.md +137 -0
- package/modules/mail/src/inbound/bytes.mjs +91 -0
- package/modules/mail/src/inbound/headers.mjs +143 -0
- package/modules/mail/src/inbound/index.mjs +29 -0
- package/modules/mail/src/inbound/mime.mjs +36 -0
- package/modules/mail/src/inbound/multipart.mjs +27 -0
- package/modules/mail/src/inbound/resend-attachment.mjs +43 -0
- package/modules/mail/src/inbound/resend.mjs +54 -0
- package/modules/mail/src/inbound/sendgrid.mjs +60 -0
- package/modules/mail/src/sender.mjs +33 -0
- package/modules/mail/src/sendgrid-email/index.d.mts +33 -0
- package/modules/mail/src/sendgrid-email/index.mjs +86 -0
- package/modules/mail/src/unsubscribe/index.mjs +142 -0
- package/modules/operator-auth/README.md +599 -0
- package/modules/operator-auth/accounts/adapter.mjs +41 -0
- package/modules/operator-auth/accounts/admin.mjs +159 -0
- package/modules/operator-auth/accounts/credentials.mjs +27 -0
- package/modules/operator-auth/accounts/editor-owner.mjs +13 -0
- package/modules/operator-auth/accounts/index.d.mts +9 -0
- package/modules/operator-auth/accounts/index.mjs +9 -0
- package/modules/operator-auth/accounts/native.d.mts +38 -0
- package/modules/operator-auth/accounts/native.mjs +171 -0
- package/modules/operator-auth/accounts/oa.mjs +90 -0
- package/modules/operator-auth/accounts/provider-control.mjs +50 -0
- package/modules/operator-auth/accounts/provider-pin.mjs +14 -0
- package/modules/operator-auth/accounts/roles.mjs +26 -0
- package/modules/operator-auth/accounts/schema/dependency-setup.sql +17 -0
- package/modules/operator-auth/accounts/schema/dev-sessions.sql +22 -0
- package/modules/operator-auth/accounts/schema/domain-rules-step-up.sql +20 -0
- package/modules/operator-auth/accounts/schema/invitation-cancellation.sql +17 -0
- package/modules/operator-auth/accounts/schema/operator-auth.sql +142 -0
- package/modules/operator-auth/accounts/schema/provider-control.sql +30 -0
- package/modules/operator-auth/accounts/schema/provider-pins.sql +6 -0
- package/modules/operator-auth/accounts/settings-page.mjs +4 -0
- package/modules/operator-auth/accounts/store.mjs +246 -0
- package/modules/operator-auth/branding.mjs +66 -0
- package/modules/operator-auth/config.mjs +35 -0
- package/modules/operator-auth/conformance/README.md +81 -0
- package/modules/operator-auth/conformance/index.d.mts +43 -0
- package/modules/operator-auth/conformance/index.mjs +300 -0
- package/modules/operator-auth/conformance/presentation.mjs +57 -0
- package/modules/operator-auth/crypto.mjs +17 -0
- package/modules/operator-auth/dev/badge.mjs +62 -0
- package/modules/operator-auth/dev/index.d.mts +14 -0
- package/modules/operator-auth/dev/index.mjs +137 -0
- package/modules/operator-auth/dev/personas.mjs +17 -0
- package/modules/operator-auth/dev/sign-in-as.d.mts +3 -0
- package/modules/operator-auth/dev/sign-in-as.mjs +25 -0
- package/modules/operator-auth/dev-admission.d.mts +4 -0
- package/modules/operator-auth/dev-admission.mjs +10 -0
- package/modules/operator-auth/dev-gate.mjs +86 -0
- package/modules/operator-auth/docs/README.md +78 -0
- package/modules/operator-auth/docs/native-accounts.md +313 -0
- package/modules/operator-auth/docs/tanstack-start.md +218 -0
- package/modules/operator-auth/docs/vite-spa.md +144 -0
- package/modules/operator-auth/errors.mjs +9 -0
- package/modules/operator-auth/http.mjs +42 -0
- package/modules/operator-auth/identity/admission.mjs +105 -0
- package/modules/operator-auth/identity/after-confirm.mjs +18 -0
- package/modules/operator-auth/identity/email-link/confirmation.mjs +14 -0
- package/modules/operator-auth/identity/email-link/index.d.mts +48 -0
- package/modules/operator-auth/identity/email-link/index.mjs +128 -0
- package/modules/operator-auth/identity/email-link/message.mjs +16 -0
- package/modules/operator-auth/identity/index.d.mts +7 -0
- package/modules/operator-auth/identity/index.mjs +5 -0
- package/modules/operator-auth/identity/oidc/README.md +171 -0
- package/modules/operator-auth/identity/oidc/client-auth.mjs +16 -0
- package/modules/operator-auth/identity/oidc/config.mjs +102 -0
- package/modules/operator-auth/identity/oidc/crypto.mjs +29 -0
- package/modules/operator-auth/identity/oidc/errors.mjs +5 -0
- package/modules/operator-auth/identity/oidc/index.d.mts +33 -0
- package/modules/operator-auth/identity/oidc/index.mjs +287 -0
- package/modules/operator-auth/identity/oidc/jwt.mjs +102 -0
- package/modules/operator-auth/identity/oidc/network.mjs +93 -0
- package/modules/operator-auth/identity/oidc/presets.mjs +26 -0
- package/modules/operator-auth/identity/oidc/schema/oidc.sql +50 -0
- package/modules/operator-auth/identity/oidc/store.mjs +68 -0
- package/modules/operator-auth/identity/principal.mjs +28 -0
- package/modules/operator-auth/index.d.mts +223 -0
- package/modules/operator-auth/index.mjs +11 -0
- package/modules/operator-auth/input.mjs +55 -0
- package/modules/operator-auth/local-cli.mjs +16 -0
- package/modules/operator-auth/page.mjs +34 -0
- package/modules/operator-auth/policy.mjs +20 -0
- package/modules/operator-auth/routes.mjs +91 -0
- package/modules/operator-auth/service.mjs +152 -0
- package/modules/operator-auth/signin/index.mjs +67 -0
- package/modules/owner-claim/README.md +137 -0
- package/modules/owner-claim/idp.mjs +40 -0
- package/modules/owner-claim/index.d.mts +27 -0
- package/modules/owner-claim/index.mjs +39 -0
- package/modules/owner-claim/page.mjs +11 -0
- package/modules/owner-claim/schema/idp.sql +4 -0
- package/modules/owner-claim/schema/owner-claim.sql +18 -0
- package/modules/owner-claim/transaction.mjs +87 -0
- package/modules/owner-claim/verify.mjs +80 -0
- package/modules/portability/README.md +444 -0
- package/modules/portability/bridge.mjs +102 -0
- package/modules/portability/catalogue.mjs +118 -0
- package/modules/portability/cli-options.mjs +38 -0
- package/modules/portability/cli.mjs +56 -0
- package/modules/portability/copies.mjs +68 -0
- package/modules/portability/dev-data.mjs +32 -0
- package/modules/portability/diff.mjs +33 -0
- package/modules/portability/export.mjs +129 -0
- package/modules/portability/files.mjs +65 -0
- package/modules/portability/format.mjs +122 -0
- package/modules/portability/generated.mjs +60 -0
- package/modules/portability/hash.mjs +79 -0
- package/modules/portability/http.mjs +42 -0
- package/modules/portability/import.mjs +185 -0
- package/modules/portability/index.d.mts +58 -0
- package/modules/portability/index.mjs +22 -0
- package/modules/portability/journal.mjs +49 -0
- package/modules/portability/legacy-files.mjs +43 -0
- package/modules/portability/legacy-safety.mjs +27 -0
- package/modules/portability/lines.mjs +36 -0
- package/modules/portability/migration-history.mjs +18 -0
- package/modules/portability/migration-statements.mjs +23 -0
- package/modules/portability/payloads.mjs +52 -0
- package/modules/portability/provider-data.mjs +25 -0
- package/modules/portability/restore-safety.mjs +30 -0
- package/modules/portability/schema/portability.sql +25 -0
- package/modules/portability/storage.mjs +49 -0
- package/modules/release/README.md +212 -0
- package/modules/release/catalogue.mjs +79 -0
- package/modules/release/export.mjs +51 -0
- package/modules/release/produce.mjs +136 -0
- package/modules/release/public-child-transport-state.cjs +29 -0
- package/modules/release/public-child.mjs +71 -0
- package/modules/release/public-git.mjs +21 -0
- package/modules/release/publication-scan.mjs +22 -0
- package/modules/release/publish-handoff.mjs +37 -0
- package/modules/release/source.mjs +71 -0
- package/modules/release/test-summary.mjs +50 -0
- package/onboarding/README.md +163 -0
- package/onboarding/activity.mjs +31 -0
- package/onboarding/adapter-auth.mjs +88 -0
- package/onboarding/adapter-hosting.mjs +35 -0
- package/onboarding/adapter-labels.mjs +13 -0
- package/onboarding/adapter-settings.mjs +129 -0
- package/onboarding/adapter.mjs +238 -0
- package/onboarding/agent-handoff.mjs +9 -0
- package/onboarding/app-processes.mjs +21 -0
- package/onboarding/archive-output.d.mts +3 -0
- package/onboarding/archive-output.mjs +54 -0
- package/onboarding/command-custody.mjs +24 -0
- package/onboarding/command-recovery.mjs +8 -0
- package/onboarding/commands.mjs +166 -0
- package/onboarding/dependency-approval.mjs +36 -0
- package/onboarding/dev-identity.mjs +23 -0
- package/onboarding/email.mjs +24 -0
- package/onboarding/failures.mjs +42 -0
- package/onboarding/input-limits.mjs +7 -0
- package/onboarding/installer-inputs.mjs +24 -0
- package/onboarding/launcher.mjs +34 -0
- package/onboarding/local/build-files.mjs +64 -0
- package/onboarding/local/build.mjs +49 -0
- package/onboarding/local/environment.mjs +30 -0
- package/onboarding/local/files.mjs +35 -0
- package/onboarding/local/operation.mjs +166 -0
- package/onboarding/local/owner.mjs +34 -0
- package/onboarding/local/process-table.mjs +114 -0
- package/onboarding/local/recovery.mjs +79 -0
- package/onboarding/local/state.mjs +31 -0
- package/onboarding/metadata.mjs +7 -0
- package/onboarding/operator-install.mjs +45 -0
- package/onboarding/operator-installer.mjs +39 -0
- package/onboarding/operator-prerequisites.mjs +27 -0
- package/onboarding/package.json +6 -0
- package/onboarding/prefill.mjs +16 -0
- package/onboarding/private-files.mjs +97 -0
- package/onboarding/private.mjs +35 -0
- package/onboarding/process-cleanup.mjs +134 -0
- package/onboarding/process-diagnostics.mjs +91 -0
- package/onboarding/process-scope.mjs +118 -0
- package/onboarding/process-table.mjs +118 -0
- package/onboarding/process-tree.mjs +36 -0
- package/onboarding/production-modules.mjs +22 -0
- package/onboarding/production-options.mjs +40 -0
- package/onboarding/production-plan.mjs +8 -0
- package/onboarding/production-runtime.mjs +30 -0
- package/onboarding/project-vite.mjs +14 -0
- package/onboarding/providers.mjs +289 -0
- package/onboarding/queue.mjs +53 -0
- package/onboarding/queued-entry.mjs +34 -0
- package/onboarding/readiness.mjs +59 -0
- package/onboarding/redaction-jwt.mjs +32 -0
- package/onboarding/redaction.mjs +298 -0
- package/onboarding/schema/SETUP.schema.json +514 -0
- package/onboarding/schema/dependencies.mjs +35 -0
- package/onboarding/schema/json-schema.mjs +202 -0
- package/onboarding/schema/setup-validation.mjs +325 -0
- package/onboarding/secrets.mjs +21 -0
- package/onboarding/server.mjs +188 -0
- package/onboarding/setup-manifest.mjs +116 -0
- package/onboarding/state.mjs +46 -0
- package/onboarding/theme-files.mjs +37 -0
- package/onboarding/theme.mjs +118 -0
- package/onboarding/ui/activity.js +98 -0
- package/onboarding/ui/address-client.mjs +33 -0
- package/onboarding/ui/app.js +377 -0
- package/onboarding/ui/index.html +1 -0
- package/onboarding/ui/model-core.mjs +127 -0
- package/onboarding/ui/model.mjs +5 -0
- package/onboarding/ui/style.css +63 -0
- package/onboarding/ui/theme.css +37 -0
- package/onboarding/ui/workspace-art.js +30 -0
- package/onboarding/wrangler-auth.mjs +43 -0
- package/operations/README.md +246 -0
- package/operations/operations.mjs +168 -0
- package/operations/project-operations.mjs +157 -0
- package/package.json +11 -4
- package/scripts/publish-check/README.md +72 -0
- package/scripts/publish-check/checksum_maps.py +52 -0
- package/scripts/publish-check/cli.py +34 -0
- package/scripts/publish-check/command_arguments.py +51 -0
- package/scripts/publish-check/command_shell_quotes.py +41 -0
- package/scripts/publish-check/command_source_quotes.py +120 -0
- package/scripts/publish-check/content_identities.py +250 -0
- package/scripts/publish-check/copy_identities.py +41 -0
- package/scripts/publish-check/der.py +61 -0
- package/scripts/publish-check/destination.py +117 -0
- package/scripts/publish-check/env_values.py +74 -0
- package/scripts/publish-check/font_licence.py +23 -0
- package/scripts/publish-check/git_history.py +115 -0
- package/scripts/publish-check/github_refs.py +217 -0
- package/scripts/publish-check/gitleaks.py +72 -0
- package/scripts/publish-check/gitleaks.toml +40 -0
- package/scripts/publish-check/history_scan.py +176 -0
- package/scripts/publish-check/hit_location.py +18 -0
- package/scripts/publish-check/hygiene_config.py +42 -0
- package/scripts/publish-check/hygiene_text.py +11 -0
- package/scripts/publish-check/identity-recipe.mjs +54 -0
- package/scripts/publish-check/json_identity.py +79 -0
- package/scripts/publish-check/license-exceptions.json +11 -0
- package/scripts/publish-check/licenses.py +49 -0
- package/scripts/publish-check/policy.py +18 -0
- package/scripts/publish-check/project_identity.py +89 -0
- package/scripts/publish-check/provenance.py +91 -0
- package/scripts/publish-check/provenance_pins.py +33 -0
- package/scripts/publish-check/public_base.py +63 -0
- package/scripts/publish-check/public_hygiene.py +80 -0
- package/scripts/publish-check/publication-config.json +12 -0
- package/scripts/publish-check/publication_config.py +34 -0
- package/scripts/publish-check/report.py +52 -0
- package/scripts/publish-check/repository_commands.py +75 -0
- package/scripts/publish-check/repository_intent.py +52 -0
- package/scripts/publish-check/reviewed.py +41 -0
- package/scripts/publish-check/source_hashes.mjs +6 -0
- package/scripts/publish-check/tree_scan.py +88 -0
- package/scripts/publish-check/trust_bundle.py +87 -0
- package/scripts/publish-check.mjs +58 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process'
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
3
|
+
import { randomUUID } from 'node:crypto'
|
|
4
|
+
import { promisify } from 'node:util'
|
|
5
|
+
import { setTimeout as delay } from 'node:timers/promises'
|
|
6
|
+
import { inspectionMs, readProcessIdentity, readProcessTable, sameBirth } from './process-table.mjs'
|
|
7
|
+
|
|
8
|
+
const execute = promisify(execFile)
|
|
9
|
+
const scopes = new WeakMap()
|
|
10
|
+
const baselines = new WeakMap()
|
|
11
|
+
const birthKey = member => `${member.pid}:${member.birth}`
|
|
12
|
+
const marker = 'RER_ONBOARDING_PROCESS_OWNER'
|
|
13
|
+
|
|
14
|
+
// An exclusive inherited token follows a child through chdir, setsid and
|
|
15
|
+
// reparenting. Shared directory, executable name and process group never grant
|
|
16
|
+
// ownership. Tokens and inspected environments stay private to this module.
|
|
17
|
+
// No process present before this store can have been started by it. This
|
|
18
|
+
// immutable exclusion avoids repeatedly reading foreign environments; it never
|
|
19
|
+
// authorizes signalling a process. Every later match still requires its token.
|
|
20
|
+
export async function createProcessBaseline() {
|
|
21
|
+
const baseline = Object.freeze({})
|
|
22
|
+
baselines.set(baseline, new Set((await readProcessTable()).map(birthKey)))
|
|
23
|
+
return baseline
|
|
24
|
+
}
|
|
25
|
+
export function createProcessScope(baseline, token = randomUUID()) {
|
|
26
|
+
const scope = Object.freeze({ token })
|
|
27
|
+
if (baseline && !baselines.has(baseline)) throw new Error('Unknown process baseline.')
|
|
28
|
+
scopes.set(scope, { excluded: baselines.get(baseline), unmarked: new Map() })
|
|
29
|
+
return scope
|
|
30
|
+
}
|
|
31
|
+
export function processScopeEnvironment(scope, environment) {
|
|
32
|
+
if (!scopes.has(scope)) throw new Error('Unknown process scope.')
|
|
33
|
+
// Nested command stores add custody without erasing their parent's marker.
|
|
34
|
+
return { ...environment, [marker]: [...new Set([...inheritedScopeTokens(process.env), ...inheritedScopeTokens(environment), scope.token])].join(',') }
|
|
35
|
+
}
|
|
36
|
+
export async function scopedProcesses(scope, table, timeout = inspectionMs, previous = []) {
|
|
37
|
+
if (!scopes.has(scope)) throw new Error('Unknown process scope.')
|
|
38
|
+
const inspectionEnd = Date.now() + timeout
|
|
39
|
+
// Inspect same-user candidates in one bounded call. A child can change cwd,
|
|
40
|
+
// detach and lose its parent between captures; the exclusive inherited marker
|
|
41
|
+
// still proves ownership. Arguments/environment never leave this function.
|
|
42
|
+
// A zombie keeps no environment to read and no descendants (they were reparented
|
|
43
|
+
// and carry the marker themselves), so it can neither prove nor hold ownership.
|
|
44
|
+
const { excluded, unmarked } = scopes.get(scope)
|
|
45
|
+
const liveKeys = new Set(table.map(birthKey))
|
|
46
|
+
for (const key of unmarked.keys()) if (!liveKeys.has(key)) unmarked.delete(key)
|
|
47
|
+
// A stable unmarked foreign process cannot inherit a new launch token without
|
|
48
|
+
// a fork. Known owners (including exec transitions) are always reinspected;
|
|
49
|
+
// their descendants are independently discovered by ancestry as well.
|
|
50
|
+
const candidates = table.filter(member => !excluded?.has(birthKey(member))
|
|
51
|
+
&& (!unmarked.has(birthKey(member)) || previous.some(saved => sameBirth(saved, member))) && !member.state?.startsWith('Z')
|
|
52
|
+
&& (member.uid === undefined || member.uid === process.getuid())
|
|
53
|
+
)
|
|
54
|
+
if (!candidates.length) return []
|
|
55
|
+
const environments = process.platform === 'linux' ? new Map() : await readEnvironments(candidates.map(member => member.pid), timeout)
|
|
56
|
+
const matches = []
|
|
57
|
+
inspectCandidate: for (const member of candidates) {
|
|
58
|
+
let environment
|
|
59
|
+
for (;;) {
|
|
60
|
+
try {
|
|
61
|
+
if (process.platform === 'linux') environment = await readFile(`/proc/${member.pid}/environ`, { encoding: 'utf8', signal: AbortSignal.timeout(Math.max(1, inspectionEnd - Date.now())) })
|
|
62
|
+
else environment = environments.get(member.pid)
|
|
63
|
+
if (environment === undefined) throw new Error('Missing process ownership metadata.')
|
|
64
|
+
break
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// Linux withholds the environment of same-user processes that opted out
|
|
67
|
+
// of inspection. Actual ancestry remains an independent custody proof.
|
|
68
|
+
if (process.platform === 'linux' && error?.code === 'EACCES') continue inspectCandidate
|
|
69
|
+
// Exit may remove environ before stat or the zombie state catches up.
|
|
70
|
+
// Reconcile the same birth inside this bounded inspection; never treat
|
|
71
|
+
// a transient read error as foreign ownership or completed cleanup.
|
|
72
|
+
const current = await readProcessIdentity(member.pid, Math.max(1, inspectionEnd - Date.now()))
|
|
73
|
+
if (!sameBirth(current, member) || current.state.startsWith('Z')) continue inspectCandidate
|
|
74
|
+
if (Date.now() < inspectionEnd && (process.platform !== 'linux' || ['ENOENT', 'ESRCH'].includes(error.code))) {
|
|
75
|
+
// The same live birth is still between images (fork/exec) or being
|
|
76
|
+
// reaped. Wait for its environment to become readable, up to the
|
|
77
|
+
// inspection deadline, instead of reading the batch listing once.
|
|
78
|
+
await delay(5)
|
|
79
|
+
if (process.platform !== 'linux') for (const [pid, text] of await readEnvironments([member.pid], Math.max(1, inspectionEnd - Date.now()))) environments.set(pid, text)
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Could not inspect ownership of process ${member.pid} (${error.code ?? 'missing'}, state ${current.state}).`)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (environment.split(/[\0\s]+/).some(value => value.startsWith(marker + '=')
|
|
86
|
+
&& value.slice(marker.length + 1).split(',').includes(scope.token))) matches.push(member)
|
|
87
|
+
else unmarked.set(birthKey(member), true)
|
|
88
|
+
}
|
|
89
|
+
// A recycled PID must not transfer a token reading to its successor. PGID may
|
|
90
|
+
// legitimately change, so follow the same birth identity across that change.
|
|
91
|
+
// The caller rechecks each match's full PID/start/command identity.
|
|
92
|
+
return matches
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// macOS exposes a process environment only through ps. One bounded call lists
|
|
96
|
+
// every candidate; a process that vanishes or is between images yields no line
|
|
97
|
+
// or an empty command, and callers wait for that same birth rather than guess.
|
|
98
|
+
async function readEnvironments(pids, timeout) {
|
|
99
|
+
let stdout
|
|
100
|
+
try {
|
|
101
|
+
({ stdout } = await execute('/bin/ps', ['eww', '-p', pids.join(','), '-o', 'pid=', '-o', 'command='], { timeout, maxBuffer: 16 * 1024 * 1024 }))
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// ps may lose a candidate while it enumerates. Keep partial private output
|
|
104
|
+
// only for that exit code; each missing identity is checked by the caller.
|
|
105
|
+
if (error.code === 1 && typeof error.stdout === 'string') stdout = error.stdout
|
|
106
|
+
else throw new Error('Could not inspect scoped process ownership.')
|
|
107
|
+
}
|
|
108
|
+
const environments = new Map()
|
|
109
|
+
for (const line of stdout.split('\n')) {
|
|
110
|
+
const match = line.match(/^\s*(\d+)\s+(.+)$/)
|
|
111
|
+
if (match) environments.set(Number(match[1]), match[2])
|
|
112
|
+
}
|
|
113
|
+
return environments
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function inheritedScopeTokens(environment) {
|
|
117
|
+
return String(environment?.[marker] ?? '').split(',').filter(value => /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(value))
|
|
118
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process'
|
|
2
|
+
import { readFile, readdir, stat } from 'node:fs/promises'
|
|
3
|
+
import { promisify } from 'node:util'
|
|
4
|
+
import { setTimeout as delay } from 'node:timers/promises'
|
|
5
|
+
|
|
6
|
+
const execute = promisify(execFile)
|
|
7
|
+
// One bounded wait for any process inspection; a loaded machine can take over a
|
|
8
|
+
// second to list processes, which must not abort an otherwise healthy cleanup.
|
|
9
|
+
export const inspectionMs = 5000
|
|
10
|
+
export const validPid = (pid) => Number.isSafeInteger(pid) && pid > 0 && pid <= 0x7fffffff
|
|
11
|
+
|
|
12
|
+
// Inspect numeric identity and the executable name, never private argv.
|
|
13
|
+
// Linux's start ticks distinguish recycled PIDs more precisely than ps lstart.
|
|
14
|
+
async function linuxProcess(pid, pgid, signal) {
|
|
15
|
+
for (;;) {
|
|
16
|
+
signal.throwIfAborted()
|
|
17
|
+
let text
|
|
18
|
+
try { text = await readFile(`/proc/${pid}/stat`, { encoding: 'utf8', signal }) } catch (error) {
|
|
19
|
+
if (error.code === 'ENOENT' || error.code === 'ESRCH') return
|
|
20
|
+
throw error
|
|
21
|
+
}
|
|
22
|
+
const group = pgid ?? Number(text.slice(text.lastIndexOf(')') + 2).trim().split(/\s+/)[2])
|
|
23
|
+
if (pgid === undefined && group === 0) return // Kernel tasks cannot belong to an owned detached group.
|
|
24
|
+
let member
|
|
25
|
+
try { member = parseLinuxProcess(pid, group, text) } catch {
|
|
26
|
+
// Procfs may finish an already-open read while its task is exiting or
|
|
27
|
+
// replacing its thread leader. An invalid snapshot never grants identity:
|
|
28
|
+
// reconcile this same PID until valid, gone, or the inspection aborts.
|
|
29
|
+
await delay(5, undefined, { signal }); continue
|
|
30
|
+
}
|
|
31
|
+
if (!member) return
|
|
32
|
+
try { return { ...member, uid: (await stat(`/proc/${pid}`)).uid } }
|
|
33
|
+
catch (error) { if (error.code === 'ENOENT' || error.code === 'ESRCH') return; throw error }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function parseLinuxProcess(pid, pgid, text) {
|
|
38
|
+
if (!validPid(pid) || !validPid(pgid) || !text.startsWith(`${pid} (`) || !text.includes(') ')) {
|
|
39
|
+
throw new Error('Invalid process identity.')
|
|
40
|
+
}
|
|
41
|
+
const fields = text.slice(text.lastIndexOf(')') + 2).trim().split(/\s+/)
|
|
42
|
+
const ppid = Number(fields[1])
|
|
43
|
+
if (Number(fields[2]) !== pgid) return
|
|
44
|
+
if (!Number.isSafeInteger(ppid) || ppid < 0 || !/^\d+$/.test(fields[19])) {
|
|
45
|
+
throw new Error('Invalid process identity.')
|
|
46
|
+
}
|
|
47
|
+
return { pid, ppid, pgid, state: fields[0], birth: fields[19], command: text.slice(text.indexOf('(') + 1, text.lastIndexOf(')')) }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function processGroup(pgid, signal) {
|
|
51
|
+
if (process.platform === 'linux') {
|
|
52
|
+
// Minimal Linux containers need not install ps. Procfs provides exact
|
|
53
|
+
// start ticks and includes zombies until their actual parent reaps them.
|
|
54
|
+
const pids = (await readdir('/proc')).filter((name) => /^\d+$/.test(name)).map(Number).filter(validPid)
|
|
55
|
+
const group = []
|
|
56
|
+
for (let offset = 0; offset < pids.length; offset += 16) {
|
|
57
|
+
signal.throwIfAborted()
|
|
58
|
+
const members = await Promise.all(pids.slice(offset, offset + 16).map((pid) => linuxProcess(pid, pgid, signal)))
|
|
59
|
+
group.push(...members.filter(Boolean))
|
|
60
|
+
}
|
|
61
|
+
return group
|
|
62
|
+
}
|
|
63
|
+
const { stdout } = await execute('/bin/ps', [
|
|
64
|
+
'-ax', '-o', 'pid=', '-o', 'ppid=', '-o', 'pgid=', '-o', 'uid=', '-o', 'stat=', '-o', 'lstart=',
|
|
65
|
+
], { env: { ...process.env, LC_ALL: 'C', TZ: 'UTC' }, signal, killSignal: 'SIGKILL', maxBuffer: 8 * 1024 * 1024 })
|
|
66
|
+
const group = []
|
|
67
|
+
for (const line of stdout.split('\n').filter((line) => line.trim())) {
|
|
68
|
+
const match = line.match(/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.{24})\s*$/)
|
|
69
|
+
if (!match) throw new Error('Could not read process identities.')
|
|
70
|
+
const [, id, parent, groupId, uid, state, birth] = match
|
|
71
|
+
const pid = Number(id)
|
|
72
|
+
const ppid = Number(parent)
|
|
73
|
+
if (pgid === undefined && (pid === 0 || Number(groupId) === 0)) continue
|
|
74
|
+
if (pgid !== undefined && Number(groupId) !== pgid) continue
|
|
75
|
+
if (!validPid(pid) || !validPid(Number(groupId)) || !Number.isSafeInteger(ppid) || ppid < 0 || !Number.isFinite(Date.parse(birth))) {
|
|
76
|
+
throw new Error('Invalid process identity.')
|
|
77
|
+
}
|
|
78
|
+
group.push({ pid, ppid, pgid: Number(groupId), uid: Number(uid), state, birth })
|
|
79
|
+
}
|
|
80
|
+
return group
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Executable inspection is limited to owned candidates. Asking macOS ps for
|
|
84
|
+
// comm across every user process invokes expensive argv lookups and can make
|
|
85
|
+
// cleanup slower than the existing bounded shutdown contract.
|
|
86
|
+
export async function readProcessIdentity(pid, timeout = inspectionMs) {
|
|
87
|
+
if (!validPid(pid) || !(timeout > 0)) throw new Error('Invalid process identity deadline.')
|
|
88
|
+
if (process.platform === 'linux') return linuxProcess(pid, undefined, AbortSignal.timeout(timeout))
|
|
89
|
+
let stdout
|
|
90
|
+
try {
|
|
91
|
+
({ stdout } = await execute('/bin/ps', ['-p', String(pid), '-o', 'pid=', '-o', 'ppid=', '-o', 'pgid=', '-o', 'uid=', '-o', 'stat=', '-o', 'lstart=', '-o', 'comm='],
|
|
92
|
+
{ env: { ...process.env, LC_ALL: 'C', TZ: 'UTC' }, timeout, killSignal: 'SIGKILL', maxBuffer: 1024 * 1024 }))
|
|
93
|
+
} catch (error) { if (error.code === 1 && !error.stdout?.trim()) return; throw new Error('Could not inspect process identity.') }
|
|
94
|
+
const match = stdout.match(/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.{24})\s+(.+?)\s*$/)
|
|
95
|
+
if (!match) throw new Error('Invalid process identity.')
|
|
96
|
+
const [, id, parent, groupId, uid, state, birth, command] = match
|
|
97
|
+
if (Number(id) !== pid || !validPid(Number(groupId)) || !Number.isFinite(Date.parse(birth + ' UTC'))) throw new Error('Invalid process identity.')
|
|
98
|
+
return { pid, ppid: Number(parent), pgid: Number(groupId), uid: Number(uid), state, birth, command }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function readProcessTable(timeout = inspectionMs, pgid) {
|
|
102
|
+
if (!(timeout > 0)) throw new Error('Process inspection deadline expired.')
|
|
103
|
+
const controller = new AbortController()
|
|
104
|
+
let timer
|
|
105
|
+
try {
|
|
106
|
+
return await Promise.race([processGroup(pgid, controller.signal), new Promise((_, reject) => {
|
|
107
|
+
timer = setTimeout(() => {
|
|
108
|
+
controller.abort()
|
|
109
|
+
reject(new Error('Process inspection deadline expired.'))
|
|
110
|
+
}, timeout)
|
|
111
|
+
})])
|
|
112
|
+
} finally { clearTimeout(timer) }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const sameBirth = (left, right) => validPid(left?.pid) && left.pid === right?.pid && left.birth === right?.birth
|
|
116
|
+
|
|
117
|
+
export const sameProcess = (left, right) => validPid(left?.pid) && left?.pid === right?.pid
|
|
118
|
+
&& left?.birth === right?.birth && left?.command === right?.command
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { scopedProcesses } from './process-scope.mjs'
|
|
2
|
+
import { inspectionMs, readProcessIdentity, readProcessTable, sameBirth, sameProcess, validPid } from './process-table.mjs'
|
|
3
|
+
|
|
4
|
+
// Retain PID/start/command identities after close. An exclusive inherited marker
|
|
5
|
+
// recovers descendants after reparenting; group membership and cwd never grant
|
|
6
|
+
// ownership. Inspect executable identity only for actual custody candidates.
|
|
7
|
+
export async function readOwnedTree(child, previous = [], timeout = inspectionMs, scope = previous.scope) {
|
|
8
|
+
if (!validPid(child.pid)) throw new Error('Invalid owned process tree.')
|
|
9
|
+
const table = await readProcessTable(timeout)
|
|
10
|
+
const candidates = table.filter(member => previous.some(saved => sameBirth(member, saved)))
|
|
11
|
+
let owned = (await Promise.all(candidates.map(member => readProcessIdentity(member.pid, timeout))))
|
|
12
|
+
.filter(member => member && previous.some(saved => sameProcess(member, saved)))
|
|
13
|
+
if (scope) {
|
|
14
|
+
for (const member of await scopedProcesses(scope, table, timeout, previous)) {
|
|
15
|
+
if (owned.some(saved => sameBirth(saved, member))) continue
|
|
16
|
+
const live = await readProcessIdentity(member.pid, timeout)
|
|
17
|
+
if (sameBirth(member, live) && !owned.some(saved => sameProcess(saved, live))) owned.push(live)
|
|
18
|
+
}
|
|
19
|
+
} else if (!previous.length && child.exitCode == null && child.signalCode == null) {
|
|
20
|
+
const leader = await readProcessIdentity(child.pid, timeout)
|
|
21
|
+
if (!leader || leader.ppid !== process.pid) throw new Error('Could not establish owned process tree identity.')
|
|
22
|
+
owned = [leader]
|
|
23
|
+
}
|
|
24
|
+
let changed
|
|
25
|
+
do {
|
|
26
|
+
changed = false
|
|
27
|
+
for (const member of table) {
|
|
28
|
+
if (owned.some(saved => sameBirth(saved, member))) continue
|
|
29
|
+
if (!owned.some(parent => parent.pid === member.ppid)) continue
|
|
30
|
+
const live = await readProcessIdentity(member.pid, timeout)
|
|
31
|
+
if (sameBirth(member, live) && owned.some(parent => parent.pid === live.ppid)) { owned.push(live); changed = true }
|
|
32
|
+
}
|
|
33
|
+
} while (changed)
|
|
34
|
+
Object.defineProperty(owned, 'scope', { value: scope })
|
|
35
|
+
return owned
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
// Vite has already emitted the complete Worker module graph. Miniflare 5
|
|
5
|
+
// requires explicit modules; use its own rule compiler for Wrangler's rules.
|
|
6
|
+
export async function productionModules(main, rules, {compileModuleRules,testRegExps}) {
|
|
7
|
+
const root=dirname(main),compiled=compileModuleRules(rules);
|
|
8
|
+
const modules=[{type:'ESModule',path:main}];
|
|
9
|
+
async function visit(directory){
|
|
10
|
+
for(const entry of (await readdir(directory,{withFileTypes:true})).sort((a,b)=>a.name.localeCompare(b.name))){
|
|
11
|
+
const path=join(directory,entry.name);
|
|
12
|
+
if(entry.isSymbolicLink())throw Error('Production modules must be regular output files.');
|
|
13
|
+
if(entry.isDirectory())await visit(path);
|
|
14
|
+
else if(entry.isFile()&&resolve(path)!==resolve(main)){
|
|
15
|
+
const name=relative(root,path).split('\\').join('/');
|
|
16
|
+
const rule=compiled.find(rule=>testRegExps(rule.include,name));
|
|
17
|
+
if(rule)modules.push({type:rule.type,path});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
await visit(root);return {modulesRoot:root,modules};
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {createRequire} from 'node:module';
|
|
2
|
+
import {realpath} from 'node:fs/promises';
|
|
3
|
+
import {resolve} from 'node:path';
|
|
4
|
+
import {readSettings} from './adapter-settings.mjs';
|
|
5
|
+
import {productionModules} from './production-modules.mjs';
|
|
6
|
+
|
|
7
|
+
// The project's own Miniflare, found through its pinned Wrangler without
|
|
8
|
+
// loading Wrangler: serving needs only Miniflare, and loading Wrangler as well
|
|
9
|
+
// keeps tens of megabytes resident for the whole session.
|
|
10
|
+
export async function projectMiniflare(root){
|
|
11
|
+
return createRequire(await realpath(resolve(root,'node_modules/wrangler/package.json')))('miniflare');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Runs once, in a short-lived process (production-plan.mjs): the pinned Wrangler
|
|
15
|
+
// converter supplies real bindings/assets/migrations, and the result is plain
|
|
16
|
+
// data for the serving process to hand to Miniflare.
|
|
17
|
+
export async function productionPlan(root,origin,port,host='127.0.0.1'){
|
|
18
|
+
const require=createRequire(await realpath(resolve(root,'node_modules/wrangler/package.json')));
|
|
19
|
+
const {unstable_getMiniflareWorkerOptions,unstable_readConfig}=require('wrangler');
|
|
20
|
+
const miniflare=require('miniflare');
|
|
21
|
+
const config=unstable_readConfig({config:resolve(root,'dist/server/wrangler.json')});
|
|
22
|
+
const selected=unstable_getMiniflareWorkerOptions(config);
|
|
23
|
+
const vars=(await readSettings(root,{file:'.dev.vars'})).values;
|
|
24
|
+
const {modulesRules,...workerOptions}=selected.workerOptions;
|
|
25
|
+
const worker={...workerOptions,name:config.name,...await productionModules(selected.main,modulesRules,miniflare),
|
|
26
|
+
bindings:{...workerOptions.bindings,...vars,[process.env.RER_ORIGIN_KEY ?? 'AUTH_ORIGIN']:origin,RER_DEV_ORIGIN:origin,...(process.env.RER_DEV_KEY?{RER_DEV_KEY:process.env.RER_DEV_KEY}:{})}};
|
|
27
|
+
// No Local Explorer, and trigger handlers only when the project declares Cron Triggers and rer preview runs them (RER_RUNTIME_TRIGGERS):
|
|
28
|
+
// rer's scheduler calls this internal loopback port, and the public proxy answers 404 for /cdn-cgi/*.
|
|
29
|
+
return {host,port,unsafeTriggerHandlers:process.env.RER_RUNTIME_TRIGGERS==='1',unsafeLocalExplorer:false,workers:[worker,...selected.externalWorkers]};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// JSON drops functions and flattens buffers, patterns and maps without a word.
|
|
33
|
+
// A plan that would change on its way to the serving process is refused.
|
|
34
|
+
export function serializePlan(plan){
|
|
35
|
+
return JSON.stringify(plan,function(key,value){
|
|
36
|
+
const original=this[key],kind=typeof original==='object'&&original!==null?Object.getPrototypeOf(original)?.constructor?.name:typeof original;
|
|
37
|
+
if(['function','bigint','symbol','Uint8Array','Buffer','ArrayBuffer','Map','Set','RegExp'].includes(kind))throw Error(`The Worker configuration holds a ${kind} at "${key}" that cannot be passed to the preview runtime.`);
|
|
38
|
+
return value;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {productionPlan,serializePlan} from './production-options.mjs';
|
|
2
|
+
|
|
3
|
+
// Short-lived: resolves the Worker's Miniflare options with Wrangler and writes
|
|
4
|
+
// them as JSON to stdout, a pipe only the starting runtime reads. The plan holds
|
|
5
|
+
// private settings, so it is never written to a file or an argument.
|
|
6
|
+
if(process.env.RER_ORIGIN_KEY && !/^[A-Z][A-Z0-9_]*$/.test(process.env.RER_ORIGIN_KEY))throw Error('Invalid local origin setting name');
|
|
7
|
+
const plan=await productionPlan(process.cwd(),process.env.RER_DEV_ORIGIN,Number(process.env.RER_RUNTIME_PORT),process.env.RER_RUNTIME_HOST);
|
|
8
|
+
await new Promise((done,fail)=>process.stdout.write(serializePlan(plan),error=>error?fail(error):done()));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {spawn} from 'node:child_process';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import {resolve} from 'node:path';
|
|
4
|
+
import {projectMiniflare} from './production-options.mjs';
|
|
5
|
+
|
|
6
|
+
// Preview's resident process. Wrangler resolves the Worker's options in a
|
|
7
|
+
// short-lived child that exits before serving starts; this process then holds
|
|
8
|
+
// only the pinned Miniflare, which owns one workerd and no bundler or
|
|
9
|
+
// file/config watcher.
|
|
10
|
+
let planner,stopping,runtime;
|
|
11
|
+
const stop=()=>stopping??=(async()=>{planner?.kill('SIGTERM');await runtime?.dispose();})();
|
|
12
|
+
process.on('SIGINT',()=>void stop());process.on('SIGTERM',()=>void stop());
|
|
13
|
+
async function plan(){
|
|
14
|
+
let text='';
|
|
15
|
+
planner=spawn(process.execPath,[fileURLToPath(new URL('./production-plan.mjs',import.meta.url))],{cwd:process.cwd(),env:process.env,stdio:['ignore','pipe','inherit']});
|
|
16
|
+
planner.stdout.setEncoding('utf8').on('data',chunk=>{text+=chunk;});
|
|
17
|
+
const code=await new Promise((done,fail)=>{planner.once('error',fail);planner.once('close',done);});
|
|
18
|
+
if(stopping)return undefined;
|
|
19
|
+
if(code!==0)throw Error('Resolving the Worker configuration failed.');
|
|
20
|
+
return JSON.parse(text);
|
|
21
|
+
}
|
|
22
|
+
try{
|
|
23
|
+
const options=await plan();
|
|
24
|
+
if(options){
|
|
25
|
+
const {Miniflare,convertV4MiniflareOptions}=await projectMiniflare(process.cwd());
|
|
26
|
+
runtime=new Miniflare({...convertV4MiniflareOptions(options),resourcePersistencePath:resolve(process.cwd(),'.wrangler/state/v3')});
|
|
27
|
+
if(stopping)await runtime.dispose();
|
|
28
|
+
else await runtime.ready;
|
|
29
|
+
}
|
|
30
|
+
}catch(error){await stop();throw error;}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {createRequire} from 'node:module';
|
|
2
|
+
import {readFileSync} from 'node:fs';
|
|
3
|
+
import {dirname,join,resolve} from 'node:path';
|
|
4
|
+
|
|
5
|
+
// The project's own vite entry file, so `dev` runs node on it directly instead
|
|
6
|
+
// of through `pnpm exec`, which keeps a 50-100 MB wrapper process alive for the
|
|
7
|
+
// whole session.
|
|
8
|
+
export function projectViteBinary(root){
|
|
9
|
+
let manifest;
|
|
10
|
+
try{manifest=createRequire(join(resolve(root),'package.json')).resolve('vite/package.json');}
|
|
11
|
+
catch{throw new Error('The project\'s vite is not installed. Run rer install first.');}
|
|
12
|
+
const bin=JSON.parse(readFileSync(manifest,'utf8')).bin;
|
|
13
|
+
return join(dirname(manifest),typeof bin==='string'?bin:bin.vite);
|
|
14
|
+
}
|