@zintrust/core 0.4.77 → 0.4.79

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.4.77",
3
+ "version": "0.4.79",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -15,11 +15,13 @@ type EnsureWranglerConfigOptions<TValues, TOptions> = {
15
15
  type EnsureWranglerConfigResult<TValues> = {
16
16
  createdFile: boolean;
17
17
  insertedEnv: boolean;
18
+ content: string;
18
19
  values: TValues;
19
20
  };
20
21
  export declare const trimNonEmptyOption: (value: string | undefined) => string | undefined;
21
22
  export declare const resolveConfigPath: (raw: string | undefined, fallback?: string) => string;
22
23
  export declare const findQuotedValue: (content: string, key: string) => string | undefined;
24
+ export declare const renderProxyWranglerDevConfig: (content: string, envName: string) => string | undefined;
23
25
  export declare const injectEnvBlock: (content: string, envName: string, block: string) => string;
24
26
  export declare const renderDefaultWranglerConfig: (envBlock: string, compatibilityDate: string) => string;
25
27
  export declare const ensureProxyEntrypoint: (options: EnsureProxyEntrypointOptions) => {
@@ -1 +1 @@
1
- {"version":3,"file":"ProxyScaffoldUtils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ProxyScaffoldUtils.ts"],"names":[],"mappings":"AAKA,KAAK,4BAA4B,GAAG;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,KAAK,2BAA2B,CAAC,OAAO,EAAE,QAAQ,IAAI;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,QAAQ,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC3E,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IAC5C,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,KAAK,0BAA0B,CAAC,OAAO,IAAI;IACzC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAIvE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,GAAG,SAAS,EAAE,iBAA2B,KAAG,MAExF,CAAC;AAmBF,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,GAAG,SAQvE,CAAC;AAmBF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,MAAM,KAAG,MAuBhF,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,MAAM,EAChB,mBAAmB,MAAM,KACxB,MAaF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,4BAA4B,KACpC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAmB3C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,EAAE,QAAQ,EACpD,SAAS,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,KACtD,0BAA0B,CAAC,OAAO,CAqBpC,CAAC"}
1
+ {"version":3,"file":"ProxyScaffoldUtils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ProxyScaffoldUtils.ts"],"names":[],"mappings":"AAKA,KAAK,4BAA4B,GAAG;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,KAAK,2BAA2B,CAAC,OAAO,EAAE,QAAQ,IAAI;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,QAAQ,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC3E,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IAC5C,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,KAAK,0BAA0B,CAAC,OAAO,IAAI;IACzC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAIvE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,GAAG,SAAS,EAAE,iBAA2B,KAAG,MAExF,CAAC;AAmBF,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,GAAG,SAQvE,CAAC;AAwKF,eAAO,MAAM,4BAA4B,GACvC,SAAS,MAAM,EACf,SAAS,MAAM,KACd,MAAM,GAAG,SAgBX,CAAC;AAQF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,MAAM,KAAG,MAuBhF,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,MAAM,EAChB,mBAAmB,MAAM,KACxB,MAaF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,SAAS,4BAA4B,KACpC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAmB3C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,EAAE,QAAQ,EACpD,SAAS,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,KACtD,0BAA0B,CAAC,OAAO,CAqBpC,CAAC"}
@@ -47,6 +47,148 @@ const findEnvObjectStart = (content) => {
47
47
  return -1;
48
48
  return valueStart;
49
49
  };
50
+ const createJsonScanState = () => ({
51
+ inString: false,
52
+ isEscaped: false,
53
+ inLineComment: false,
54
+ inBlockComment: false,
55
+ });
56
+ const advanceWithinLineComment = (state, current) => {
57
+ if (!state.inLineComment)
58
+ return 0;
59
+ if (current === '\n')
60
+ state.inLineComment = false;
61
+ return 1;
62
+ };
63
+ const advanceWithinBlockComment = (state, current, next) => {
64
+ if (!state.inBlockComment)
65
+ return 0;
66
+ if (current === '*' && next === '/') {
67
+ state.inBlockComment = false;
68
+ return 2;
69
+ }
70
+ return 1;
71
+ };
72
+ const advanceWithinString = (state, current) => {
73
+ if (!state.inString)
74
+ return 0;
75
+ if (state.isEscaped) {
76
+ state.isEscaped = false;
77
+ }
78
+ else if (current === '\\') {
79
+ state.isEscaped = true;
80
+ }
81
+ else if (current === '"') {
82
+ state.inString = false;
83
+ }
84
+ return 1;
85
+ };
86
+ const startJsonScanContext = (state, current, next) => {
87
+ if (current === '/' && next === '/') {
88
+ state.inLineComment = true;
89
+ return 2;
90
+ }
91
+ if (current === '/' && next === '*') {
92
+ state.inBlockComment = true;
93
+ return 2;
94
+ }
95
+ if (current === '"') {
96
+ state.inString = true;
97
+ return 1;
98
+ }
99
+ return 0;
100
+ };
101
+ const advanceJsonScanState = (state, current, next) => {
102
+ return (advanceWithinLineComment(state, current) ||
103
+ advanceWithinBlockComment(state, current, next) ||
104
+ advanceWithinString(state, current) ||
105
+ startJsonScanContext(state, current, next));
106
+ };
107
+ const rewriteRelativeWranglerPaths = (content) => {
108
+ return content.replaceAll('": "./', '": "../../');
109
+ };
110
+ const findQuotedKeyFrom = (content, key, startIndex) => {
111
+ let cursor = Math.max(0, startIndex);
112
+ const state = createJsonScanState();
113
+ const candidate = `"${key}"`;
114
+ while (cursor < content.length) {
115
+ const current = content[cursor];
116
+ const next = content[cursor + 1];
117
+ if (!state.inString && !state.inLineComment && !state.inBlockComment) {
118
+ if (content.startsWith(candidate, cursor))
119
+ return cursor;
120
+ }
121
+ const advanced = advanceJsonScanState(state, current, next);
122
+ cursor += advanced > 0 ? advanced : 1;
123
+ }
124
+ return -1;
125
+ };
126
+ const findJsonKeyValueStartFrom = (content, key, startIndex) => {
127
+ const keyPosition = findQuotedKeyFrom(content, key, startIndex);
128
+ if (keyPosition < 0)
129
+ return -1;
130
+ let cursor = keyPosition + key.length + 2;
131
+ while (isJsonWhitespace(content[cursor]))
132
+ cursor += 1;
133
+ if (content[cursor] !== ':')
134
+ return -1;
135
+ cursor += 1;
136
+ while (isJsonWhitespace(content[cursor]))
137
+ cursor += 1;
138
+ return cursor;
139
+ };
140
+ const findMatchingObjectBrace = (content, objectStart) => {
141
+ let depth = 0;
142
+ const state = createJsonScanState();
143
+ for (let index = objectStart; index < content.length; index += 1) {
144
+ const current = content[index];
145
+ const next = content[index + 1];
146
+ if (!state.inString && !state.inLineComment && !state.inBlockComment) {
147
+ if (current === '{') {
148
+ depth += 1;
149
+ }
150
+ else if (current === '}') {
151
+ depth -= 1;
152
+ if (depth === 0)
153
+ return index;
154
+ }
155
+ }
156
+ const advanced = advanceJsonScanState(state, current, next);
157
+ if (advanced > 1)
158
+ index += advanced - 1;
159
+ }
160
+ return -1;
161
+ };
162
+ const extractObjectBlock = (content, key, startIndex = 0) => {
163
+ const valueStart = findJsonKeyValueStartFrom(content, key, startIndex);
164
+ if (valueStart < 0 || content[valueStart] !== '{')
165
+ return undefined;
166
+ const valueEnd = findMatchingObjectBrace(content, valueStart);
167
+ if (valueEnd < 0)
168
+ return undefined;
169
+ return content.slice(valueStart, valueEnd + 1);
170
+ };
171
+ const indentBlock = (content, spaces) => {
172
+ const prefix = ' '.repeat(spaces);
173
+ return content
174
+ .split('\n')
175
+ .map((line) => (line.trim().length === 0 ? line : `${prefix}${line}`))
176
+ .join('\n');
177
+ };
178
+ export const renderProxyWranglerDevConfig = (content, envName) => {
179
+ const envObjectStart = findEnvObjectStart(content);
180
+ if (envObjectStart < 0)
181
+ return undefined;
182
+ const envBlock = extractObjectBlock(content, envName, envObjectStart);
183
+ if (envBlock === undefined)
184
+ return undefined;
185
+ const aliasBlock = extractObjectBlock(content, 'alias');
186
+ const envBody = envBlock.slice(1, -1).trim();
187
+ if (envBody.length === 0)
188
+ return undefined;
189
+ const aliasLine = aliasBlock === undefined ? [] : [` "alias": ${aliasBlock},`];
190
+ return rewriteRelativeWranglerPaths(['{', ...aliasLine, indentBlock(envBody, 2), '}', ''].join('\n'));
191
+ };
50
192
  const isObjectEffectivelyEmpty = (content, objectStart) => {
51
193
  let cursor = objectStart + 1;
52
194
  while (isJsonWhitespace(content[cursor]))
@@ -105,15 +247,16 @@ export const ensureProxyEntrypoint = (options) => {
105
247
  export const ensureWranglerConfig = (options) => {
106
248
  if (!existsSync(options.configPath)) {
107
249
  const values = options.resolveValues(undefined, options.options);
108
- writeFileSync(options.configPath, renderDefaultWranglerConfig(options.renderEnvBlock(values), options.compatibilityDate), 'utf-8');
109
- return { createdFile: true, insertedEnv: true, values };
250
+ const content = renderDefaultWranglerConfig(options.renderEnvBlock(values), options.compatibilityDate);
251
+ writeFileSync(options.configPath, content, 'utf-8');
252
+ return { createdFile: true, insertedEnv: true, content, values };
110
253
  }
111
254
  const content = readFileSync(options.configPath, 'utf-8');
112
255
  const values = options.resolveValues(content, options.options);
113
256
  const next = injectEnvBlock(content, options.envName, options.renderEnvBlock(values));
114
257
  if (next !== content) {
115
258
  writeFileSync(options.configPath, next, 'utf-8');
116
- return { createdFile: false, insertedEnv: true, values };
259
+ return { createdFile: false, insertedEnv: true, content: next, values };
117
260
  }
118
- return { createdFile: false, insertedEnv: false, values };
261
+ return { createdFile: false, insertedEnv: false, content, values };
119
262
  };
@@ -1 +1 @@
1
- {"version":3,"file":"WranglerProxyCommandUtils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/WranglerProxyCommandUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAWrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,MAAM,2BAA2B,GAAG,cAAc,GAAG;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,+BAA+B,CAAC,OAAO,EAAE,QAAQ,SAAS,2BAA2B,IAAI;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC3E,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IAC5C,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,SAAS,OAAO,EAAE,eAAe,MAAM,KAAG,IAIrF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,EAAE,QAAQ,SAAS,2BAA2B,EAC9F,OAAO,+BAA+B,CAAC,OAAO,EAAE,QAAQ,CAAC,KACxD,YA0DF,CAAC"}
1
+ {"version":3,"file":"WranglerProxyCommandUtils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/WranglerProxyCommandUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAarE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,MAAM,2BAA2B,GAAG,cAAc,GAAG;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,+BAA+B,CAAC,OAAO,EAAE,QAAQ,SAAS,2BAA2B,IAAI;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC3E,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IAC5C,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,SAAS,OAAO,EAAE,eAAe,MAAM,KAAG,IAIrF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,EAAE,QAAQ,SAAS,2BAA2B,EAC9F,OAAO,+BAA+B,CAAC,OAAO,EAAE,QAAQ,CAAC,KACxD,YAuEF,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { BaseCommand } from '../BaseCommand.js';
2
2
  import { maybeRunProxyWatchMode, parseIntOption } from '../commands/ProxyCommandUtils.js';
3
- import { ensureProxyEntrypoint, ensureWranglerConfig, resolveConfigPath, } from '../commands/ProxyScaffoldUtils.js';
3
+ import { ensureProxyEntrypoint, ensureWranglerConfig, renderProxyWranglerDevConfig, resolveConfigPath, } from '../commands/ProxyScaffoldUtils.js';
4
4
  import { SpawnUtil } from '../utils/spawn.js';
5
5
  import { Logger } from '../../config/logger.js';
6
+ import { mkdirSync, writeFileSync } from '../../node-singletons/fs.js';
6
7
  import { join } from '../../node-singletons/path.js';
7
8
  export const addWranglerProxyBaseOptions = (command, defaultConfig) => {
8
9
  command.option('-c, --config <path>', 'Wrangler config file', defaultConfig);
@@ -45,7 +46,18 @@ export const createWranglerProxyCommand = (input) => {
45
46
  Logger.info(`Added env.${input.envName} to ${configPath}.`);
46
47
  }
47
48
  input.afterConfigResolved?.(result.values);
48
- const args = ['dev', '--config', configPath, '--env', input.envName];
49
+ const proxyConfigContent = renderProxyWranglerDevConfig(result.content, input.envName);
50
+ const proxyConfigDir = join(cwd, '.wrangler', 'tmp');
51
+ const proxyConfigPath = join(proxyConfigDir, `zin.proxy.${input.envName}.jsonc`);
52
+ if (proxyConfigContent !== undefined) {
53
+ mkdirSync(proxyConfigDir, { recursive: true });
54
+ writeFileSync(proxyConfigPath, proxyConfigContent, 'utf-8');
55
+ }
56
+ const args = [
57
+ 'dev',
58
+ '--config',
59
+ proxyConfigContent === undefined ? configPath : proxyConfigPath,
60
+ ];
49
61
  if (port !== undefined) {
50
62
  args.push('--port', String(port));
51
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../src/config/workers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAItC,OAAO,KAAK,EACV,WAAW,EAIX,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAiTnC,eAAO,MAAM,qBAAqB,GAChC,QAAQ,WAAW,EACnB,mBAAc,EACd,UAAU,qBAAqB,KAC9B,OA6CF,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CA4B7D,CAAC;AAgFF,QAAA,MAAM,mBAAmB,QAAO,mBA2D/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAqBnE,eAAO,MAAM,aAAa,EAAE,aAY1B,CAAC"}
1
+ {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../../src/config/workers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAItC,OAAO,KAAK,EACV,WAAW,EAIX,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAgXnC,eAAO,MAAM,qBAAqB,GAChC,QAAQ,WAAW,EACnB,mBAAc,EACd,UAAU,qBAAqB,KAC9B,OA6CF,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CAmB7D,CAAC;AAgFF,QAAA,MAAM,mBAAmB,QAAO,mBA2D/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAqBnE,eAAO,MAAM,aAAa,EAAE,aAY1B,CAAC"}
@@ -28,6 +28,56 @@ const unregisterRedisConnection = (client) => {
28
28
  registry.cachedConnections.delete(registryKey);
29
29
  }
30
30
  };
31
+ const awaitRedisQuitWithin = async (client, timeoutMs) => {
32
+ if (typeof client.quit !== 'function')
33
+ return true;
34
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
35
+ await client.quit();
36
+ return true;
37
+ }
38
+ let timeoutId;
39
+ try {
40
+ await Promise.race([
41
+ client.quit(),
42
+ new Promise((_, reject) => {
43
+ timeoutId = globalThis.setTimeout(() => {
44
+ reject(ErrorFactory.createGeneralError('Redis graceful shutdown timed out', { timeoutMs }));
45
+ }, timeoutMs);
46
+ }),
47
+ ]);
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ finally {
54
+ if (timeoutId !== undefined) {
55
+ globalThis.clearTimeout(timeoutId);
56
+ }
57
+ }
58
+ };
59
+ const forceDisconnectRedisClient = (client, error) => {
60
+ if (error !== undefined) {
61
+ Logger.warn('Tracked Redis graceful shutdown failed, forcing disconnect', error);
62
+ }
63
+ try {
64
+ client.disconnect();
65
+ }
66
+ catch (disconnectError) {
67
+ Logger.error('Tracked Redis forced disconnect failed', disconnectError);
68
+ }
69
+ };
70
+ const shutdownTrackedRedisConnection = async (client, timeoutMs) => {
71
+ try {
72
+ const quitCompleted = await awaitRedisQuitWithin(client, timeoutMs);
73
+ if (!quitCompleted) {
74
+ forceDisconnectRedisClient(client, ErrorFactory.createGeneralError('Redis graceful shutdown timed out', { timeoutMs }));
75
+ }
76
+ }
77
+ catch (error) {
78
+ forceDisconnectRedisClient(client, error);
79
+ }
80
+ };
31
81
  const hasReusableRedisStatus = (client) => {
32
82
  return client.status !== 'end' && client.status !== 'close';
33
83
  };
@@ -263,6 +313,7 @@ export const createRedisConnection = (config, maxRetries = 3, options) => {
263
313
  export const shutdownRedisConnections = async () => {
264
314
  const registry = getRedisConnectionRegistry();
265
315
  const trackedConnections = Array.from(registry.activeConnections);
316
+ const perConnectionTimeoutMs = 750;
266
317
  if (trackedConnections.length === 0)
267
318
  return;
268
319
  registry.activeConnections.clear();
@@ -271,18 +322,7 @@ export const shutdownRedisConnections = async () => {
271
322
  count: trackedConnections.length,
272
323
  });
273
324
  await Promise.allSettled(trackedConnections.map(async (client) => {
274
- try {
275
- await client.quit();
276
- }
277
- catch (error) {
278
- Logger.warn('Tracked Redis graceful shutdown failed, forcing disconnect', error);
279
- try {
280
- client.disconnect();
281
- }
282
- catch (disconnectError) {
283
- Logger.error('Tracked Redis forced disconnect failed', disconnectError);
284
- }
285
- }
325
+ await shutdownTrackedRedisConnection(client, perConnectionTimeoutMs);
286
326
  }));
287
327
  };
288
328
  const createIntervalConfig = () => Env.SSE_SNAPSHOT_INTERVAL;
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @zintrust/core v0.4.77
2
+ * @zintrust/core v0.4.79
3
3
  *
4
4
  * ZinTrust Framework - Production-Grade TypeScript Backend
5
5
  * Built for performance, type safety, and exceptional developer experience
6
6
  *
7
7
  * Build Information:
8
- * Built: 2026-04-08T09:22:49.437Z
8
+ * Built: 2026-04-08T11:45:55.486Z
9
9
  * Node: >=20.0.0
10
10
  * License: MIT
11
11
  *
@@ -21,7 +21,7 @@
21
21
  * Available at runtime for debugging and health checks
22
22
  */
23
23
  export const ZINTRUST_VERSION = '0.1.41';
24
- export const ZINTRUST_BUILD_DATE = '2026-04-08T09:22:49.403Z'; // Replaced during build
24
+ export const ZINTRUST_BUILD_DATE = '2026-04-08T11:45:55.451Z'; // Replaced during build
25
25
  export { Application } from './boot/Application.js';
26
26
  export { AwsSigV4 } from './common/index.js';
27
27
  export { SignedRequest } from './security/SignedRequest.js';
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorHandlerMiddleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/ErrorHandlerMiddleware.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACxC;AA0BD,eAAO,MAAM,sBAAsB;qBACjB,mBAAmB,GAAQ,UAAU;EA8CrD,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"ErrorHandlerMiddleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/ErrorHandlerMiddleware.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACxC;AA6CD,eAAO,MAAM,sBAAsB;qBACjB,mBAAmB,GAAQ,UAAU;EA8CrD,CAAC;AAEH,eAAe,sBAAsB,CAAC"}
@@ -5,6 +5,18 @@ import { ErrorResponse } from '../http/ErrorResponse.js';
5
5
  import { RequestContext } from '../http/RequestContext.js';
6
6
  import { respondWithMiddlewareFailure, } from './MiddlewareFailureResponder.js';
7
7
  import { captureTraceException } from '../runtime/plugins/trace-runtime.js';
8
+ const resolveTraceExceptionContext = (req) => {
9
+ const requestContext = RequestContext.get(req);
10
+ const context = req.context ?? {};
11
+ const batchId = requestContext?.traceId ??
12
+ (typeof context['traceId'] === 'string' ? context['traceId'] : undefined);
13
+ const path = requestContext?.path ?? (typeof context['path'] === 'string' ? context['path'] : undefined);
14
+ const userId = requestContext?.userId ??
15
+ (typeof context['userId'] === 'string' ? context['userId'] : undefined);
16
+ if (batchId === undefined && path === undefined && userId === undefined)
17
+ return undefined;
18
+ return { batchId, path, userId };
19
+ };
8
20
  const isWritableEnded = (res) => {
9
21
  if (typeof res.getRaw !== 'function')
10
22
  return false;
@@ -30,7 +42,7 @@ export const ErrorHandlerMiddleware = Object.freeze({
30
42
  await next();
31
43
  }
32
44
  catch (error) {
33
- captureTraceException(error);
45
+ captureTraceException(error, resolveTraceExceptionContext(req));
34
46
  Logger.error('Unhandled request error:', error);
35
47
  const requestId = RequestContext.get(req)?.requestId ?? req.context['requestId'];
36
48
  const includeStack = Env.NODE_ENV !== 'production' && !shouldHideStackFromResponse(error);
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationStore.d.ts","sourceRoot":"","sources":["../../../../src/orm/migrations/MigrationStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAoahG,eAAO,MAAM,cAAc;oBACH,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;8BAKzC,SAAS,UACN,cAAc,YACZ,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;sBA4BZ,SAAS,SACN,cAAc,WACZ,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;sBAmDlC,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC,IAAI,CAAC;mBA2DV,SAAS,UACL;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,qBAAqB,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GACA,OAAO,CAAC,IAAI,CAAC;kCAmDV,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACnE,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;8BA6C5C,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,MAAM,EAAE,CAAC;qBA0Bd,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;EAmBhB,CAAC"}
1
+ {"version":3,"file":"MigrationStore.d.ts","sourceRoot":"","sources":["../../../../src/orm/migrations/MigrationStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6dhG,eAAO,MAAM,cAAc;oBACH,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;8BAKzC,SAAS,UACN,cAAc,YACZ,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;sBA4BZ,SAAS,SACN,cAAc,WACZ,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;sBAmDlC,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC,IAAI,CAAC;mBA2DV,SAAS,UACL;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,qBAAqB,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GACA,OAAO,CAAC,IAAI,CAAC;kCAmDV,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACnE,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;8BA6C5C,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,MAAM,EAAE,CAAC;qBA0Bd,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;EAmBhB,CAAC"}
@@ -32,7 +32,9 @@ const queryExists = async (db, sql, parameters) => {
32
32
  const schemaHasTable = async (db, tableName) => {
33
33
  const driver = db.getType();
34
34
  if (driver === 'sqlite' || driver === 'd1' || driver === 'd1-remote') {
35
- return queryExists(db, "SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1", [tableName]);
35
+ return queryExists(db, "SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1", [
36
+ tableName,
37
+ ]);
36
38
  }
37
39
  if (driver === 'postgresql') {
38
40
  return queryExists(db, "SELECT 1 FROM information_schema.tables WHERE table_schema='public' AND table_name=? LIMIT 1", [tableName]);
@@ -87,41 +89,70 @@ const ensureTrackingTable = async (db) => {
87
89
  await ensure();
88
90
  clearTableLayoutCache(db);
89
91
  };
92
+ const probeTableLayout = async (db) => {
93
+ const [hasTable, hasName, hasMigration, hasScope, hasService, hasStatus, hasAppliedAt, hasCreatedAt,] = await Promise.all([
94
+ schemaHasTable(db, 'migrations'),
95
+ schemaHasColumn(db, 'migrations', 'name'),
96
+ schemaHasColumn(db, 'migrations', 'migration'),
97
+ schemaHasColumn(db, 'migrations', 'scope'),
98
+ schemaHasColumn(db, 'migrations', 'service'),
99
+ schemaHasColumn(db, 'migrations', 'status'),
100
+ schemaHasColumn(db, 'migrations', 'applied_at'),
101
+ schemaHasColumn(db, 'migrations', 'created_at'),
102
+ ]);
103
+ return {
104
+ hasAppliedAt,
105
+ hasCreatedAt,
106
+ hasMigration,
107
+ hasName,
108
+ hasScope,
109
+ hasService,
110
+ hasStatus,
111
+ hasTable,
112
+ };
113
+ };
114
+ const ensureProbeTableExists = async (db, probe, allowEnsure) => {
115
+ if (probe.hasTable || !allowEnsure)
116
+ return null;
117
+ await ensureTrackingTable(db);
118
+ return resolveTableLayout(db, false);
119
+ };
120
+ const assertProbeHasIdentityColumns = (probe) => {
121
+ if (probe.hasName || probe.hasMigration)
122
+ return;
123
+ throw ErrorFactory.createCliError('The migrations table is missing both `name` and `migration` columns. Update the tracking table before running migrations.');
124
+ };
125
+ const toTableLayout = (probe) => {
126
+ return {
127
+ hasAppliedAt: probe.hasAppliedAt,
128
+ hasCreatedAt: probe.hasCreatedAt,
129
+ hasMigration: probe.hasMigration,
130
+ hasName: probe.hasName,
131
+ hasScope: probe.hasScope,
132
+ hasService: probe.hasService,
133
+ hasStatus: probe.hasStatus,
134
+ requiresCompatibilityMode: probe.hasMigration ||
135
+ !probe.hasName ||
136
+ !probe.hasScope ||
137
+ !probe.hasService ||
138
+ !probe.hasStatus,
139
+ };
140
+ };
141
+ const loadTableLayout = async (db, allowEnsure) => {
142
+ if (typeof db.query !== 'function')
143
+ return DEFAULT_LAYOUT;
144
+ const probe = await probeTableLayout(db);
145
+ const ensuredLayout = await ensureProbeTableExists(db, probe, allowEnsure);
146
+ if (ensuredLayout !== null)
147
+ return ensuredLayout;
148
+ assertProbeHasIdentityColumns(probe);
149
+ return toTableLayout(probe);
150
+ };
90
151
  const resolveTableLayout = async (db, allowEnsure = true) => {
91
152
  const cached = tableLayoutCache.get(db);
92
153
  if (cached !== undefined)
93
154
  return cached;
94
- const layoutPromise = (async () => {
95
- if (typeof db.query !== 'function')
96
- return DEFAULT_LAYOUT;
97
- const [hasTable, hasName, hasMigration, hasScope, hasService, hasStatus, hasAppliedAt, hasCreatedAt] = await Promise.all([
98
- schemaHasTable(db, 'migrations'),
99
- schemaHasColumn(db, 'migrations', 'name'),
100
- schemaHasColumn(db, 'migrations', 'migration'),
101
- schemaHasColumn(db, 'migrations', 'scope'),
102
- schemaHasColumn(db, 'migrations', 'service'),
103
- schemaHasColumn(db, 'migrations', 'status'),
104
- schemaHasColumn(db, 'migrations', 'applied_at'),
105
- schemaHasColumn(db, 'migrations', 'created_at'),
106
- ]);
107
- if (!hasTable && allowEnsure) {
108
- await ensureTrackingTable(db);
109
- return resolveTableLayout(db, false);
110
- }
111
- if (!hasName && !hasMigration) {
112
- throw ErrorFactory.createCliError('The migrations table is missing both `name` and `migration` columns. Update the tracking table before running migrations.');
113
- }
114
- return {
115
- hasAppliedAt,
116
- hasCreatedAt,
117
- hasMigration,
118
- hasName,
119
- hasScope,
120
- hasService,
121
- hasStatus,
122
- requiresCompatibilityMode: hasMigration || !hasName || !hasScope || !hasService || !hasStatus,
123
- };
124
- })();
155
+ const layoutPromise = loadTableLayout(db, allowEnsure);
125
156
  tableLayoutCache.set(db, layoutPromise);
126
157
  return layoutPromise.catch((error) => {
127
158
  if (tableLayoutCache.get(db) === layoutPromise) {
@@ -1 +1 @@
1
- {"version":3,"file":"ZintrustD1Proxy.d.ts","sourceRoot":"","sources":["../../../../src/proxy/d1/ZintrustD1Proxy.ts"],"names":[],"mappings":"AAWA,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjD,KAAK,qBAAqB,GAAG;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE;QACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QACrE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;QAChE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;KAChG,CAAC;IACF,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,IAAI;IACpB,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;CACf,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,mBAAmB,CAAC;IACpD,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5C,GAAG,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CACjC,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,mBAAmB,CAAC;CAC/C,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AA6QF,eAAO,MAAM,eAAe;;;mBAGL,OAAO,OAAO,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC;EAqB5D,CAAC;AAEH,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ZintrustD1Proxy.d.ts","sourceRoot":"","sources":["../../../../src/proxy/d1/ZintrustD1Proxy.ts"],"names":[],"mappings":"AASA,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjD,KAAK,qBAAqB,GAAG;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE;QACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QACrE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;QAChE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;KAChG,CAAC;IACF,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF,CAAC;AAEF,KAAK,WAAW,CAAC,CAAC,IAAI;IACpB,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;CACf,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,mBAAmB,CAAC;IACpD,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5C,GAAG,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CACjC,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,mBAAmB,CAAC;CAC/C,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAyRF,eAAO,MAAM,eAAe;;;mBAGL,OAAO,OAAO,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC;EAqB5D,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -1,11 +1,12 @@
1
- import { Logger } from '../../config/logger.js';
2
- import { isArray, isObject, isString } from '../../helper/index.js';
3
1
  import { getEnvInt, json, normalizeBindingName, readAndVerifyJson, toErrorResponse, } from '../CloudflareProxyShared.js';
4
2
  import { RequestValidator } from '../RequestValidator.js';
5
3
  const DEFAULT_SIGNING_WINDOW_MS = 60_000;
6
4
  const DEFAULT_MAX_BODY_BYTES = 128 * 1024;
7
5
  const DEFAULT_MAX_SQL_BYTES = 32 * 1024;
8
6
  const DEFAULT_MAX_PARAMS = 256;
7
+ const isRecord = (value) => typeof value === 'object' && value !== null;
8
+ const isString = (value) => typeof value === 'string';
9
+ const isArray = (value) => Array.isArray(value);
9
10
  const isDebugEnabled = (env) => {
10
11
  const raw = env.ZT_PROXY_DEBUG;
11
12
  if (!isString(raw))
@@ -28,10 +29,16 @@ const safeErrorMessage = (error) => {
28
29
  const logProxyError = (env, context, error) => {
29
30
  if (!isDebugEnabled(env))
30
31
  return;
31
- Logger.error('[ZintrustD1Proxy] error', {
32
- ...context,
33
- message: safeErrorMessage(error).slice(0, 800),
34
- });
32
+ try {
33
+ // eslint-disable-next-line no-console
34
+ console.error('[ZintrustD1Proxy] error', {
35
+ ...context,
36
+ message: safeErrorMessage(error).slice(0, 800),
37
+ });
38
+ }
39
+ catch {
40
+ // ignore logging failures in Workers proxy mode
41
+ }
35
42
  };
36
43
  const resolveD1Binding = (env) => {
37
44
  const candidates = ['DB', 'zintrust_db', normalizeBindingName(env.D1_BINDING)].filter((value, index, values) => isString(value) && value.trim() !== '' && values.indexOf(value) === index);
@@ -50,7 +57,7 @@ const loadStatements = (env) => {
50
57
  return null;
51
58
  try {
52
59
  const parsed = JSON.parse(raw);
53
- if (!isObject(parsed))
60
+ if (!isRecord(parsed))
54
61
  return null;
55
62
  return parsed;
56
63
  }
@@ -80,7 +87,7 @@ const toD1ExceptionResponse = (error) => {
80
87
  return toErrorResponse(500, 'D1_ERROR', message);
81
88
  };
82
89
  const parseSqlPayload = (payload) => {
83
- if (!isObject(payload)) {
90
+ if (!isRecord(payload)) {
84
91
  return { ok: false, response: toErrorResponse(400, 'VALIDATION_ERROR', 'Invalid body') };
85
92
  }
86
93
  const sql = payload['sql'];
@@ -181,7 +188,7 @@ const handleExec = async (request, env) => {
181
188
  }
182
189
  };
183
190
  const parseStatementPayload = (payload) => {
184
- if (!isObject(payload)) {
191
+ if (!isRecord(payload)) {
185
192
  return { ok: false, response: toErrorResponse(400, 'VALIDATION_ERROR', 'Invalid body') };
186
193
  }
187
194
  const statementId = payload['statementId'];
@@ -18,7 +18,12 @@ export declare const registerTraceRoutes: (router: unknown, storage: unknown, op
18
18
  basePath?: string;
19
19
  middleware?: ReadonlyArray<string>;
20
20
  }) => void;
21
- export declare const captureTraceException: (error: unknown) => void;
21
+ export declare const captureTraceException: (error: unknown, context?: {
22
+ batchId?: string;
23
+ hostname?: string;
24
+ path?: string;
25
+ userId?: string;
26
+ }) => void;
22
27
  export declare const ensureSystemTraceRegistered: () => Promise<void>;
23
28
  export {};
24
29
  //# sourceMappingURL=trace-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trace-runtime.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/trace-runtime.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC;CACtC,CAAC;AA6DF,eAAO,MAAM,WAAW,QAAO,OAA0C,CAAC;AAE1E,eAAO,MAAM,WAAW,EAAE,cAIxB,CAAC;AAEH,eAAO,MAAM,YAAY,EAAE,eAIzB,CAAC;AAEH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,OAAO,EACf,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,KAClE,IAEF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,OAAO,EACf,SAAS,OAAO,EAChB,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,KAClE,IAEF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,KAAG,IAStD,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAAa,OAAO,CAAC,IAAI,CAIhE,CAAC"}
1
+ {"version":3,"file":"trace-runtime.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/trace-runtime.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC;CACtC,CAAC;AAwEF,eAAO,MAAM,WAAW,QAAO,OAA0C,CAAC;AAE1E,eAAO,MAAM,WAAW,EAAE,cAIxB,CAAC;AAEH,eAAO,MAAM,YAAY,EAAE,eAIzB,CAAC;AAEH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,OAAO,EACf,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,KAClE,IAEF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,OAAO,EACf,SAAS,OAAO,EAChB,UAAU;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,KAClE,IAEF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,OAAO,OAAO,EACd,UAAU;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAChF,IASF,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAAa,OAAO,CAAC,IAAI,CAIhE,CAAC"}
@@ -6,7 +6,7 @@ const fallbackTraceStorage = Object.freeze({
6
6
  });
7
7
  const fallbackRegisterTraceDashboard = (_router, _options) => undefined;
8
8
  const fallbackRegisterTraceRoutes = (_router, _storage, _options) => undefined;
9
- const fallbackCaptureTraceException = (_error) => undefined;
9
+ const fallbackCaptureTraceException = (_error, _context) => undefined;
10
10
  let systemTraceModule;
11
11
  let didAttemptSystemTraceLoad = false;
12
12
  let pendingSystemTraceLoad;
@@ -46,13 +46,13 @@ export const registerTraceDashboard = (router, options) => {
46
46
  export const registerTraceRoutes = (router, storage, options) => {
47
47
  (systemTraceModule?.registerTraceRoutes ?? fallbackRegisterTraceRoutes)(router, storage, options);
48
48
  };
49
- export const captureTraceException = (error) => {
49
+ export const captureTraceException = (error, context) => {
50
50
  if (systemTraceModule?.captureTraceException !== undefined) {
51
- systemTraceModule.captureTraceException(error);
51
+ systemTraceModule.captureTraceException(error, context);
52
52
  return;
53
53
  }
54
54
  void loadSystemTraceModule().then((module) => {
55
- (module?.captureTraceException ?? fallbackCaptureTraceException)(error);
55
+ (module?.captureTraceException ?? fallbackCaptureTraceException)(error, context);
56
56
  });
57
57
  };
58
58
  export const ensureSystemTraceRegistered = async () => {