@runeditrun/rer 0.0.0-stage → 0.1.1
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 +157 -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 +182 -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 +158 -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 +117 -0
- package/global/launch/facts.mjs +94 -0
- package/global/launch/failure.mjs +5 -0
- package/global/launch/local-defaults.mjs +4 -0
- package/global/launch/prepare.mjs +63 -0
- package/global/launch/render.mjs +44 -0
- package/global/launch/state.mjs +106 -0
- package/global/launch/steps.mjs +90 -0
- package/global/launch/stop.mjs +89 -0
- package/global/launch/worker.mjs +62 -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,298 @@
|
|
|
1
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
2
|
+
import { jwtRanges, jwtHold } from './redaction-jwt.mjs';
|
|
3
|
+
|
|
4
|
+
const MASK = '[REDACTED]';
|
|
5
|
+
const PEM_BEGIN = /-----BEGIN [A-Z0-9 ]{0,64}PRIVATE KEY(?: BLOCK)?-----/g;
|
|
6
|
+
const PEM_END = /-----END [A-Z0-9 ]{0,64}PRIVATE KEY(?: BLOCK)?-----/g;
|
|
7
|
+
// A credential variable name has a credential word as a whole word part:
|
|
8
|
+
// GITHUB_TOKEN, db-password, apiKey or TOKEN, never PATH, DESIGN_MODE,
|
|
9
|
+
// SIGNAL_NAME, KEYBOARD_LAYOUT, COMPASS_DIR or AUTHOR_NAME.
|
|
10
|
+
const CREDENTIAL_WORD = 'token|secret|credential|key|pat|dsn|auth|pass|passwd|password|pwd|signature|sig|cookie|apikey|accesskey|privatekey|secretkey|authtoken|accesstoken';
|
|
11
|
+
const CREDENTIAL_NAME = new RegExp(`(?:^|[_.-])(?:${CREDENTIAL_WORD})s?(?:$|[_.-])`, 'i');
|
|
12
|
+
// Keep camelCase matching separate: inline flag modifiers are unavailable in
|
|
13
|
+
// Base's maintained Node 22 runtime. These names require a real case boundary.
|
|
14
|
+
const CAMEL_CREDENTIAL_NAME = /[A-Za-z0-9](?:Token|Secret|Credential|Key|Pat|Dsn|Auth|Pass|Passwd|Password|Pwd|Signature|Sig|Cookie)s?(?:$|[_.-]|[A-Z0-9])/;
|
|
15
|
+
const FIELD_NAME = '(?:api[_-]?key|access[_-]?token|auth[_-]?token|token|password|secret|signature|sig|key|pat|dsn|auth|pass)';
|
|
16
|
+
// A field name may follow `_` or `-` (DB_PASSWORD, client_secret, x-api-key),
|
|
17
|
+
// but not a letter or digit inside an ordinary word.
|
|
18
|
+
const FIELD = '(?<![A-Za-z0-9])' + FIELD_NAME;
|
|
19
|
+
// camelCase and PascalCase-suffixed names (refreshToken, clientSecret,
|
|
20
|
+
// privateKey, dbPassword, AccountKey) match case-sensitively after a letter
|
|
21
|
+
// or digit, including an acronym prefix (APIToken, AWSSecretKey).
|
|
22
|
+
// Case-sensitive credential words still exclude ordinary "Tokens"/"keyboard".
|
|
23
|
+
const CAMEL_SUFFIX = '(?:Token|Secret|Password|Passwd|Key|Pat|Dsn|Auth|Pass|Signature|Sig)';
|
|
24
|
+
const CAMEL_FIELD = '(?<=[A-Za-z0-9])' + CAMEL_SUFFIX;
|
|
25
|
+
// Stream holds retain the preceding character. Flushing it would turn an
|
|
26
|
+
// ambiguous camel suffix into a standalone field with different value rules.
|
|
27
|
+
const CAMEL_CONTEXT = '[A-Za-z0-9]' + CAMEL_SUFFIX;
|
|
28
|
+
// A boolean or 0/1 flag after a credential-shaped name (SKIP_AUTH=1,
|
|
29
|
+
// DISABLE_AUTH=true) is configuration, not a credential.
|
|
30
|
+
const FLAG_WORDS = 'true|false|yes|no|on|off|null|none|0|1'.replace(/[a-z]/g, letter => `[${letter}${letter.toUpperCase()}]`);
|
|
31
|
+
const NOT_FLAG = '(?!(?:' + FLAG_WORDS + ')(?:[\\s"\'<>;&,)\\]}]|$))';
|
|
32
|
+
// A quoted value is private up to its closing quote, spaces included.
|
|
33
|
+
// Escape pairs cannot be closing quotes; a trailing escape waits for more text.
|
|
34
|
+
const DOUBLE_QUOTED = /"(?:\\[^\r\n]|[^"\\\r\n])*(?:\\(?=[\r\n]|$))?/.source;
|
|
35
|
+
const SINGLE_QUOTED = /'(?:\\[^\r\n]|[^'\\\r\n])*(?:\\(?=[\r\n]|$))?/.source;
|
|
36
|
+
const PRIVATE_VALUE = `(?:${DOUBLE_QUOTED}(?:"|(?=[\\r\\n]|$))|${SINGLE_QUOTED}(?:'|(?=[\\r\\n]|$))|[^\\s"'<>;&]+)`;
|
|
37
|
+
const FIELD_VALUE = '["\']?\\s*[=:]\\s*' + NOT_FLAG + PRIVATE_VALUE;
|
|
38
|
+
const CLI_PREFIX = '(?<![A-Za-z0-9_-])--(?:[A-Za-z0-9]+[_-])*';
|
|
39
|
+
const CLI_ARGUMENT = CLI_PREFIX + '(' + FIELD_NAME + ')\\s+' + NOT_FLAG + '(' + PRIVATE_VALUE + ')';
|
|
40
|
+
// A bare Bearer/Basic value must look like a credential, not the next word of
|
|
41
|
+
// prose such as "Basic checks passed"; after Authorization any value is private.
|
|
42
|
+
const AUTH_CHAR = '[A-Za-z0-9._~+/-]';
|
|
43
|
+
// A slash alone is a path ("Basic usage/options", "Bearer /path"), not a
|
|
44
|
+
// credential signal; 20 leading characters without a slash still count.
|
|
45
|
+
const BARE_AUTH = '\\b(?:Bearer|Basic)\\s+(?=' + AUTH_CHAR + '*[0-9+=]|[A-Za-z0-9._~+-]{20})' + AUTH_CHAR + '{8,}=*';
|
|
46
|
+
// Any scheme word after Authorization (Bearer, Basic, token, Digest, ...) and
|
|
47
|
+
// the rest of a Cookie or Set-Cookie header are private.
|
|
48
|
+
const AUTH_PARAMS = '(?:[A-Za-z0-9_-]+=(?:"[^"\\r\\n]*"|[^\\s",<>]+)\\s*(?:,\\s*)?)+';
|
|
49
|
+
const AUTH_HEADER = '\\b(?:Proxy-)?Authorization["\']?\\s*[=:]\\s*["\']?[A-Za-z][A-Za-z0-9_-]*\\s+(?:' + AUTH_PARAMS + '|[^\\s"\'<>]+)';
|
|
50
|
+
const COOKIE_HEADER = '(?<![A-Za-z0-9_-])(?:Set-)?Cookie["\']?\\s*:\\s*(?:[^\\s=;,"\'<>]+=[^\\s;,"\'<>]*\\s*(?:;\\s*)?)+';
|
|
51
|
+
// Userinfo ends at the last @ before the path, query or fragment, so a password
|
|
52
|
+
// may contain @. A password containing / is recognised when the text after the
|
|
53
|
+
// first : is not a port; that password is bounded and never backtracked, so
|
|
54
|
+
// repeated schemes on one line stay linear. Start only at a scheme boundary:
|
|
55
|
+
// retrying a scheme at every character of a long ordinary line otherwise
|
|
56
|
+
// backtracks quadratically.
|
|
57
|
+
const SCHEME = '(?<![a-z0-9+.-])[a-z][a-z0-9+.-]*://';
|
|
58
|
+
const USERINFO = SCHEME + '([^\\s/?#"<>`]*)@';
|
|
59
|
+
const SLASHED_USERINFO = SCHEME + '([^\\s/?#:@"<>`\\[\\]]*:(?![0-9]*(?:[/?#\\s"<>`]|$))(?=(?<password>[^\\s"<>`@]{0,128}))\\k<password>)@';
|
|
60
|
+
const PATTERNS = new RegExp('(?:' + [
|
|
61
|
+
AUTH_HEADER, BARE_AUTH,
|
|
62
|
+
'(?<![A-Za-z0-9_])(?:gh[pousr]_|github_pat_|sk-(?:proj-)?|sk_live_|sk_test_|rk_live_|rk_test_|pk_live_|whsec_|SG\\.|xox[baprs]-|AKIA|ASIA|AIza|npm_|glpat-|pypi-|hf_|re_)[A-Za-z0-9_./+=-]+',
|
|
63
|
+
FIELD + FIELD_VALUE, COOKIE_HEADER,
|
|
64
|
+
USERINFO, SLASHED_USERINFO,
|
|
65
|
+
].join('|') + ')', 'gi');
|
|
66
|
+
const CAMEL_PATTERN = new RegExp('(' + CAMEL_FIELD + ')["\']?\\s*[=:]\\s*' + NOT_FLAG + '(' + PRIVATE_VALUE + ')', 'g');
|
|
67
|
+
const CLI_PATTERN = new RegExp(CLI_ARGUMENT, 'gi');
|
|
68
|
+
// Key/Auth/Pass/Token also name ordinary diagnostics. For inferred suffixed
|
|
69
|
+
// fields and separate CLI arguments, require a non-trivial value. Explicit
|
|
70
|
+
// secret registration remains exact, even for short credentials.
|
|
71
|
+
const AMBIGUOUS_FIELD = /^(?:key|auth|pass|token)$/i;
|
|
72
|
+
const MIN_ASSIGNMENT_VALUE = 8;
|
|
73
|
+
const privateAssignment = match => !AMBIGUOUS_FIELD.test(match[1]) || match[2].replace(/^["']|["']$/g, '').length >= MIN_ASSIGNMENT_VALUE;
|
|
74
|
+
// Holds for text that may still continue. Complete text, and the end of a
|
|
75
|
+
// stream, has nothing more to arrive, so a trailing bare field name, dash run
|
|
76
|
+
// or plain host:port is ordinary diagnostic text there.
|
|
77
|
+
const PREFIX_TAIL = '["\']?\\s*(?:[=:]\\s*)?["\']?$';
|
|
78
|
+
const FIELD_PREFIX = new RegExp('(?:\\b(?:Bearer|Basic)|' + FIELD + ')' + PREFIX_TAIL, 'i');
|
|
79
|
+
const CAMEL_PREFIX = new RegExp(CAMEL_CONTEXT + PREFIX_TAIL);
|
|
80
|
+
const CLI_PREFIX_HOLD = new RegExp(CLI_PREFIX + FIELD_NAME + '\\s+$', 'i');
|
|
81
|
+
// Keep a quoted value's opening field until its closing quote arrives, even
|
|
82
|
+
// when its first word is too short to classify as a credential yet.
|
|
83
|
+
const QUOTED_TAIL = '((?:' + DOUBLE_QUOTED + '|' + SINGLE_QUOTED + '))$';
|
|
84
|
+
const QUOTED_HOLDS = [
|
|
85
|
+
new RegExp(FIELD + '["\']?\\s*[=:]\\s*' + QUOTED_TAIL, 'i'),
|
|
86
|
+
new RegExp(CAMEL_CONTEXT + '["\']?\\s*[=:]\\s*' + QUOTED_TAIL),
|
|
87
|
+
new RegExp(CLI_PREFIX + FIELD_NAME + '\\s+' + QUOTED_TAIL, 'i'),
|
|
88
|
+
];
|
|
89
|
+
// A short unquoted value may still grow into a secret or out of a flag. Keep
|
|
90
|
+
// its field context until the value ends or its classification is settled.
|
|
91
|
+
const SHORT_VALUE_TAIL = `[^\\s"'<>;&]{1,${MIN_ASSIGNMENT_VALUE - 1}}(?![\\s\\S])`;
|
|
92
|
+
const SHORT_FIELD_HOLDS = [
|
|
93
|
+
new RegExp(FIELD + '["\']?\\s*[=:]\\s*' + SHORT_VALUE_TAIL, 'i'),
|
|
94
|
+
new RegExp(CAMEL_CONTEXT + '["\']?\\s*[=:]\\s*' + SHORT_VALUE_TAIL),
|
|
95
|
+
new RegExp(CLI_PREFIX + FIELD_NAME + '\\s+' + SHORT_VALUE_TAIL, 'i'),
|
|
96
|
+
];
|
|
97
|
+
const PEM_HEADER_HOLD = /-----BEGIN (?![A-Z0-9 ]*-----)[^\n]*$/;
|
|
98
|
+
const STREAM_HOLDS = [jwtHold, new RegExp(SCHEME + '[^\\s/?#"<>`]*$', 'i'), PEM_HEADER_HOLD];
|
|
99
|
+
const COMPLETE_HOLDS = [jwtHold, new RegExp(SCHEME + '[^\\s/?#:@"<>`]*:(?![0-9]*$)[^\\s/?#"<>`]*$', 'i'), PEM_HEADER_HOLD];
|
|
100
|
+
const CREDENTIAL_URL = new RegExp(USERINFO + '|' + SLASHED_USERINFO, 'i');
|
|
101
|
+
const userinfoPasswords = value => [USERINFO, SLASHED_USERINFO].flatMap(source => {
|
|
102
|
+
const userinfo = new RegExp(source, 'i').exec(value)?.[1] ?? '', at = userinfo.indexOf(':');
|
|
103
|
+
if (at < 0) return [];
|
|
104
|
+
const password = userinfo.slice(at + 1);
|
|
105
|
+
let decoded = password;
|
|
106
|
+
try { decoded = decodeURIComponent(password); } catch {}
|
|
107
|
+
return [password, decoded];
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Stateful stripping also covers UTF-8 C1 controls, which stripVTControlCharacters
|
|
111
|
+
// alone leaves behind. Broken control strings recover at a line or 4 KiB.
|
|
112
|
+
function controlCleaner() {
|
|
113
|
+
let state = '', length = 0;
|
|
114
|
+
return {
|
|
115
|
+
write(text) {
|
|
116
|
+
let output = '';
|
|
117
|
+
for (const char of text) {
|
|
118
|
+
if (state) {
|
|
119
|
+
if (char === '\n' || char === '\r') { state = ''; length = 0; output += '\n'; continue; }
|
|
120
|
+
if (++length >= 4096) { state = ''; length = 0; continue; }
|
|
121
|
+
if (state === 'escape') {
|
|
122
|
+
state = char === '[' ? 'csi' : ']PX^_'.includes(char) ? 'string' : '';
|
|
123
|
+
} else if (state === 'csi') {
|
|
124
|
+
if (char >= '@' && char <= '~') state = '';
|
|
125
|
+
} else if (char === '\x07' || char === '\x9c' || (state === 'stringEscape' && char === '\\')) state = '';
|
|
126
|
+
else state = char === '\x1b' ? 'stringEscape' : 'string';
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (char === '\x1b') { state = 'escape'; length = 0; continue; }
|
|
130
|
+
if (char === '\x9b') { state = 'csi'; length = 0; continue; }
|
|
131
|
+
if ('\x90\x98\x9d\x9e\x9f'.includes(char)) { state = 'string'; length = 0; continue; }
|
|
132
|
+
if (char === '\r') output += '\n';
|
|
133
|
+
else if (char === '\n' || char === '\t' || (char >= ' ' && !/[\x7f-\x9f\u202a-\u202e\u2066-\u2069]/.test(char))) output += char;
|
|
134
|
+
}
|
|
135
|
+
return output;
|
|
136
|
+
},
|
|
137
|
+
reset() { state = ''; length = 0; }
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const cleanText = text => controlCleaner().write(String(text));
|
|
141
|
+
|
|
142
|
+
// Keep every value for this session, even after its credential scope is cleared.
|
|
143
|
+
export function createRedaction({mask = MASK} = {}) {
|
|
144
|
+
const secrets = new Set();
|
|
145
|
+
let longest = 1;
|
|
146
|
+
// Each known value is registered with the encodings and parts a tool may print
|
|
147
|
+
// instead of its exact bytes. A derived form shorter than eight characters
|
|
148
|
+
// (and than the value) is skipped so it cannot erase ordinary digits or words.
|
|
149
|
+
const encodings = value => {
|
|
150
|
+
const bytes = Buffer.from(value), encoded = encodeURIComponent(value.toWellFormed()), base64 = bytes.toString('base64');
|
|
151
|
+
const json = JSON.stringify(value).slice(1,-1);
|
|
152
|
+
const forms = [value, value.toUpperCase(), value.toLowerCase(),
|
|
153
|
+
value.replace(/[&<>"']/g, char => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[char])),
|
|
154
|
+
value.replaceAll("'", "'\\''"),
|
|
155
|
+
cleanText(value), cleanText(value.replace(/\r?\n/g,'\r\n')), json,
|
|
156
|
+
json.replace(/[^\x00-\x7e]/g, char => '\\u' + char.charCodeAt(0).toString(16).padStart(4,'0')),
|
|
157
|
+
base64, base64.replace(/=+$/,''), bytes.toString('base64url'), encoded,
|
|
158
|
+
new URLSearchParams({value}).toString().slice('value='.length),
|
|
159
|
+
encoded.replace(/%[0-9A-F]{2}/g, part => part.toLowerCase()), encoded.replace(/%20/g, '+'), encodeURIComponent(encoded)];
|
|
160
|
+
if (value.length >= 8) forms.push(bytes.toString('hex'), bytes.toString('hex').toUpperCase());
|
|
161
|
+
return forms;
|
|
162
|
+
};
|
|
163
|
+
const addSecrets = input => {
|
|
164
|
+
if (typeof input === 'string' && input) {
|
|
165
|
+
const minimum = Math.min(8, input.length);
|
|
166
|
+
const parts = [input, input.trim(), ...userinfoPasswords(input)].filter(part => part.length >= minimum);
|
|
167
|
+
for (const value of new Set(parts.flatMap(encodings))) if (value.length >= minimum) { secrets.add(value); longest = Math.max(longest, value.length); }
|
|
168
|
+
} else if (input && typeof input === 'object') for (const value of Object.values(input)) addSecrets(value);
|
|
169
|
+
};
|
|
170
|
+
const ranges = text => {
|
|
171
|
+
const assignments = [...text.matchAll(CAMEL_PATTERN), ...text.matchAll(CLI_PATTERN)].filter(privateAssignment);
|
|
172
|
+
const found = [...text.matchAll(PATTERNS), ...assignments].map(match => [match.index, match.index + match[0].length]);
|
|
173
|
+
found.push(...jwtRanges(text));
|
|
174
|
+
for (const begin of text.matchAll(PEM_BEGIN)) {
|
|
175
|
+
const end = [...text.slice(begin.index + begin[0].length).matchAll(PEM_END)][0];
|
|
176
|
+
found.push([begin.index, end ? begin.index + begin[0].length + end.index + end[0].length : text.length]);
|
|
177
|
+
}
|
|
178
|
+
for (const secret of secrets) {
|
|
179
|
+
let from = 0, at;
|
|
180
|
+
while ((at = text.indexOf(secret, from)) >= 0) { found.push([at, at + secret.length]); from = at + 1; }
|
|
181
|
+
}
|
|
182
|
+
return found.sort((a,b) => a[0]-b[0]);
|
|
183
|
+
};
|
|
184
|
+
const replace = text => {
|
|
185
|
+
let end = 0, result = '';
|
|
186
|
+
for (const [start,stop] of ranges(text)) {
|
|
187
|
+
if (stop <= end) continue;
|
|
188
|
+
if (start >= end) result += text.slice(end,start) + mask;
|
|
189
|
+
end = stop;
|
|
190
|
+
}
|
|
191
|
+
return result + text.slice(end);
|
|
192
|
+
};
|
|
193
|
+
// `complete` text has nothing more to arrive: only a registered secret's prefix,
|
|
194
|
+
// a credential-shaped URL authority, a partial JWT or private-key header, or an
|
|
195
|
+
// unterminated private-key block stays held there.
|
|
196
|
+
const incompleteStart = (text, minimumPrefix=1, complete=false) => {
|
|
197
|
+
let cutoff = text.length;
|
|
198
|
+
for (const secret of secrets) {
|
|
199
|
+
// The earliest start whose remaining text begins this secret is its longest held prefix.
|
|
200
|
+
for (let at=Math.max(0,text.length-secret.length+1); at<=text.length-minimumPrefix; at++) {
|
|
201
|
+
if (text.charCodeAt(at)===secret.charCodeAt(0) && secret.startsWith(text.slice(at))) { cutoff=Math.min(cutoff,at); break; }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (!complete) {
|
|
205
|
+
for (const pattern of [FIELD_PREFIX, CAMEL_PREFIX, CLI_PREFIX_HOLD, ...QUOTED_HOLDS, ...SHORT_FIELD_HOLDS]) {
|
|
206
|
+
const prefix = pattern.exec(text);
|
|
207
|
+
if (prefix) cutoff = Math.min(cutoff,prefix.index);
|
|
208
|
+
}
|
|
209
|
+
const pemPrefix = '-----BEGIN ';
|
|
210
|
+
for (let size=pemPrefix.length-1; size>=minimumPrefix; size--) if (text.endsWith(pemPrefix.slice(0,size))) cutoff=Math.min(cutoff,text.length-size);
|
|
211
|
+
}
|
|
212
|
+
// A JWT header, URL authority, and private-key header are private even before
|
|
213
|
+
// the signature, @ delimiter, or full PEM header arrives.
|
|
214
|
+
for (const pattern of complete ? COMPLETE_HOLDS : STREAM_HOLDS) {
|
|
215
|
+
const match = pattern.exec(text); if (match) cutoff = Math.min(cutoff,match.index);
|
|
216
|
+
}
|
|
217
|
+
for (const begin of text.matchAll(PEM_BEGIN)) {
|
|
218
|
+
if (![...text.slice(begin.index + begin[0].length).matchAll(PEM_END)].length) cutoff=Math.min(cutoff,begin.index);
|
|
219
|
+
}
|
|
220
|
+
return cutoff;
|
|
221
|
+
};
|
|
222
|
+
const snapshot = (text, minimumPrefix=1, complete=false) => {
|
|
223
|
+
let cutoff = incompleteStart(text,minimumPrefix,complete);
|
|
224
|
+
for (const [start,end] of ranges(text)) if (start<cutoff && end>cutoff) cutoff=start;
|
|
225
|
+
return replace(text.slice(0,cutoff)) + (cutoff<text.length ? mask : '');
|
|
226
|
+
};
|
|
227
|
+
const redact = text => snapshot(cleanText(text),4,true);
|
|
228
|
+
const stream = emit => {
|
|
229
|
+
const decoder = new StringDecoder('utf8'), cleaner = controlCleaner();
|
|
230
|
+
let pending = '', discardToken = false, discardQuote = '', discardEscaped = false, discardPem = false, pemTail = '';
|
|
231
|
+
const drain = () => {
|
|
232
|
+
let cutoff = Math.max(pending.lastIndexOf('\n')+1, pending.length-Math.max(256,longest-1));
|
|
233
|
+
cutoff = Math.min(cutoff,incompleteStart(pending));
|
|
234
|
+
for (const [start,end] of ranges(pending)) if (start<cutoff && end>cutoff) cutoff=start;
|
|
235
|
+
if (cutoff) { emit(replace(pending.slice(0,cutoff))); pending=pending.slice(cutoff); }
|
|
236
|
+
// Tokens and PEM bodies can be arbitrarily large; never retain their tails.
|
|
237
|
+
if (pending.length > longest+16384) {
|
|
238
|
+
discardPem = [...pending.matchAll(PEM_BEGIN)].some(begin => ![...pending.slice(begin.index+begin[0].length).matchAll(PEM_END)].length);
|
|
239
|
+
pemTail = discardPem ? pending.slice(-128) : '';
|
|
240
|
+
const quoted = QUOTED_HOLDS.map(pattern => pattern.exec(pending)).filter(Boolean).sort((a,b) => a.index-b.index)[0];
|
|
241
|
+
discardQuote = !discardPem && quoted ? quoted[1][0] : '';
|
|
242
|
+
discardEscaped = !!discardQuote && ((/\\+$/.exec(pending)?.[0].length ?? 0) % 2 === 1);
|
|
243
|
+
emit(snapshot(pending,4)); pending=''; discardToken=!discardPem&&!discardQuote;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
const pushText = text => {
|
|
247
|
+
text = cleaner.write(text);
|
|
248
|
+
if (discardPem) {
|
|
249
|
+
const combined = pemTail+text, end = [...combined.matchAll(PEM_END)][0];
|
|
250
|
+
if (!end) { pemTail=combined.slice(-128); return; }
|
|
251
|
+
text=combined.slice(end.index+end[0].length); pemTail=''; discardPem=false;
|
|
252
|
+
}
|
|
253
|
+
if (discardQuote) {
|
|
254
|
+
let at = 0;
|
|
255
|
+
for (; at < text.length; at++) {
|
|
256
|
+
const char = text[at];
|
|
257
|
+
if (char === '\n' || char === '\r') { discardQuote=''; break; }
|
|
258
|
+
if (discardEscaped) { discardEscaped=false; continue; }
|
|
259
|
+
if (char === '\\') { discardEscaped=true; continue; }
|
|
260
|
+
if (char === discardQuote) { discardQuote=''; at++; break; }
|
|
261
|
+
}
|
|
262
|
+
if (discardQuote) return;
|
|
263
|
+
text = text.slice(at); discardEscaped=false;
|
|
264
|
+
}
|
|
265
|
+
if (discardToken) {
|
|
266
|
+
const at=text.search(/[\s"'<>]/); if (at<0) return;
|
|
267
|
+
text=text.slice(at); discardToken=false;
|
|
268
|
+
}
|
|
269
|
+
pending+=text; drain();
|
|
270
|
+
};
|
|
271
|
+
return {
|
|
272
|
+
write(chunk) {
|
|
273
|
+
// Decode and clean bounded slices, even when a producer hands us 100 MiB.
|
|
274
|
+
if (Buffer.isBuffer(chunk) || ArrayBuffer.isView(chunk)) {
|
|
275
|
+
const bytes=Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk.buffer,chunk.byteOffset,chunk.byteLength);
|
|
276
|
+
for (let index=0; index<bytes.length; index+=4096) pushText(decoder.write(bytes.subarray(index,index+4096)));
|
|
277
|
+
} else {
|
|
278
|
+
const text=String(chunk);
|
|
279
|
+
for (let index=0; index<text.length;) { let end=Math.min(text.length,index+4096); if (end<text.length && /[\ud800-\udbff]/.test(text[end-1])) end--; pushText(text.slice(index,end)); index=end; }
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
end() { pushText(decoder.end()); emit(snapshot(pending,4,true)); pending=''; discardToken=false; discardQuote=''; discardEscaped=false; discardPem=false; pemTail=''; cleaner.reset(); },
|
|
283
|
+
snapshot: () => snapshot(pending),
|
|
284
|
+
get bufferedLength() { return pending.length+pemTail.length; }
|
|
285
|
+
};
|
|
286
|
+
};
|
|
287
|
+
return {addSecrets,redact,stream};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function credentialValues(input, declared = []) {
|
|
291
|
+
if (!input || typeof input !== 'object') return [];
|
|
292
|
+
return Object.entries(input).flatMap(([key,value]) => {
|
|
293
|
+
// An explicit model declaration remains an exact secret contract, including
|
|
294
|
+
// short values. Environment heuristics must not turn boolean flags into masks.
|
|
295
|
+
if (typeof value === 'string') return declared.includes(key) || (value.length>=8 && (CREDENTIAL_NAME.test(key) || CAMEL_CREDENTIAL_NAME.test(key) || CREDENTIAL_URL.test(value))) ? [value] : [];
|
|
296
|
+
return value && typeof value==='object' ? credentialValues(value,declared) : [];
|
|
297
|
+
});
|
|
298
|
+
}
|