@rebasepro/server 0.13.0 → 0.13.1-canary.g06dbe5b

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.
Files changed (125) hide show
  1. package/dist/{admin_block-CcSGdH7M.js → admin_block-H86dCPsj.js} +62 -2
  2. package/dist/admin_block-H86dCPsj.js.map +1 -0
  3. package/dist/api/ast-schema-editor.d.ts +74 -6
  4. package/dist/api/errors.d.ts +0 -6
  5. package/dist/api/openapi-generator.d.ts +14 -0
  6. package/dist/api/rest/api-generator.d.ts +1 -1
  7. package/dist/api/rest/idempotency.d.ts +62 -4
  8. package/dist/api/rest/query-parser.d.ts +15 -1
  9. package/dist/api/rest/write-validation.d.ts +52 -9
  10. package/dist/auth/adapter-middleware.d.ts +3 -1
  11. package/dist/auth/apple-oauth.d.ts +16 -11
  12. package/dist/auth/bitbucket-oauth.d.ts +2 -4
  13. package/dist/auth/builtin-auth-adapter.d.ts +2 -0
  14. package/dist/auth/discord-oauth.d.ts +5 -6
  15. package/dist/auth/facebook-oauth.d.ts +2 -4
  16. package/dist/auth/github-oauth.d.ts +2 -4
  17. package/dist/auth/gitlab-oauth.d.ts +6 -4
  18. package/dist/auth/google-oauth.d.ts +1 -0
  19. package/dist/auth/index.d.ts +8 -1
  20. package/dist/auth/interfaces.d.ts +68 -1
  21. package/dist/auth/jwt.d.ts +40 -0
  22. package/dist/auth/linkedin-oauth.d.ts +2 -4
  23. package/dist/auth/mfa-gate.d.ts +42 -0
  24. package/dist/auth/mfa-routes.d.ts +26 -1
  25. package/dist/auth/mfa.d.ts +16 -0
  26. package/dist/auth/microsoft-oauth.d.ts +19 -4
  27. package/dist/auth/oauth-code-flow.d.ts +66 -0
  28. package/dist/auth/oauth-signin-policy.d.ts +61 -0
  29. package/dist/auth/oidc-id-token.d.ts +61 -0
  30. package/dist/auth/rate-limiter.d.ts +37 -2
  31. package/dist/auth/rls-scope.d.ts +25 -0
  32. package/dist/auth/routes.d.ts +8 -0
  33. package/dist/auth/slack-oauth.d.ts +2 -4
  34. package/dist/auth/spotify-oauth.d.ts +2 -4
  35. package/dist/auth/twitter-oauth.d.ts +2 -5
  36. package/dist/{auth-CuC9M2x6.js → auth-DkAHqvf5.js} +1604 -391
  37. package/dist/auth-DkAHqvf5.js.map +1 -0
  38. package/dist/{backup-CVggVhR2.js → backup-DLluVyuA.js} +2 -2
  39. package/dist/{backup-CVggVhR2.js.map → backup-DLluVyuA.js.map} +1 -1
  40. package/dist/boot/boot.d.ts +19 -0
  41. package/dist/boot/ddl-bootstrap.d.ts +70 -0
  42. package/dist/{contract-routes-Dj8i5AiM.js → contract-routes-BB1U05sS.js} +3 -3
  43. package/dist/{contract-routes-Dj8i5AiM.js.map → contract-routes-BB1U05sS.js.map} +1 -1
  44. package/dist/cron/cron-scheduler.d.ts +8 -3
  45. package/dist/cron/define-cron.d.ts +17 -3
  46. package/dist/{cron-loader-B1S2MCSl.js → cron-loader-3U5aGILy.js} +2 -2
  47. package/dist/{cron-loader-B1S2MCSl.js.map → cron-loader-3U5aGILy.js.map} +1 -1
  48. package/dist/{cron-routes-CrQ0tK-_.js → cron-routes-rZgwlOz4.js} +2 -2
  49. package/dist/{cron-routes-CrQ0tK-_.js.map → cron-routes-rZgwlOz4.js.map} +1 -1
  50. package/dist/{cron-scheduler-B3RFt0HS.js → cron-scheduler-FJAaCAXm.js} +30 -5
  51. package/dist/cron-scheduler-FJAaCAXm.js.map +1 -0
  52. package/dist/{cron-store-BywZsyfZ.js → cron-store-9NmUDfzL.js} +66 -47
  53. package/dist/cron-store-9NmUDfzL.js.map +1 -0
  54. package/dist/ddl-bootstrap-BhXbTnBl.js +183 -0
  55. package/dist/ddl-bootstrap-BhXbTnBl.js.map +1 -0
  56. package/dist/email/html.d.ts +54 -0
  57. package/dist/email/index.d.ts +3 -0
  58. package/dist/email/link-base.d.ts +39 -0
  59. package/dist/email/smtp-email-service.d.ts +7 -1
  60. package/dist/email/templates.d.ts +9 -1
  61. package/dist/email/types.d.ts +11 -1
  62. package/dist/{errors-CgkCzoj7.js → errors-B1WZEdsK.js} +3 -11
  63. package/dist/errors-B1WZEdsK.js.map +1 -0
  64. package/dist/function-loader-D1SwtCa5.js +139 -0
  65. package/dist/function-loader-D1SwtCa5.js.map +1 -0
  66. package/dist/{function-routes-C0cLIy3N.js → function-routes-Btcez1T-.js} +18 -6
  67. package/dist/function-routes-Btcez1T-.js.map +1 -0
  68. package/dist/functions/define-function.d.ts +25 -6
  69. package/dist/functions/function-loader.d.ts +23 -0
  70. package/dist/functions/function-routes.d.ts +7 -1
  71. package/dist/functions/request-timeout.d.ts +34 -0
  72. package/dist/history/history-routes.d.ts +6 -0
  73. package/dist/index.d.ts +2 -1
  74. package/dist/index.es.js +1960 -794
  75. package/dist/index.es.js.map +1 -1
  76. package/dist/init/docs.d.ts +10 -1
  77. package/dist/init/process-safety.d.ts +25 -0
  78. package/dist/init.d.ts +27 -0
  79. package/dist/{jwt-DD6EtpGj.js → jwt-Cuq6MwNy.js} +70 -8
  80. package/dist/jwt-Cuq6MwNy.js.map +1 -0
  81. package/dist/logger-DfvF_8r-.js +190 -0
  82. package/dist/logger-DfvF_8r-.js.map +1 -0
  83. package/dist/openapi-generator-BQxxxDpb.js +865 -0
  84. package/dist/openapi-generator-BQxxxDpb.js.map +1 -0
  85. package/dist/request-timeout-RivJsME0.js +65 -0
  86. package/dist/request-timeout-RivJsME0.js.map +1 -0
  87. package/dist/schema-editor-routes-DZFKGXgq.js +437 -0
  88. package/dist/schema-editor-routes-DZFKGXgq.js.map +1 -0
  89. package/dist/serve-spa.d.ts +5 -4
  90. package/dist/services/outbound-url-guard.d.ts +53 -0
  91. package/dist/services/routed-realtime-service.d.ts +10 -2
  92. package/dist/services/webhook-service.d.ts +76 -1
  93. package/dist/singleton.d.ts +25 -8
  94. package/dist/{src-Cum9kox5.js → src-By48Ffg0.js} +322 -70
  95. package/dist/src-By48Ffg0.js.map +1 -0
  96. package/dist/{src-_qQ3RNCK.js → src-Ca6NhxKs.js} +79 -2
  97. package/dist/src-Ca6NhxKs.js.map +1 -0
  98. package/dist/storage/LocalStorageController.d.ts +12 -1
  99. package/dist/storage/image-transform.d.ts +57 -0
  100. package/dist/storage/keys.d.ts +98 -0
  101. package/dist/storage/routes.d.ts +11 -0
  102. package/dist/storage/tus-handler.d.ts +7 -1
  103. package/dist/utils/logger.d.ts +18 -0
  104. package/dist/utils/logging.d.ts +0 -4
  105. package/dist/utils/sql.d.ts +11 -6
  106. package/package.json +7 -6
  107. package/dist/admin_block-CcSGdH7M.js.map +0 -1
  108. package/dist/auth-CuC9M2x6.js.map +0 -1
  109. package/dist/backend-CIxN4FVm.js +0 -15
  110. package/dist/backend-CIxN4FVm.js.map +0 -1
  111. package/dist/cron-scheduler-B3RFt0HS.js.map +0 -1
  112. package/dist/cron-store-BywZsyfZ.js.map +0 -1
  113. package/dist/errors-CgkCzoj7.js.map +0 -1
  114. package/dist/function-loader-B_1fYfUY.js +0 -86
  115. package/dist/function-loader-B_1fYfUY.js.map +0 -1
  116. package/dist/function-routes-C0cLIy3N.js.map +0 -1
  117. package/dist/jwt-DD6EtpGj.js.map +0 -1
  118. package/dist/logger-BYU66ENZ.js +0 -94
  119. package/dist/logger-BYU66ENZ.js.map +0 -1
  120. package/dist/openapi-generator-BEwyiaAr.js +0 -597
  121. package/dist/openapi-generator-BEwyiaAr.js.map +0 -1
  122. package/dist/schema-editor-routes-CbF20Mf1.js +0 -248
  123. package/dist/schema-editor-routes-CbF20Mf1.js.map +0 -1
  124. package/dist/src-Cum9kox5.js.map +0 -1
  125. package/dist/src-_qQ3RNCK.js.map +0 -1
@@ -0,0 +1,190 @@
1
+ import { createRequire as __createRequire } from "module";
2
+ import process from "process";
3
+ __createRequire(import.meta.url);
4
+ //#region src/utils/logger.ts
5
+ /** Google Cloud Logging severity strings. */
6
+ var GCP_SEVERITY = {
7
+ debug: "DEBUG",
8
+ info: "INFO",
9
+ warn: "WARNING",
10
+ error: "ERROR"
11
+ };
12
+ var LOG_PRIORITY = {
13
+ debug: 0,
14
+ info: 1,
15
+ warn: 2,
16
+ error: 3
17
+ };
18
+ function isProduction() {
19
+ return process.env.NODE_ENV === "production";
20
+ }
21
+ function getMinLevel() {
22
+ const env = (process.env.LOG_LEVEL || "info").toLowerCase();
23
+ if (env in LOG_PRIORITY) return env;
24
+ return "info";
25
+ }
26
+ var FAILED_QUERY_MARKER = "Failed query:";
27
+ var REDACTED_QUERY = "Failed query: [redacted]";
28
+ var REDACTED_VALUE = "[redacted]";
29
+ /**
30
+ * Key fragments whose values are never safe to publish. Compared against the
31
+ * key with separators and case removed, so `api_key`, `apiKey` and `API-KEY`
32
+ * all match `apikey`.
33
+ */
34
+ var SENSITIVE_KEY_FRAGMENTS = [
35
+ "password",
36
+ "passwd",
37
+ "passphrase",
38
+ "secret",
39
+ "token",
40
+ "apikey",
41
+ "authorization",
42
+ "credential",
43
+ "cookie",
44
+ "privatekey",
45
+ "sessionid"
46
+ ];
47
+ /** Longest structure the redactor will walk before giving up. */
48
+ var MAX_REDACT_DEPTH = 8;
49
+ function isSensitiveKey(key) {
50
+ const normalised = key.toLowerCase().replace(/[^a-z0-9]/g, "");
51
+ return SENSITIVE_KEY_FRAGMENTS.some((fragment) => normalised.includes(fragment));
52
+ }
53
+ /**
54
+ * Local escape hatch for the `Failed query:` strip only — the statement is the
55
+ * fastest way to diagnose a failing query on a developer machine. Ignored in
56
+ * production, so a runtime that inherits the variable cannot leak because of
57
+ * it, and it never re-enables the key deny-list.
58
+ */
59
+ function rawQueriesAllowed() {
60
+ return process.env.NODE_ENV !== "production" && process.env.REBASE_LOG_RAW_QUERIES === "true";
61
+ }
62
+ /**
63
+ * Strip every `Failed query: … / params: …` span out of a message or stack,
64
+ * keeping the surrounding text (including stack frames, which carry no user
65
+ * data). When no `params:` line follows the marker the rest of the string is
66
+ * dropped: a statement of unknown extent is treated as sensitive rather than
67
+ * guessed at.
68
+ *
69
+ * Idempotent, and it has to be: an already-redacted span still starts with the
70
+ * marker but has no `params:` line, so a second pass over it would fall into
71
+ * the drop-the-rest branch and eat the stack frames behind it. Redaction runs
72
+ * more than once on the same string in practice — the cron scheduler redacts
73
+ * before persisting and then logs the result.
74
+ */
75
+ function redactSensitiveText(text) {
76
+ if (!text.includes(FAILED_QUERY_MARKER) || rawQueriesAllowed()) return text;
77
+ let out = text;
78
+ let idx = out.indexOf(FAILED_QUERY_MARKER);
79
+ while (idx !== -1) {
80
+ if (out.startsWith(REDACTED_QUERY, idx)) {
81
+ idx = out.indexOf(FAILED_QUERY_MARKER, idx + 24);
82
+ continue;
83
+ }
84
+ const paramsIdx = out.indexOf("\nparams:", idx);
85
+ let end;
86
+ if (paramsIdx === -1) end = out.length;
87
+ else {
88
+ const eol = out.indexOf("\n", paramsIdx + 1);
89
+ end = eol === -1 ? out.length : eol;
90
+ }
91
+ out = out.slice(0, idx) + REDACTED_QUERY + out.slice(end);
92
+ idx = out.indexOf(FAILED_QUERY_MARKER, idx + 24);
93
+ }
94
+ return out;
95
+ }
96
+ /**
97
+ * Serialise an Error into a plain object (stack + message), with the query
98
+ * text redacted out of both. `query`/`params` own-properties — which
99
+ * `DrizzleQueryError` carries beside the message — are deliberately not
100
+ * copied.
101
+ * Handles non-Error values gracefully.
102
+ */
103
+ function serialiseError(value) {
104
+ if (value instanceof Error) return {
105
+ name: value.name,
106
+ message: redactSensitiveText(value.message),
107
+ stack: value.stack ? redactSensitiveText(value.stack) : void 0
108
+ };
109
+ return { value: redactSensitiveText(String(value)) };
110
+ }
111
+ /**
112
+ * Redact one logged value: errors are serialised, strings are stripped of
113
+ * query text, objects and arrays are walked. Cycles and over-deep structures
114
+ * collapse to a marker rather than throwing — a logger that can fail is worse
115
+ * than one that logs less. (An object referenced twice in one payload is
116
+ * reported as `[circular]` the second time; bounding the walk matters more
117
+ * than rendering a shared reference twice.)
118
+ */
119
+ function redactValue(value, depth, seen) {
120
+ if (value instanceof Error) return serialiseError(value);
121
+ if (typeof value === "string") return redactSensitiveText(value);
122
+ if (value === null || typeof value !== "object") return value;
123
+ if (depth >= MAX_REDACT_DEPTH) return "[truncated]";
124
+ if (seen.has(value)) return "[circular]";
125
+ seen.add(value);
126
+ if (Array.isArray(value)) return value.map((item) => redactValue(item, depth + 1, seen));
127
+ if (value instanceof Date) return value;
128
+ const out = {};
129
+ for (const [key, val] of Object.entries(value)) out[key] = isSensitiveKey(key) ? REDACTED_VALUE : redactValue(val, depth + 1, seen);
130
+ return out;
131
+ }
132
+ function formatData(data) {
133
+ if (!data) return void 0;
134
+ const seen = /* @__PURE__ */ new WeakSet();
135
+ const out = {};
136
+ for (const [key, val] of Object.entries(data)) out[key] = isSensitiveKey(key) ? REDACTED_VALUE : redactValue(val, 0, seen);
137
+ return out;
138
+ }
139
+ function createLogger(rawDefaultFields = {}) {
140
+ const minLevel = getMinLevel();
141
+ const defaultFields = formatData(rawDefaultFields) ?? {};
142
+ function emit(level, message, data) {
143
+ if (LOG_PRIORITY[level] < LOG_PRIORITY[minLevel]) return;
144
+ const safeMessage = redactSensitiveText(message);
145
+ const merged = {
146
+ ...defaultFields,
147
+ ...formatData(data)
148
+ };
149
+ if (isProduction()) {
150
+ const entry = {
151
+ severity: GCP_SEVERITY[level],
152
+ message: safeMessage,
153
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
154
+ ...merged
155
+ };
156
+ const line = JSON.stringify(entry);
157
+ if (level === "error") process.stderr.write(line + "\n");
158
+ else process.stdout.write(line + "\n");
159
+ } else {
160
+ const prefix = level === "error" ? "❌" : level === "warn" ? "⚠️" : level === "info" ? "ℹ️" : "🐛";
161
+ const extra = Object.keys(merged).length > 0 ? ` ${JSON.stringify(merged)}` : "";
162
+ const out = `${prefix} [${level.toUpperCase()}] ${safeMessage}${extra}`;
163
+ if (level === "error") console.error(out);
164
+ else if (level === "warn") console.warn(out);
165
+ else console.log(out);
166
+ }
167
+ }
168
+ return {
169
+ debug: (msg, data) => emit("debug", msg, data),
170
+ info: (msg, data) => emit("info", msg, data),
171
+ warn: (msg, data) => emit("warn", msg, data),
172
+ error: (msg, data) => emit("error", msg, data),
173
+ child(fields) {
174
+ return createLogger({
175
+ ...defaultFields,
176
+ ...fields
177
+ });
178
+ }
179
+ };
180
+ }
181
+ /**
182
+ * Singleton logger instance.
183
+ * In production: emits JSON lines with `severity`, `message`, `timestamp`.
184
+ * In development: emits human-readable prefixed lines.
185
+ */
186
+ var logger = createLogger();
187
+ //#endregion
188
+ export { redactSensitiveText as n, logger as t };
189
+
190
+ //# sourceMappingURL=logger-DfvF_8r-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-DfvF_8r-.js","names":[],"sources":["../src/utils/logger.ts"],"sourcesContent":["/**\n * Structured Logger for Rebase Backend\n *\n * Outputs JSON lines when `NODE_ENV=production`, human-readable prefixed\n * lines otherwise. Designed to work with Google Cloud Logging severity levels.\n *\n * Every line — message and data, at any depth — passes through the redaction\n * below, which strips Drizzle's `Failed query: … / params: …` wrapper and the\n * values of secret-looking keys. See the block above `serialiseError`.\n *\n * Usage:\n * import { logger } from \"./utils/logger\";\n * logger.info(\"Server started\", { port: 3001 });\n * logger.error(\"Request failed\", { path: \"/api/test\", error: err });\n */\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** Google Cloud Logging severity strings. */\nconst GCP_SEVERITY: Record<LogLevel, string> = {\n debug: \"DEBUG\",\n info: \"INFO\",\n warn: \"WARNING\",\n error: \"ERROR\"\n};\n\nconst LOG_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3\n};\n\nexport interface LogEntry {\n severity: string;\n message: string;\n timestamp: string;\n [key: string]: unknown;\n}\n\nexport interface Logger {\n debug(message: string, data?: Record<string, unknown>): void;\n info(message: string, data?: Record<string, unknown>): void;\n warn(message: string, data?: Record<string, unknown>): void;\n error(message: string, data?: Record<string, unknown>): void;\n child(defaultFields: Record<string, unknown>): Logger;\n}\n\nfunction isProduction(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction getMinLevel(): LogLevel {\n const env = (process.env.LOG_LEVEL || \"info\").toLowerCase();\n if (env in LOG_PRIORITY) return env as LogLevel;\n return \"info\";\n}\n\n// ── Redaction ───────────────────────────────────────────────────────\n//\n// Drizzle builds every query failure as\n// `Failed query: ${query}\\nparams: ${params}` (drizzle-orm/errors.js), so the\n// statement *and* every bound value ride along in `.message` and `.stack` of\n// whatever a driver rethrows — an email and a bcrypt hash reach stdout the\n// moment a registration hits a unique violation. The redaction lives here, in\n// the one function every log line passes through, rather than at the ~124\n// `{ error: … }` call sites: a per-site rule is what produced the leak (one\n// file suppressed the stack, four others did not), and the next caller would\n// reintroduce it. Nothing above this line needs to know about it.\n\nconst FAILED_QUERY_MARKER = \"Failed query:\";\nconst REDACTED_QUERY = \"Failed query: [redacted]\";\nconst REDACTED_VALUE = \"[redacted]\";\n\n/**\n * Key fragments whose values are never safe to publish. Compared against the\n * key with separators and case removed, so `api_key`, `apiKey` and `API-KEY`\n * all match `apikey`.\n */\nconst SENSITIVE_KEY_FRAGMENTS = [\n \"password\",\n \"passwd\",\n \"passphrase\",\n \"secret\",\n \"token\",\n \"apikey\",\n \"authorization\",\n \"credential\",\n \"cookie\",\n \"privatekey\",\n \"sessionid\"\n];\n\n/** Longest structure the redactor will walk before giving up. */\nconst MAX_REDACT_DEPTH = 8;\n\nfunction isSensitiveKey(key: string): boolean {\n const normalised = key.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n return SENSITIVE_KEY_FRAGMENTS.some(fragment => normalised.includes(fragment));\n}\n\n/**\n * Local escape hatch for the `Failed query:` strip only — the statement is the\n * fastest way to diagnose a failing query on a developer machine. Ignored in\n * production, so a runtime that inherits the variable cannot leak because of\n * it, and it never re-enables the key deny-list.\n */\nfunction rawQueriesAllowed(): boolean {\n return process.env.NODE_ENV !== \"production\"\n && process.env.REBASE_LOG_RAW_QUERIES === \"true\";\n}\n\n/**\n * Strip every `Failed query: … / params: …` span out of a message or stack,\n * keeping the surrounding text (including stack frames, which carry no user\n * data). When no `params:` line follows the marker the rest of the string is\n * dropped: a statement of unknown extent is treated as sensitive rather than\n * guessed at.\n *\n * Idempotent, and it has to be: an already-redacted span still starts with the\n * marker but has no `params:` line, so a second pass over it would fall into\n * the drop-the-rest branch and eat the stack frames behind it. Redaction runs\n * more than once on the same string in practice — the cron scheduler redacts\n * before persisting and then logs the result.\n */\nexport function redactSensitiveText(text: string): string {\n if (!text.includes(FAILED_QUERY_MARKER) || rawQueriesAllowed()) return text;\n\n let out = text;\n let idx = out.indexOf(FAILED_QUERY_MARKER);\n while (idx !== -1) {\n if (out.startsWith(REDACTED_QUERY, idx)) {\n idx = out.indexOf(FAILED_QUERY_MARKER, idx + REDACTED_QUERY.length);\n continue;\n }\n const paramsIdx = out.indexOf(\"\\nparams:\", idx);\n let end: number;\n if (paramsIdx === -1) {\n end = out.length;\n } else {\n const eol = out.indexOf(\"\\n\", paramsIdx + 1);\n end = eol === -1 ? out.length : eol;\n }\n out = out.slice(0, idx) + REDACTED_QUERY + out.slice(end);\n idx = out.indexOf(FAILED_QUERY_MARKER, idx + REDACTED_QUERY.length);\n }\n return out;\n}\n\n/**\n * Serialise an Error into a plain object (stack + message), with the query\n * text redacted out of both. `query`/`params` own-properties — which\n * `DrizzleQueryError` carries beside the message — are deliberately not\n * copied.\n * Handles non-Error values gracefully.\n */\nfunction serialiseError(value: unknown): Record<string, unknown> {\n if (value instanceof Error) {\n return {\n name: value.name,\n message: redactSensitiveText(value.message),\n stack: value.stack ? redactSensitiveText(value.stack) : undefined\n };\n }\n return { value: redactSensitiveText(String(value)) };\n}\n\n/**\n * Redact one logged value: errors are serialised, strings are stripped of\n * query text, objects and arrays are walked. Cycles and over-deep structures\n * collapse to a marker rather than throwing — a logger that can fail is worse\n * than one that logs less. (An object referenced twice in one payload is\n * reported as `[circular]` the second time; bounding the walk matters more\n * than rendering a shared reference twice.)\n */\nfunction redactValue(value: unknown, depth: number, seen: WeakSet<object>): unknown {\n // `serialiseError` returns only already-redacted strings, so it is the\n // terminal step — walking its output again would redact twice.\n if (value instanceof Error) return serialiseError(value);\n if (typeof value === \"string\") return redactSensitiveText(value);\n if (value === null || typeof value !== \"object\") return value;\n if (depth >= MAX_REDACT_DEPTH) return \"[truncated]\";\n if (seen.has(value)) return \"[circular]\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value.map(item => redactValue(item, depth + 1, seen));\n }\n if (value instanceof Date) return value;\n\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSensitiveKey(key) ? REDACTED_VALUE : redactValue(val, depth + 1, seen);\n }\n return out;\n}\n\nfunction formatData(data?: Record<string, unknown>): Record<string, unknown> | undefined {\n if (!data) return undefined;\n const seen = new WeakSet<object>();\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(data)) {\n out[key] = isSensitiveKey(key) ? REDACTED_VALUE : redactValue(val, 0, seen);\n }\n return out;\n}\n\nfunction createLogger(rawDefaultFields: Record<string, unknown> = {}): Logger {\n const minLevel = getMinLevel();\n // Child fields go through the same pass as per-call data — they are merged\n // into every line this logger emits, so leaving them raw would be a hole\n // the moment `child()` gets its first caller.\n const defaultFields = formatData(rawDefaultFields) ?? {};\n\n function emit(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (LOG_PRIORITY[level] < LOG_PRIORITY[minLevel]) return;\n\n // The message is redacted too, not just the data: several call sites\n // interpolate `error.message` straight into the line they log.\n const safeMessage = redactSensitiveText(message);\n const merged = { ...defaultFields,\n...formatData(data) };\n\n if (isProduction()) {\n // Structured JSON for Cloud Logging\n const entry: LogEntry = {\n severity: GCP_SEVERITY[level],\n message: safeMessage,\n timestamp: new Date().toISOString(),\n ...merged\n };\n const line = JSON.stringify(entry);\n\n if (level === \"error\") {\n process.stderr.write(line + \"\\n\");\n } else {\n process.stdout.write(line + \"\\n\");\n }\n } else {\n // Human-readable for development\n const prefix = level === \"error\" ? \"❌\"\n : level === \"warn\" ? \"⚠️\"\n : level === \"info\" ? \"ℹ️\"\n : \"🐛\";\n const extra = Object.keys(merged).length > 0 ? ` ${JSON.stringify(merged)}` : \"\";\n const out = `${prefix} [${level.toUpperCase()}] ${safeMessage}${extra}`;\n\n if (level === \"error\") {\n console.error(out);\n } else if (level === \"warn\") {\n console.warn(out);\n } else {\n console.log(out);\n }\n }\n }\n\n return {\n debug: (msg, data) => emit(\"debug\", msg, data),\n info: (msg, data) => emit(\"info\", msg, data),\n warn: (msg, data) => emit(\"warn\", msg, data),\n error: (msg, data) => emit(\"error\", msg, data),\n child(fields: Record<string, unknown>): Logger {\n return createLogger({ ...defaultFields,\n...fields });\n }\n };\n}\n\n/**\n * Singleton logger instance.\n * In production: emits JSON lines with `severity`, `message`, `timestamp`.\n * In development: emits human-readable prefixed lines.\n */\nexport const logger: Logger = createLogger();\n"],"mappings":"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"}