@mandujs/core 0.54.32 → 0.55.0-beta.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/README.md +654 -654
- package/package.json +106 -210
- package/scripts/postinstall-lock.ts +153 -153
- package/src/a11y/__tests__/run-audit.test.ts +333 -333
- package/src/a11y/fix-hints.ts +76 -76
- package/src/a11y/index.ts +18 -18
- package/src/a11y/run-audit.ts +15 -15
- package/src/a11y/types.ts +125 -125
- package/src/agent/__tests__/apply.test.ts +224 -0
- package/src/agent/__tests__/context.test.ts +97 -98
- package/src/agent/apply.ts +1031 -0
- package/src/agent/context.ts +552 -552
- package/src/agent/index.ts +4 -3
- package/src/agent/plan.ts +161 -243
- package/src/agent/repair.ts +239 -162
- package/src/agent/sync.ts +197 -198
- package/src/agent/types.ts +242 -94
- package/src/agent/verify.ts +55 -55
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +15 -5
- package/src/auth/__tests__/reset.test.ts +2 -2
- package/src/auth/__tests__/tokens.test.ts +274 -274
- package/src/auth/__tests__/verification.test.ts +274 -274
- package/src/auth/index.ts +76 -76
- package/src/auth/login.ts +225 -225
- package/src/auth/password.ts +14 -2
- package/src/auth/reset.ts +243 -243
- package/src/auth/tokens.ts +612 -612
- package/src/auth/verification.ts +253 -253
- package/src/brain/__tests__/redactor.test.ts +94 -94
- package/src/brain/adapters/__tests__/_helpers.ts +83 -83
- package/src/brain/adapters/__tests__/anthropic-oauth.test.ts +196 -196
- package/src/brain/adapters/__tests__/chatgpt-auth.test.ts +193 -193
- package/src/brain/adapters/__tests__/openai-oauth.test.ts +209 -209
- package/src/brain/adapters/__tests__/resolver.test.ts +143 -143
- package/src/brain/adapters/anthropic-oauth.ts +1 -1
- package/src/brain/adapters/chatgpt-auth.ts +300 -300
- package/src/brain/adapters/index.ts +319 -319
- package/src/brain/adapters/oauth-flow.ts +439 -439
- package/src/brain/consent.ts +240 -240
- package/src/brain/credentials.ts +396 -396
- package/src/brain/doctor/analyzer.ts +7 -7
- package/src/bundler/__snapshots__/build.test.ts.snap +5 -5
- package/src/bundler/__tests__/build-runner.ts +166 -166
- package/src/bundler/__tests__/client-boundary-transform.test.ts +524 -524
- package/src/bundler/__tests__/cold-start.test.ts +60 -60
- package/src/bundler/__tests__/css.test.ts +49 -20
- package/src/bundler/__tests__/dev-reliability.test.ts +619 -619
- package/src/bundler/__tests__/extended-watch.test.ts +711 -711
- package/src/bundler/__tests__/fast-refresh.test.ts +24 -24
- package/src/bundler/__tests__/generation.test.ts +447 -0
- package/src/bundler/__tests__/hdr.test.ts +24 -18
- package/src/bundler/__tests__/hmr-client.test.ts +62 -24
- package/src/bundler/__tests__/jsx-runtime-shim.test.ts +179 -140
- package/src/bundler/__tests__/manifest-schema.test.ts +305 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +42 -42
- package/src/bundler/__tests__/slot-dispatch.test.ts +573 -573
- package/src/bundler/__tests__/url-cap-and-slot-regex.test.ts +286 -286
- package/src/bundler/__tests__/vendor-cache.test.ts +455 -455
- package/src/bundler/analyzer.ts +15 -15
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +898 -915
- package/src/bundler/build.ts +113 -24
- package/src/bundler/client-boundary-transform.ts +977 -977
- package/src/bundler/css.ts +65 -44
- package/src/bundler/dev.ts +105 -73
- package/src/bundler/fast-refresh-preamble.ts +47 -47
- package/src/bundler/generation.ts +602 -0
- package/src/bundler/index.ts +3 -3
- package/src/bundler/manifest-schema.ts +55 -40
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +13 -13
- package/src/bundler/plugins/__tests__/react-compiler-config.test.ts +83 -83
- package/src/bundler/plugins/__tests__/react-compiler-lint.test.ts +110 -110
- package/src/bundler/plugins/block-generated-imports.ts +16 -15
- package/src/bundler/plugins/index.ts +83 -83
- package/src/bundler/plugins/react-compiler-config.ts +108 -108
- package/src/bundler/plugins/react-compiler-lint.ts +253 -253
- package/src/bundler/plugins/react-compiler.ts +162 -162
- package/src/bundler/prerender.ts +29 -9
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +1 -1
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +58 -56
- package/src/bundler/vendor-cache-types.ts +130 -130
- package/src/bundler/vendor-cache.ts +526 -526
- package/src/change/snapshot.ts +18 -18
- package/src/client/Form.tsx +105 -105
- package/src/client/Link.tsx +9 -9
- package/src/client/__tests__/props-serialization.test.ts +37 -37
- package/src/client/__tests__/use-sse.test.ts +153 -153
- package/src/client/globals.ts +1 -1
- package/src/client/hooks.ts +362 -362
- package/src/client/hydrate.ts +2 -2
- package/src/client/index.ts +1 -1
- package/src/client/island.ts +79 -79
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/props-serialization.ts +233 -233
- package/src/client/runtime-entry.ts +598 -598
- package/src/client/runtime.ts +1 -1
- package/src/client/serialize.ts +50 -50
- package/src/client/use-fetch.ts +6 -6
- package/src/client/use-head.ts +197 -197
- package/src/client/use-sse.ts +378 -378
- package/src/client/window-state.ts +101 -101
- package/src/components/Image-compat.ts +3 -0
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +1 -1
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +9 -9
- package/src/content/content-layer.ts +7 -7
- package/src/content/data-store.ts +245 -245
- package/src/content/frontmatter.ts +189 -189
- package/src/content/generate-types.ts +1 -1
- package/src/content/index.ts +2 -2
- package/src/content/loader-context.ts +171 -171
- package/src/content/loaders/api.ts +216 -216
- package/src/content/loaders/file.ts +172 -172
- package/src/content/loaders/glob.ts +253 -253
- package/src/content/loaders/index.ts +34 -34
- package/src/content/loaders/types.ts +137 -137
- package/src/content/meta-store.ts +209 -209
- package/src/content/prebuild.test.ts +571 -571
- package/src/content/prebuild.ts +636 -636
- package/src/content/schema.ts +20 -20
- package/src/content/sidebar.ts +630 -630
- package/src/content/slug.ts +110 -110
- package/src/content/types.ts +282 -282
- package/src/content/watcher.ts +135 -135
- package/src/contract/client-safe.test.ts +42 -42
- package/src/contract/client-safe.ts +114 -114
- package/src/contract/define.ts +11 -11
- package/src/contract/index.ts +1 -1
- package/src/contract/normalize.test.ts +276 -276
- package/src/contract/normalize.ts +410 -410
- package/src/contract/registry.test.ts +206 -206
- package/src/contract/route-helpers.ts +1 -1
- package/src/contract/rpc.ts +443 -443
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +9 -9
- package/src/db/index.ts +2 -2
- package/src/db/migrations/history-table.ts +345 -345
- package/src/db/migrations/index.ts +3 -3
- package/src/db/migrations/lock.ts +324 -324
- package/src/db/migrations/runner.ts +650 -650
- package/src/deploy/cache.ts +140 -140
- package/src/deploy/compile/vercel.ts +344 -344
- package/src/deploy/index.ts +87 -87
- package/src/deploy/inference/brain.ts +268 -268
- package/src/deploy/inference/context.ts +82 -82
- package/src/deploy/inference/filling-extract.ts +245 -245
- package/src/deploy/inference/heuristic.ts +182 -182
- package/src/deploy/intent.ts +173 -173
- package/src/deploy/plan.ts +178 -178
- package/src/design/__tests__/agents-link.test.ts +109 -109
- package/src/design/__tests__/extract-patch-diff.test.ts +265 -265
- package/src/design/__tests__/lint.test.ts +110 -110
- package/src/design/__tests__/parser.test.ts +195 -195
- package/src/design/__tests__/tailwind-theme.test.ts +229 -229
- package/src/design/agents-link.ts +165 -165
- package/src/design/diff.ts +138 -138
- package/src/design/extract.ts +285 -285
- package/src/design/index.ts +102 -102
- package/src/design/lint.ts +209 -209
- package/src/design/parser.ts +555 -555
- package/src/design/patch.ts +241 -241
- package/src/design/scaffold.ts +147 -147
- package/src/design/tailwind-theme.ts +441 -441
- package/src/design/types.ts +210 -210
- package/src/desktop/__tests__/smoke.test.ts +2 -2
- package/src/desktop/__tests__/webview-fallback.test.ts +12 -32
- package/src/desktop/__tests__/window.test.ts +20 -99
- package/src/desktop/__tests__/worker.test.ts +266 -266
- package/src/desktop/index.ts +43 -43
- package/src/desktop/types.ts +158 -158
- package/src/desktop/webview-fallback.ts +17 -4
- package/src/desktop/window.ts +17 -8
- package/src/desktop/worker.ts +180 -180
- package/src/dev-error-overlay/__tests__/overlay-injector.test.ts +241 -241
- package/src/dev-error-overlay/index.ts +30 -30
- package/src/dev-error-overlay/overlay-injector.ts +243 -243
- package/src/dev-error-overlay/overlay-styles.ts +52 -52
- package/src/dev-error-overlay/types.ts +66 -66
- package/src/devtools/ai/context-builder.ts +375 -375
- package/src/devtools/ai/index.ts +25 -25
- package/src/devtools/ai/mcp-connector.ts +25 -25
- package/src/devtools/client/catchers/error-catcher.ts +344 -344
- package/src/devtools/client/catchers/index.ts +18 -18
- package/src/devtools/client/components/index.ts +39 -39
- package/src/devtools/client/components/mandu-character.tsx +331 -331
- package/src/devtools/client/components/panel/errors-panel.tsx +259 -259
- package/src/devtools/client/components/panel/guard-panel.tsx +30 -30
- package/src/devtools/client/components/panel/islands-panel.tsx +16 -16
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +1 -1
- package/src/devtools/client/components/panel/preview-panel.tsx +46 -46
- package/src/devtools/client/filters/context-filters.ts +282 -282
- package/src/devtools/client/filters/index.ts +16 -16
- package/src/devtools/client/index.ts +63 -63
- package/src/devtools/hook/create-hook.ts +207 -207
- package/src/devtools/hook/index.ts +13 -13
- package/src/devtools/index.ts +439 -439
- package/src/devtools/init.ts +265 -265
- package/src/devtools/protocol.ts +237 -237
- package/src/devtools/server/index.ts +17 -17
- package/src/devtools/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/diagnose/__tests__/checks.test.ts +136 -136
- package/src/diagnose/checks.ts +185 -185
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +10 -10
- package/src/diagnose/types.ts +53 -53
- package/src/email/__tests__/email.test.ts +355 -355
- package/src/email/index.ts +282 -282
- package/src/email/smtp.ts +64 -64
- package/src/error/domains.ts +265 -265
- package/src/error/types.ts +6 -6
- package/src/errors/extractor.ts +409 -409
- package/src/errors/index.ts +19 -19
- package/src/filling/__tests__/session-sqlite.test.ts +5 -1
- package/src/filling/auth.ts +308 -308
- package/src/filling/body-parse.test.ts +60 -60
- package/src/filling/cookie-codec.ts +5 -3
- package/src/filling/deps.ts +265 -265
- package/src/filling/head-method.test.ts +154 -154
- package/src/filling/session-sqlite.ts +617 -617
- package/src/filling/sse.ts +5 -5
- package/src/filling/ws.ts +78 -78
- package/src/generator/generate.ts +30 -30
- package/src/generator/index.ts +3 -3
- package/src/generator/templates.test.ts +48 -48
- package/src/generator/templates.ts +219 -219
- package/src/guard/__tests__/design-inline-class.test.ts +219 -219
- package/src/guard/__tests__/tsgolint-bridge.test.ts +347 -347
- package/src/guard/analyzer.ts +360 -360
- package/src/guard/auto-correct.ts +1 -1
- package/src/guard/check.ts +39 -24
- package/src/guard/config-guard.ts +13 -13
- package/src/guard/contract-guard.ts +9 -9
- package/src/guard/define-rule.ts +243 -243
- package/src/guard/design-inline-class.ts +393 -393
- package/src/guard/file-type.test.ts +24 -24
- package/src/guard/fs-routes-policy.ts +51 -51
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/index.ts +11 -11
- package/src/guard/presets/atomic.ts +70 -70
- package/src/guard/presets/clean.ts +77 -77
- package/src/guard/presets/fsd.ts +79 -79
- package/src/guard/presets/hexagonal.ts +68 -68
- package/src/guard/reporter.ts +442 -442
- package/src/guard/rule-presets.ts +379 -379
- package/src/guard/semantic-slots.ts +1 -1
- package/src/guard/suggestions.ts +358 -358
- package/src/guard/tsgolint-bridge.ts +512 -512
- package/src/guard/types.ts +348 -348
- package/src/guard/watcher.ts +405 -405
- package/src/i18n/define.ts +126 -126
- package/src/i18n/index.ts +52 -52
- package/src/i18n/message-registry.ts +173 -173
- package/src/i18n/types.ts +112 -112
- package/src/id/__tests__/id.test.ts +3 -3
- package/src/id/index.ts +105 -105
- package/src/index.ts +9 -48
- package/src/internal/client-boundary.ts +266 -266
- package/src/internal/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -779
- package/src/kitchen/api/bundle-inspector.ts +179 -0
- package/src/kitchen/api/errors-grouping.ts +126 -126
- package/src/kitchen/api/file-api.ts +11 -11
- package/src/kitchen/kitchen-handler.ts +36 -0
- package/src/kitchen/kitchen-ui.ts +456 -0
- package/src/logging/index.ts +22 -22
- package/src/logging/transports.ts +365 -365
- package/src/middleware/bridge.ts +147 -147
- package/src/middleware/compose.ts +134 -134
- package/src/middleware/compress.ts +62 -62
- package/src/middleware/cors.ts +47 -47
- package/src/middleware/csrf.ts +328 -328
- package/src/middleware/define.ts +132 -132
- package/src/middleware/jwt.ts +134 -134
- package/src/middleware/logger.ts +58 -58
- package/src/middleware/oauth/__tests__/oauth.test.ts +1 -1
- package/src/middleware/oauth/index.ts +505 -505
- package/src/middleware/oauth/providers.ts +115 -115
- package/src/middleware/rate-limit/index.ts +522 -522
- package/src/middleware/rate-limit/sqlite-store.ts +382 -382
- package/src/middleware/scheduler-cron.ts +96 -96
- package/src/middleware/secure/__tests__/secure.test.ts +360 -360
- package/src/middleware/secure/csp.ts +193 -193
- package/src/middleware/session.ts +174 -174
- package/src/middleware/timeout.ts +55 -55
- package/src/observability/logger-adapter.ts +36 -36
- package/src/observability/sqlite-store.ts +254 -254
- package/src/openapi/generator.ts +1 -1
- package/src/openapi/openapi.test.ts +43 -43
- package/src/perf/__tests__/user-marks.test.ts +354 -354
- package/src/perf/index.ts +133 -133
- package/src/perf/user-marks.ts +1 -1
- package/src/plugins/__tests__/lifecycle-integration.test.ts +272 -272
- package/src/plugins/__tests__/runner.test.ts +409 -409
- package/src/plugins/define.ts +124 -124
- package/src/plugins/examples/dep-check-plugin.ts +80 -80
- package/src/plugins/examples/prerender-cache-plugin.ts +111 -111
- package/src/plugins/examples/sitemap-plugin.ts +65 -65
- package/src/plugins/runner.ts +361 -361
- package/src/plugins/types.ts +368 -368
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +7 -7
- package/src/resource/__tests__/schema.test.ts +14 -14
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +165 -165
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +146 -146
- package/src/resource/ddl/persistence-types.ts +218 -218
- package/src/resource/ddl/type-map.ts +223 -223
- package/src/resource/ddl/types.ts +232 -232
- package/src/resource/generator-repo.ts +630 -630
- package/src/resource/generator-schema.ts +11 -11
- package/src/resource/generators/slot.ts +72 -72
- package/src/resource/schema.ts +21 -21
- package/src/router/client-entry.test.ts +227 -227
- package/src/router/client-entry.ts +218 -218
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.test.ts +532 -532
- package/src/router/fs-routes.ts +53 -53
- package/src/router/fs-scanner.ts +216 -216
- package/src/router/fs-types.ts +19 -19
- package/src/router/route-source-analyzer.ts +521 -521
- package/src/routes/index.ts +74 -74
- package/src/routes/metadata-routes.ts +427 -427
- package/src/routes/types.ts +341 -341
- package/src/runtime/__tests__/devtools-adapter.test.ts +68 -68
- package/src/runtime/__tests__/error-boundary-redaction.test.ts +141 -141
- package/src/runtime/__tests__/hdr-client.test.ts +223 -223
- package/src/runtime/__tests__/http-errors.test.ts +117 -117
- package/src/runtime/__tests__/inline-client-hydration.test.ts +237 -237
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/__tests__/observability-lifecycle.test.ts +103 -103
- package/src/runtime/__tests__/page-render-response.test.ts +517 -517
- package/src/runtime/__tests__/request-middleware.test.ts +70 -70
- package/src/runtime/__tests__/searchparams-page-props.test.ts +81 -81
- package/src/runtime/adapter.ts +47 -47
- package/src/runtime/boundary.tsx +252 -252
- package/src/runtime/cache.ts +494 -494
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/devtools-adapter.ts +68 -68
- package/src/runtime/escape.ts +34 -34
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/fast-refresh-types.ts +1 -1
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +30 -11
- package/src/runtime/http-errors.ts +113 -113
- package/src/runtime/image-handler.ts +1 -1
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/logger.test.ts +345 -345
- package/src/runtime/middleware.ts +264 -264
- package/src/runtime/not-found.ts +93 -93
- package/src/runtime/observability-lifecycle.ts +290 -290
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/page-render-response.ts +287 -274
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/rate-limit.ts +1 -1
- package/src/runtime/redirect.ts +1 -1
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/request-middleware.ts +31 -31
- package/src/runtime/router.test.ts +4 -4
- package/src/runtime/router.ts +10 -10
- package/src/runtime/server.ts +127 -211
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/ssr.ts +43 -17
- package/src/runtime/static-files.ts +369 -289
- package/src/runtime/streaming-ssr.ts +219 -180
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/__tests__/scheduler.test.ts +12 -11
- package/src/scheduler/index.ts +11 -5
- package/src/scheduler/validate.ts +169 -169
- package/src/seo/index.ts +219 -219
- package/src/seo/integration/ssr.ts +306 -306
- package/src/seo/render/basic.ts +435 -435
- package/src/seo/render/index.ts +143 -143
- package/src/seo/render/jsonld.ts +539 -539
- package/src/seo/render/opengraph.ts +197 -197
- package/src/seo/render/robots.ts +116 -116
- package/src/seo/render/sitemap.ts +137 -137
- package/src/seo/render/twitter.ts +127 -127
- package/src/seo/resolve/opengraph.ts +143 -143
- package/src/seo/resolve/robots.ts +73 -73
- package/src/seo/resolve/title.ts +94 -94
- package/src/seo/resolve/twitter.ts +73 -73
- package/src/seo/resolve/url.ts +104 -104
- package/src/seo/routes/index.ts +290 -290
- package/src/seo/types.ts +588 -588
- package/src/slot/validator.ts +39 -39
- package/src/spec/schema.ts +35 -35
- package/src/storage/s3/__tests__/s3.test.ts +479 -479
- package/src/storage/s3/index.ts +412 -412
- package/src/testing/__tests__/assertions.test.ts +632 -632
- package/src/testing/__tests__/reporter.test.ts +454 -454
- package/src/testing/assertions.ts +986 -986
- package/src/testing/db.ts +157 -157
- package/src/testing/index.ts +9 -3
- package/src/testing/lcov.ts +192 -0
- package/src/testing/mocks.ts +203 -203
- package/src/testing/session.ts +190 -190
- package/src/types/branded.ts +56 -56
- package/src/types/index.ts +1 -1
- package/src/utils/safe-io.ts +188 -188
- package/src/utils/string-safe.ts +298 -298
- package/src/watcher/__tests__/watcher.test.ts +59 -59
- package/src/watcher/watcher.ts +61 -61
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for `packages/core/src/brain/redactor.ts`.
|
|
3
|
-
*
|
|
4
|
-
* Each test asserts BOTH invariants we care about:
|
|
5
|
-
* 1. The secret no longer appears verbatim in the redacted output.
|
|
6
|
-
* 2. A correctly-kinded `RedactionHit` shows up in the audit list.
|
|
7
|
-
*
|
|
8
|
-
* Regression guard — if someone relaxes a pattern to fix a false
|
|
9
|
-
* positive, the matching test here will fail before a key leaks.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, it, expect } from "bun:test";
|
|
13
|
-
import { redactSecrets, redact } from "../redactor";
|
|
14
|
-
|
|
15
|
-
describe("redactSecrets — OpenAI-style keys", () => {
|
|
16
|
-
it("redacts sk-... keys and audits the hit", () => {
|
|
17
|
-
const secret = "sk-proj-ABCDEFGHIJKLMNOPQRSTUVWX";
|
|
18
|
-
const input = `Use key ${secret} to call.`;
|
|
19
|
-
const { redacted, hits } = redactSecrets(input);
|
|
20
|
-
expect(redacted).not.toContain(secret);
|
|
21
|
-
expect(redacted).toContain("[[REDACTED:openai-key]]");
|
|
22
|
-
expect(hits.length).toBeGreaterThanOrEqual(1);
|
|
23
|
-
const sampleContainsFullKey = hits.some((h) => h.sample.includes(secret));
|
|
24
|
-
expect(sampleContainsFullKey).toBe(false);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe("redactSecrets — Bearer tokens", () => {
|
|
29
|
-
it("redacts Authorization: Bearer headers", () => {
|
|
30
|
-
const bearer = "Bearer eyJhbGciOiJIUzI1NiJ9abcdefghij.signature-blob";
|
|
31
|
-
const input = `curl -H 'Authorization: ${bearer}' api/host`;
|
|
32
|
-
const { redacted, hits } = redactSecrets(input);
|
|
33
|
-
expect(redacted).not.toContain(bearer);
|
|
34
|
-
expect(hits.some((h) => h.kind === "bearer-token")).toBe(true);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe("redactSecrets — .env references", () => {
|
|
39
|
-
it("redacts bare .env and .env.production references", () => {
|
|
40
|
-
const input = "Credentials live in .env and overrides in .env.production.";
|
|
41
|
-
const { redacted, hits } = redactSecrets(input);
|
|
42
|
-
expect(redacted).not.toContain(" .env ");
|
|
43
|
-
expect(redacted).not.toContain(".env.production");
|
|
44
|
-
expect(hits.filter((h) => h.kind === "env-ref").length).toBeGreaterThanOrEqual(
|
|
45
|
-
2,
|
|
46
|
-
);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe("redactSecrets — KEY=VALUE assignments", () => {
|
|
51
|
-
it("redacts API_KEY=... assignments in-place", () => {
|
|
52
|
-
const input = `OPENAI_API_KEY=sk-fake1234567890abcdef\nDEBUG=1`;
|
|
53
|
-
const { redacted, hits } = redactSecrets(input);
|
|
54
|
-
// The whole assignment collapses into a single marker.
|
|
55
|
-
expect(redacted).toContain("[[REDACTED:api-key-assignment]]");
|
|
56
|
-
expect(redacted).toContain("DEBUG=1"); // untouched
|
|
57
|
-
expect(hits.some((h) => h.kind === "api-key-assignment")).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe("redactSecrets — multi-match, non-overlapping", () => {
|
|
62
|
-
it("redacts multiple secrets in a single payload", () => {
|
|
63
|
-
const gh = "ghp_1234567890abcdefghijklmnopqrstuvwxyz";
|
|
64
|
-
const aws = "AKIAIOSFODNN7EXAMPLE";
|
|
65
|
-
const input = `GitHub: ${gh}\nAWS: ${aws}\nNothing here.`;
|
|
66
|
-
const { redacted, hits } = redactSecrets(input);
|
|
67
|
-
expect(redacted).not.toContain(gh);
|
|
68
|
-
expect(redacted).not.toContain(aws);
|
|
69
|
-
expect(hits.some((h) => h.kind === "github-token")).toBe(true);
|
|
70
|
-
expect(hits.some((h) => h.kind === "aws-key")).toBe(true);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe("redactSecrets — clean input passthrough", () => {
|
|
75
|
-
it("returns the input unchanged and an empty hit list when nothing matches", () => {
|
|
76
|
-
const input = "No secrets, just a normal message about the weather.";
|
|
77
|
-
const { redacted, hits } = redactSecrets(input);
|
|
78
|
-
expect(redacted).toBe(input);
|
|
79
|
-
expect(hits.length).toBe(0);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe("redact() convenience", () => {
|
|
84
|
-
it("returns the redacted string directly", () => {
|
|
85
|
-
const secret = "sk-proj-THISISAFAKEKEY1234567890";
|
|
86
|
-
const out = redact(`token: ${secret}`);
|
|
87
|
-
expect(out).not.toContain(secret);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("returns the original string when nothing matches", () => {
|
|
91
|
-
const input = "hello world";
|
|
92
|
-
expect(redact(input)).toBe(input);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Tests for `packages/core/src/brain/redactor.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Each test asserts BOTH invariants we care about:
|
|
5
|
+
* 1. The secret no longer appears verbatim in the redacted output.
|
|
6
|
+
* 2. A correctly-kinded `RedactionHit` shows up in the audit list.
|
|
7
|
+
*
|
|
8
|
+
* Regression guard — if someone relaxes a pattern to fix a false
|
|
9
|
+
* positive, the matching test here will fail before a key leaks.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect } from "bun:test";
|
|
13
|
+
import { redactSecrets, redact } from "../redactor";
|
|
14
|
+
|
|
15
|
+
describe("redactSecrets — OpenAI-style keys", () => {
|
|
16
|
+
it("redacts sk-... keys and audits the hit", () => {
|
|
17
|
+
const secret = "sk-proj-ABCDEFGHIJKLMNOPQRSTUVWX";
|
|
18
|
+
const input = `Use key ${secret} to call.`;
|
|
19
|
+
const { redacted, hits } = redactSecrets(input);
|
|
20
|
+
expect(redacted).not.toContain(secret);
|
|
21
|
+
expect(redacted).toContain("[[REDACTED:openai-key]]");
|
|
22
|
+
expect(hits.length).toBeGreaterThanOrEqual(1);
|
|
23
|
+
const sampleContainsFullKey = hits.some((h) => h.sample.includes(secret));
|
|
24
|
+
expect(sampleContainsFullKey).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("redactSecrets — Bearer tokens", () => {
|
|
29
|
+
it("redacts Authorization: Bearer headers", () => {
|
|
30
|
+
const bearer = "Bearer eyJhbGciOiJIUzI1NiJ9abcdefghij.signature-blob";
|
|
31
|
+
const input = `curl -H 'Authorization: ${bearer}' api/host`;
|
|
32
|
+
const { redacted, hits } = redactSecrets(input);
|
|
33
|
+
expect(redacted).not.toContain(bearer);
|
|
34
|
+
expect(hits.some((h) => h.kind === "bearer-token")).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("redactSecrets — .env references", () => {
|
|
39
|
+
it("redacts bare .env and .env.production references", () => {
|
|
40
|
+
const input = "Credentials live in .env and overrides in .env.production.";
|
|
41
|
+
const { redacted, hits } = redactSecrets(input);
|
|
42
|
+
expect(redacted).not.toContain(" .env ");
|
|
43
|
+
expect(redacted).not.toContain(".env.production");
|
|
44
|
+
expect(hits.filter((h) => h.kind === "env-ref").length).toBeGreaterThanOrEqual(
|
|
45
|
+
2,
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("redactSecrets — KEY=VALUE assignments", () => {
|
|
51
|
+
it("redacts API_KEY=... assignments in-place", () => {
|
|
52
|
+
const input = `OPENAI_API_KEY=sk-fake1234567890abcdef\nDEBUG=1`;
|
|
53
|
+
const { redacted, hits } = redactSecrets(input);
|
|
54
|
+
// The whole assignment collapses into a single marker.
|
|
55
|
+
expect(redacted).toContain("[[REDACTED:api-key-assignment]]");
|
|
56
|
+
expect(redacted).toContain("DEBUG=1"); // untouched
|
|
57
|
+
expect(hits.some((h) => h.kind === "api-key-assignment")).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("redactSecrets — multi-match, non-overlapping", () => {
|
|
62
|
+
it("redacts multiple secrets in a single payload", () => {
|
|
63
|
+
const gh = "ghp_1234567890abcdefghijklmnopqrstuvwxyz";
|
|
64
|
+
const aws = "AKIAIOSFODNN7EXAMPLE";
|
|
65
|
+
const input = `GitHub: ${gh}\nAWS: ${aws}\nNothing here.`;
|
|
66
|
+
const { redacted, hits } = redactSecrets(input);
|
|
67
|
+
expect(redacted).not.toContain(gh);
|
|
68
|
+
expect(redacted).not.toContain(aws);
|
|
69
|
+
expect(hits.some((h) => h.kind === "github-token")).toBe(true);
|
|
70
|
+
expect(hits.some((h) => h.kind === "aws-key")).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("redactSecrets — clean input passthrough", () => {
|
|
75
|
+
it("returns the input unchanged and an empty hit list when nothing matches", () => {
|
|
76
|
+
const input = "No secrets, just a normal message about the weather.";
|
|
77
|
+
const { redacted, hits } = redactSecrets(input);
|
|
78
|
+
expect(redacted).toBe(input);
|
|
79
|
+
expect(hits.length).toBe(0);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe("redact() convenience", () => {
|
|
84
|
+
it("returns the redacted string directly", () => {
|
|
85
|
+
const secret = "sk-proj-THISISAFAKEKEY1234567890";
|
|
86
|
+
const out = redact(`token: ${secret}`);
|
|
87
|
+
expect(out).not.toContain(secret);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("returns the original string when nothing matches", () => {
|
|
91
|
+
const input = "hello world";
|
|
92
|
+
expect(redact(input)).toBe(input);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared test fixtures for brain adapter tests.
|
|
3
|
-
*
|
|
4
|
-
* Every helper here stays framework-free so the unit tests do not pull
|
|
5
|
-
* in the real network / keychain / filesystem paths.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import path from "node:path";
|
|
9
|
-
import os from "node:os";
|
|
10
|
-
import {
|
|
11
|
-
CredentialStore,
|
|
12
|
-
type CredentialBackend,
|
|
13
|
-
type StoredToken,
|
|
14
|
-
} from "../../credentials";
|
|
15
|
-
import type { HttpClient, OAuthEndpoints } from "../oauth-flow";
|
|
16
|
-
import { ChatGPTAuth } from "../chatgpt-auth";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* In-memory credential store that satisfies `CredentialBackend`. We
|
|
20
|
-
* construct a regular `CredentialStore` around it so the adapters see
|
|
21
|
-
* the exact public API (.load/.save/.delete/.list/.touch/.backendName).
|
|
22
|
-
*/
|
|
23
|
-
export function makeMemoryStore(
|
|
24
|
-
seed: Record<string, StoredToken> = {},
|
|
25
|
-
): CredentialStore {
|
|
26
|
-
const map = new Map<string, StoredToken>(Object.entries(seed));
|
|
27
|
-
const backend: CredentialBackend = {
|
|
28
|
-
name: "memory",
|
|
29
|
-
async save(provider, token) {
|
|
30
|
-
map.set(provider, token);
|
|
31
|
-
},
|
|
32
|
-
async load(provider) {
|
|
33
|
-
return map.get(provider) ?? null;
|
|
34
|
-
},
|
|
35
|
-
async delete(provider) {
|
|
36
|
-
map.delete(provider);
|
|
37
|
-
},
|
|
38
|
-
async list() {
|
|
39
|
-
return [...map.keys()];
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
return new CredentialStore(backend);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Build a stub `HttpClient` whose behavior is driven by a response
|
|
47
|
-
* factory. The factory receives the URL and RequestInit and returns a
|
|
48
|
-
* `Response`. Tests use this to simulate 401 sequences, token
|
|
49
|
-
* refresh, etc. without spinning up a live server.
|
|
50
|
-
*/
|
|
51
|
-
export function makeStubHttpClient(
|
|
52
|
-
respond: (url: string, init?: RequestInit) => Response | Promise<Response>,
|
|
53
|
-
): HttpClient {
|
|
54
|
-
return async (url, init) => respond(url, init);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const FAKE_ENDPOINTS: OAuthEndpoints = {
|
|
58
|
-
authorizationUrl: "https://example.test/oauth/authorize",
|
|
59
|
-
tokenUrl: "https://example.test/oauth/token",
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export function jsonResponse(body: unknown, status = 200): Response {
|
|
63
|
-
return new Response(JSON.stringify(body), {
|
|
64
|
-
status,
|
|
65
|
-
headers: { "content-type": "application/json" },
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Isolated ChatGPTAuth that always reports no session token — points at
|
|
71
|
-
* a nonexistent path so it never picks up the developer's real
|
|
72
|
-
* `~/.codex/auth.json`. Tests that exercise the keychain path must
|
|
73
|
-
* pass this helper to prevent the ChatGPT code path from short-
|
|
74
|
-
* circuiting the test's intended flow.
|
|
75
|
-
*/
|
|
76
|
-
export function makeEmptyChatGPTAuth(): ChatGPTAuth {
|
|
77
|
-
return new ChatGPTAuth({
|
|
78
|
-
authFilePath: path.join(
|
|
79
|
-
os.tmpdir(),
|
|
80
|
-
`mandu-test-no-auth-${process.pid}-${Date.now()}.json`,
|
|
81
|
-
),
|
|
82
|
-
});
|
|
83
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared test fixtures for brain adapter tests.
|
|
3
|
+
*
|
|
4
|
+
* Every helper here stays framework-free so the unit tests do not pull
|
|
5
|
+
* in the real network / keychain / filesystem paths.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import os from "node:os";
|
|
10
|
+
import {
|
|
11
|
+
CredentialStore,
|
|
12
|
+
type CredentialBackend,
|
|
13
|
+
type StoredToken,
|
|
14
|
+
} from "../../credentials";
|
|
15
|
+
import type { HttpClient, OAuthEndpoints } from "../oauth-flow";
|
|
16
|
+
import { ChatGPTAuth } from "../chatgpt-auth";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* In-memory credential store that satisfies `CredentialBackend`. We
|
|
20
|
+
* construct a regular `CredentialStore` around it so the adapters see
|
|
21
|
+
* the exact public API (.load/.save/.delete/.list/.touch/.backendName).
|
|
22
|
+
*/
|
|
23
|
+
export function makeMemoryStore(
|
|
24
|
+
seed: Record<string, StoredToken> = {},
|
|
25
|
+
): CredentialStore {
|
|
26
|
+
const map = new Map<string, StoredToken>(Object.entries(seed));
|
|
27
|
+
const backend: CredentialBackend = {
|
|
28
|
+
name: "memory",
|
|
29
|
+
async save(provider, token) {
|
|
30
|
+
map.set(provider, token);
|
|
31
|
+
},
|
|
32
|
+
async load(provider) {
|
|
33
|
+
return map.get(provider) ?? null;
|
|
34
|
+
},
|
|
35
|
+
async delete(provider) {
|
|
36
|
+
map.delete(provider);
|
|
37
|
+
},
|
|
38
|
+
async list() {
|
|
39
|
+
return [...map.keys()];
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return new CredentialStore(backend);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Build a stub `HttpClient` whose behavior is driven by a response
|
|
47
|
+
* factory. The factory receives the URL and RequestInit and returns a
|
|
48
|
+
* `Response`. Tests use this to simulate 401 sequences, token
|
|
49
|
+
* refresh, etc. without spinning up a live server.
|
|
50
|
+
*/
|
|
51
|
+
export function makeStubHttpClient(
|
|
52
|
+
respond: (url: string, init?: RequestInit) => Response | Promise<Response>,
|
|
53
|
+
): HttpClient {
|
|
54
|
+
return async (url, init) => respond(url, init);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const FAKE_ENDPOINTS: OAuthEndpoints = {
|
|
58
|
+
authorizationUrl: "https://example.test/oauth/authorize",
|
|
59
|
+
tokenUrl: "https://example.test/oauth/token",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export function jsonResponse(body: unknown, status = 200): Response {
|
|
63
|
+
return new Response(JSON.stringify(body), {
|
|
64
|
+
status,
|
|
65
|
+
headers: { "content-type": "application/json" },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Isolated ChatGPTAuth that always reports no session token — points at
|
|
71
|
+
* a nonexistent path so it never picks up the developer's real
|
|
72
|
+
* `~/.codex/auth.json`. Tests that exercise the keychain path must
|
|
73
|
+
* pass this helper to prevent the ChatGPT code path from short-
|
|
74
|
+
* circuiting the test's intended flow.
|
|
75
|
+
*/
|
|
76
|
+
export function makeEmptyChatGPTAuth(): ChatGPTAuth {
|
|
77
|
+
return new ChatGPTAuth({
|
|
78
|
+
authFilePath: path.join(
|
|
79
|
+
os.tmpdir(),
|
|
80
|
+
`mandu-test-no-auth-${process.pid}-${Date.now()}.json`,
|
|
81
|
+
),
|
|
82
|
+
});
|
|
83
|
+
}
|