@zintrust/core 1.8.5 → 1.8.6
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 +5 -5
- package/src/cli/cloudflare/CloudflareSecretSync.d.ts +9 -4
- package/src/cli/cloudflare/CloudflareSecretSync.d.ts.map +1 -1
- package/src/cli/cloudflare/CloudflareSecretSync.js +121 -16
- package/src/cli/commands/PutCommand.d.ts.map +1 -1
- package/src/cli/commands/PutCommand.js +25 -1
- package/src/cli/commands/WranglerProxyCommandUtils.d.ts.map +1 -1
- package/src/cli/commands/WranglerProxyCommandUtils.js +21 -1
- package/src/index.js +3 -3
- package/src/proxy/smtp/SmtpProxyServer.d.ts.map +1 -1
- package/src/proxy/smtp/SmtpProxyServer.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/core",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
4
4
|
"description": "Production-grade TypeScript backend framework for JavaScript",
|
|
5
5
|
"homepage": "https://zintrust.com",
|
|
6
6
|
"repository": {
|
|
@@ -59,14 +59,14 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@cloudflare/containers": "^0.3.4",
|
|
61
61
|
"bcryptjs": "^3.0.3",
|
|
62
|
-
"bullmq": "^5.76.
|
|
62
|
+
"bullmq": "^5.76.10",
|
|
63
63
|
"chalk": "^5.6.2",
|
|
64
64
|
"commander": "^14.0.3",
|
|
65
65
|
"inquirer": "^13.4.3",
|
|
66
66
|
"jsonwebtoken": "^9.0.3",
|
|
67
67
|
"mysql2": "^3.22.3",
|
|
68
|
-
"pg": "^8.
|
|
69
|
-
"tsx": "^4.22.
|
|
68
|
+
"pg": "^8.21.0",
|
|
69
|
+
"tsx": "^4.22.3"
|
|
70
70
|
},
|
|
71
71
|
"overrides": {
|
|
72
72
|
"ajv": "^8.18.0",
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
"@tootallnate/once": "3.0.1",
|
|
77
77
|
"node-forge": "^1.4.0",
|
|
78
78
|
"fast-uri": "3.1.2",
|
|
79
|
-
"fast-xml-builder": "1.2.0",
|
|
80
79
|
"fast-xml-parser": "5.8.0",
|
|
80
|
+
"protobufjs": "7.5.9",
|
|
81
81
|
"brace-expansion": "^5.0.5",
|
|
82
82
|
"picomatch": "^4.0.4",
|
|
83
83
|
"cross-spawn": "^7.0.5",
|
|
@@ -15,20 +15,25 @@ type CloudflareSecretSyncArgs = {
|
|
|
15
15
|
envPath: string;
|
|
16
16
|
dryRun?: boolean;
|
|
17
17
|
configGroups?: string[];
|
|
18
|
+
directKeys?: string[];
|
|
19
|
+
inlineValues?: Record<string, string>;
|
|
18
20
|
configPath?: string;
|
|
19
21
|
target?: string;
|
|
22
|
+
bulk?: boolean;
|
|
20
23
|
requireSelection?: boolean;
|
|
21
24
|
};
|
|
22
25
|
export type CloudflareSecretSyncResult = {
|
|
23
26
|
pushed: number;
|
|
27
|
+
pushedKeys: string[];
|
|
28
|
+
skippedEmptyKeys: string[];
|
|
24
29
|
failures: CloudflareSecretSyncFailure[];
|
|
25
30
|
selectedKeys: string[];
|
|
26
31
|
};
|
|
27
|
-
export declare const reportCloudflareSecretSync: (log: CloudflareSecretLog, result: Pick<CloudflareSecretSyncResult, "pushed" | "failures">) => void;
|
|
28
|
-
export declare const syncCloudflareSecrets: ({ log, cwd, wranglerEnvs, envPath, dryRun, configGroups, configPath, target, requireSelection, }: CloudflareSecretSyncArgs) => Promise<CloudflareSecretSyncResult>;
|
|
32
|
+
export declare const reportCloudflareSecretSync: (log: CloudflareSecretLog, result: Pick<CloudflareSecretSyncResult, "pushed" | "skippedEmptyKeys" | "failures">) => void;
|
|
33
|
+
export declare const syncCloudflareSecrets: ({ log, cwd, wranglerEnvs, envPath, dryRun, configGroups, directKeys, inlineValues, configPath, target, bulk, requireSelection, }: CloudflareSecretSyncArgs) => Promise<CloudflareSecretSyncResult>;
|
|
29
34
|
declare const _default: Readonly<{
|
|
30
|
-
syncCloudflareSecrets: ({ log, cwd, wranglerEnvs, envPath, dryRun, configGroups, configPath, target, requireSelection, }: CloudflareSecretSyncArgs) => Promise<CloudflareSecretSyncResult>;
|
|
31
|
-
reportCloudflareSecretSync: (log: CloudflareSecretLog, result: Pick<CloudflareSecretSyncResult, "pushed" | "failures">) => void;
|
|
35
|
+
syncCloudflareSecrets: ({ log, cwd, wranglerEnvs, envPath, dryRun, configGroups, directKeys, inlineValues, configPath, target, bulk, requireSelection, }: CloudflareSecretSyncArgs) => Promise<CloudflareSecretSyncResult>;
|
|
36
|
+
reportCloudflareSecretSync: (log: CloudflareSecretLog, result: Pick<CloudflareSecretSyncResult, "pushed" | "skippedEmptyKeys" | "failures">) => void;
|
|
32
37
|
}>;
|
|
33
38
|
export default _default;
|
|
34
39
|
//# sourceMappingURL=CloudflareSecretSync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudflareSecretSync.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloudflare/CloudflareSecretSync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CloudflareSecretSync.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloudflare/CloudflareSecretSync.ts"],"names":[],"mappings":"AAaA,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAcF,KAAK,wBAAwB,GAAG;IAC9B,GAAG,EAAE,mBAAmB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,2BAA2B,EAAE,CAAC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAuTF,eAAO,MAAM,0BAA0B,GACrC,KAAK,mBAAmB,EACxB,QAAQ,IAAI,CAAC,0BAA0B,EAAE,QAAQ,GAAG,kBAAkB,GAAG,UAAU,CAAC,KACnF,IAcF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAU,kIAazC,wBAAwB,KAAG,OAAO,CAAC,0BAA0B,CAiD/D,CAAC;;8JAjDC,wBAAwB,KAAG,OAAO,CAAC,0BAA0B,CAAC;sCA/B1D,mBAAmB,UAChB,IAAI,CAAC,0BAA0B,EAAE,QAAQ,GAAG,kBAAkB,GAAG,UAAU,CAAC,KACnF,IAAI;;AAgFP,wBAGG"}
|
|
@@ -3,7 +3,8 @@ import { resolveNpmPath } from '../../common/index.js';
|
|
|
3
3
|
import { appConfig } from '../../config/app.js';
|
|
4
4
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
5
|
import { execFileSync } from '../../node-singletons/child-process.js';
|
|
6
|
-
import { existsSync } from '../../node-singletons/fs.js';
|
|
6
|
+
import { existsSync, mkdtempSync, rmSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
7
|
+
import { tmpdir } from '../../node-singletons/os.js';
|
|
7
8
|
import * as path from '../../node-singletons/path.js';
|
|
8
9
|
import { EnvFile } from '../../toolkit/Secrets/EnvFile.js';
|
|
9
10
|
const uniq = (items) => {
|
|
@@ -29,6 +30,12 @@ const resolveValue = (key, envMap) => {
|
|
|
29
30
|
const fromProcess = process.env[key];
|
|
30
31
|
return fromFile ?? fromProcess ?? '';
|
|
31
32
|
};
|
|
33
|
+
const resolveValueWithOverrides = (key, envMap, inlineValues) => {
|
|
34
|
+
const inlineValue = inlineValues[key];
|
|
35
|
+
if (typeof inlineValue === 'string')
|
|
36
|
+
return inlineValue;
|
|
37
|
+
return resolveValue(key, envMap);
|
|
38
|
+
};
|
|
32
39
|
const getPutTimeoutMs = () => {
|
|
33
40
|
const raw = process.env['ZT_PUT_TIMEOUT_MS'];
|
|
34
41
|
if (typeof raw !== 'string')
|
|
@@ -38,13 +45,20 @@ const getPutTimeoutMs = () => {
|
|
|
38
45
|
return 120000;
|
|
39
46
|
return parsed;
|
|
40
47
|
};
|
|
48
|
+
const describeWranglerEnv = (wranglerEnv) => wranglerEnv.trim() === '' ? 'top-level worker' : wranglerEnv;
|
|
41
49
|
const putSecret = (wranglerEnv, key, value, configPath) => {
|
|
42
50
|
const npmPath = resolveNpmPath();
|
|
43
51
|
const args = ['exec', '--yes', '--', 'wrangler'];
|
|
44
52
|
if (typeof configPath === 'string' && configPath.trim() !== '') {
|
|
45
53
|
args.push('--config', configPath.trim());
|
|
46
54
|
}
|
|
47
|
-
args.push('secret', 'put', key
|
|
55
|
+
args.push('secret', 'put', key);
|
|
56
|
+
if (wranglerEnv.trim() === '') {
|
|
57
|
+
args.push('--env=');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
args.push('--env', wranglerEnv);
|
|
61
|
+
}
|
|
48
62
|
execFileSync(npmPath, args, {
|
|
49
63
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
50
64
|
input: value,
|
|
@@ -54,8 +68,33 @@ const putSecret = (wranglerEnv, key, value, configPath) => {
|
|
|
54
68
|
env: appConfig.getSafeEnv(),
|
|
55
69
|
});
|
|
56
70
|
};
|
|
71
|
+
const putSecretBulk = (wranglerEnv, payloadPath, configPath) => {
|
|
72
|
+
const npmPath = resolveNpmPath();
|
|
73
|
+
const args = ['exec', '--yes', '--', 'wrangler'];
|
|
74
|
+
if (typeof configPath === 'string' && configPath.trim() !== '') {
|
|
75
|
+
args.push('--config', configPath.trim());
|
|
76
|
+
}
|
|
77
|
+
args.push('secret', 'bulk', payloadPath);
|
|
78
|
+
if (wranglerEnv.trim() === '') {
|
|
79
|
+
args.push('--env=');
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
args.push('--env', wranglerEnv);
|
|
83
|
+
}
|
|
84
|
+
execFileSync(npmPath, args, {
|
|
85
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
86
|
+
encoding: 'utf8',
|
|
87
|
+
timeout: getPutTimeoutMs(),
|
|
88
|
+
killSignal: 'SIGTERM',
|
|
89
|
+
env: appConfig.getSafeEnv(),
|
|
90
|
+
});
|
|
91
|
+
};
|
|
57
92
|
const getFailureReason = (error) => error instanceof Error ? error.message : String(error);
|
|
58
|
-
const resolveSelectedKeys = ({ log, config, cwd, wranglerEnvs, configGroups = [], configPath, target, requireSelection, }) => {
|
|
93
|
+
const resolveSelectedKeys = ({ log, config, cwd, wranglerEnvs, configGroups = [], directKeys = [], configPath, target, requireSelection, }) => {
|
|
94
|
+
const selectedDirectKeys = uniq(directKeys);
|
|
95
|
+
if (selectedDirectKeys.length > 0) {
|
|
96
|
+
return selectedDirectKeys;
|
|
97
|
+
}
|
|
59
98
|
const explicitKeys = uniq(configGroups.flatMap((groupKey) => {
|
|
60
99
|
const keys = getConfigArray(config, groupKey);
|
|
61
100
|
if (keys.length === 0) {
|
|
@@ -76,46 +115,109 @@ const resolveSelectedKeys = ({ log, config, cwd, wranglerEnvs, configGroups = []
|
|
|
76
115
|
return selectedKeys;
|
|
77
116
|
}
|
|
78
117
|
throw ErrorFactory.createCliError(configGroups.length === 0
|
|
79
|
-
? 'No secret keys resolved from .zintrust.json cloudflare.shared_env/cloudflare.targets/cloudflare.wrangler_envs. Use --var <group
|
|
118
|
+
? 'No secret keys resolved from explicit keys or .zintrust.json cloudflare.shared_env/cloudflare.targets/cloudflare.wrangler_envs. Use --key/--keys, --var <group>, or add a Cloudflare env manifest.'
|
|
80
119
|
: 'No secret keys resolved from selected groups.');
|
|
81
120
|
};
|
|
82
|
-
const
|
|
121
|
+
const resolveBulkPayload = (log, wranglerEnv, selectedKeys, envMap, inlineValues) => {
|
|
122
|
+
const payload = {};
|
|
123
|
+
const includedKeys = [];
|
|
124
|
+
const skippedEmptyKeys = [];
|
|
125
|
+
const wranglerEnvLabel = describeWranglerEnv(wranglerEnv);
|
|
126
|
+
for (const key of selectedKeys) {
|
|
127
|
+
const value = resolveValueWithOverrides(key, envMap, inlineValues);
|
|
128
|
+
if (value.trim() === '') {
|
|
129
|
+
log.warn(`skip ${key} -> ${wranglerEnvLabel}: empty value`);
|
|
130
|
+
skippedEmptyKeys.push(key);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
payload[key] = value;
|
|
134
|
+
includedKeys.push(key);
|
|
135
|
+
}
|
|
136
|
+
return { payload, includedKeys, skippedEmptyKeys };
|
|
137
|
+
};
|
|
138
|
+
const processSecretSync = (log, wranglerEnvs, selectedKeys, envMap, dryRun, configPath, inlineValues) => {
|
|
83
139
|
let pushed = 0;
|
|
140
|
+
const pushedKeys = [];
|
|
141
|
+
const skippedEmptyKeys = [];
|
|
84
142
|
const failures = [];
|
|
85
143
|
for (const wranglerEnv of wranglerEnvs) {
|
|
144
|
+
const wranglerEnvLabel = describeWranglerEnv(wranglerEnv);
|
|
86
145
|
for (const key of selectedKeys) {
|
|
87
|
-
const value =
|
|
146
|
+
const value = resolveValueWithOverrides(key, envMap, inlineValues);
|
|
88
147
|
if (value.trim() === '') {
|
|
89
|
-
|
|
148
|
+
log.warn(`skip ${key} -> ${wranglerEnvLabel}: empty value`);
|
|
149
|
+
skippedEmptyKeys.push(key);
|
|
90
150
|
continue;
|
|
91
151
|
}
|
|
92
152
|
try {
|
|
93
153
|
if (!dryRun) {
|
|
94
|
-
log.info(`putting ${key} -> ${
|
|
154
|
+
log.info(`putting ${key} -> ${wranglerEnvLabel}...`);
|
|
95
155
|
putSecret(wranglerEnv, key, value, configPath);
|
|
96
156
|
}
|
|
97
157
|
pushed += 1;
|
|
98
|
-
|
|
158
|
+
pushedKeys.push(key);
|
|
159
|
+
log.info(`${dryRun ? '[dry-run] ' : ''}put ${key} -> ${wranglerEnvLabel}`);
|
|
99
160
|
}
|
|
100
161
|
catch (error) {
|
|
101
162
|
failures.push({ wranglerEnv, key, reason: getFailureReason(error) });
|
|
102
163
|
}
|
|
103
164
|
}
|
|
104
165
|
}
|
|
105
|
-
return { pushed, failures };
|
|
166
|
+
return { pushed, pushedKeys, skippedEmptyKeys, failures };
|
|
167
|
+
};
|
|
168
|
+
const processSecretBulkSync = (log, wranglerEnvs, selectedKeys, envMap, dryRun, configPath, inlineValues) => {
|
|
169
|
+
let pushed = 0;
|
|
170
|
+
const pushedKeys = [];
|
|
171
|
+
const skippedEmptyKeys = [];
|
|
172
|
+
const failures = [];
|
|
173
|
+
for (const wranglerEnv of wranglerEnvs) {
|
|
174
|
+
const wranglerEnvLabel = describeWranglerEnv(wranglerEnv);
|
|
175
|
+
const { payload, includedKeys, skippedEmptyKeys: skippedForEnv, } = resolveBulkPayload(log, wranglerEnv, selectedKeys, envMap, inlineValues);
|
|
176
|
+
skippedEmptyKeys.push(...skippedForEnv);
|
|
177
|
+
if (includedKeys.length === 0) {
|
|
178
|
+
log.info(`skip bulk upload -> ${wranglerEnvLabel}: no non-empty keys`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
log.info(`${dryRun ? '[dry-run] ' : ''}bulk keys -> ${wranglerEnvLabel}: ${includedKeys.join(', ')}`);
|
|
182
|
+
if (dryRun) {
|
|
183
|
+
pushed += includedKeys.length;
|
|
184
|
+
pushedKeys.push(...includedKeys);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const tempDir = mkdtempSync(path.join(tmpdir(), 'zintrust-cloudflare-secret-bulk-'));
|
|
188
|
+
const payloadPath = path.join(tempDir, 'secrets.json');
|
|
189
|
+
try {
|
|
190
|
+
writeFileSync(payloadPath, JSON.stringify(payload, null, 2), 'utf8');
|
|
191
|
+
log.info(`bulk uploading ${includedKeys.length} key(s) -> ${wranglerEnvLabel}...`);
|
|
192
|
+
putSecretBulk(wranglerEnv, payloadPath, configPath);
|
|
193
|
+
pushed += includedKeys.length;
|
|
194
|
+
pushedKeys.push(...includedKeys);
|
|
195
|
+
log.info(`bulk put ${includedKeys.length} key(s) -> ${wranglerEnvLabel}`);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const reason = getFailureReason(error);
|
|
199
|
+
for (const key of includedKeys) {
|
|
200
|
+
failures.push({ wranglerEnv, key, reason });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return { pushed, pushedKeys, skippedEmptyKeys, failures };
|
|
106
208
|
};
|
|
107
209
|
export const reportCloudflareSecretSync = (log, result) => {
|
|
108
210
|
if (typeof log.success === 'function') {
|
|
109
|
-
log.success(`Cloudflare secrets report: pushed=${result.pushed}, failed=${result.failures.length}`);
|
|
211
|
+
log.success(`Cloudflare secrets report: pushed=${result.pushed}, skipped_empty=${result.skippedEmptyKeys.length}, failed=${result.failures.length}`);
|
|
110
212
|
}
|
|
111
213
|
else {
|
|
112
|
-
log.info(`Cloudflare secrets report: pushed=${result.pushed}, failed=${result.failures.length}`);
|
|
214
|
+
log.info(`Cloudflare secrets report: pushed=${result.pushed}, skipped_empty=${result.skippedEmptyKeys.length}, failed=${result.failures.length}`);
|
|
113
215
|
}
|
|
114
216
|
for (const item of result.failures) {
|
|
115
|
-
log.warn(`${item.key} -> ${item.wranglerEnv}: ${item.reason}`);
|
|
217
|
+
log.warn(`${item.key} -> ${describeWranglerEnv(item.wranglerEnv)}: ${item.reason}`);
|
|
116
218
|
}
|
|
117
219
|
};
|
|
118
|
-
export const syncCloudflareSecrets = async ({ log, cwd, wranglerEnvs, envPath, dryRun = false, configGroups = [], configPath, target, requireSelection = true, }) => {
|
|
220
|
+
export const syncCloudflareSecrets = async ({ log, cwd, wranglerEnvs, envPath, dryRun = false, configGroups = [], directKeys = [], inlineValues = {}, configPath, target, bulk = false, requireSelection = true, }) => {
|
|
119
221
|
const normalizedConfigPath = typeof configPath === 'string' && configPath.trim() !== '' ? configPath.trim() : undefined;
|
|
120
222
|
if (normalizedConfigPath !== undefined && !existsSync(path.join(cwd, normalizedConfigPath))) {
|
|
121
223
|
throw ErrorFactory.createCliError(`Wrangler config not found: ${normalizedConfigPath}`);
|
|
@@ -127,15 +229,18 @@ export const syncCloudflareSecrets = async ({ log, cwd, wranglerEnvs, envPath, d
|
|
|
127
229
|
cwd,
|
|
128
230
|
wranglerEnvs,
|
|
129
231
|
configGroups,
|
|
232
|
+
directKeys,
|
|
130
233
|
configPath: normalizedConfigPath,
|
|
131
234
|
target,
|
|
132
235
|
requireSelection,
|
|
133
236
|
});
|
|
134
237
|
if (selectedKeys.length === 0) {
|
|
135
|
-
return { pushed: 0, failures: [], selectedKeys: [] };
|
|
238
|
+
return { pushed: 0, pushedKeys: [], skippedEmptyKeys: [], failures: [], selectedKeys: [] };
|
|
136
239
|
}
|
|
137
240
|
const envMap = await EnvFile.read({ cwd, path: envPath });
|
|
138
|
-
const syncResult =
|
|
241
|
+
const syncResult = bulk
|
|
242
|
+
? processSecretBulkSync(log, wranglerEnvs, selectedKeys, envMap, dryRun, normalizedConfigPath, inlineValues)
|
|
243
|
+
: processSecretSync(log, wranglerEnvs, selectedKeys, envMap, dryRun, normalizedConfigPath, inlineValues);
|
|
139
244
|
return {
|
|
140
245
|
...syncResult,
|
|
141
246
|
selectedKeys,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PutCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/PutCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"PutCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/PutCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAwHvF,eAAO,MAAM,UAAU;cACX,YAAY;EAWtB,CAAC;AAEH,eAAe,UAAU,CAAC"}
|
|
@@ -23,10 +23,25 @@ const uniq = (items) => {
|
|
|
23
23
|
const resolveConfigGroups = (options) => {
|
|
24
24
|
return uniq(toStringArray(options.var));
|
|
25
25
|
};
|
|
26
|
+
const resolveDirectKeys = (options) => {
|
|
27
|
+
return uniq([...toStringArray(options.key), ...toStringArray(options.keys)]);
|
|
28
|
+
};
|
|
29
|
+
const resolveInlineValues = (options) => {
|
|
30
|
+
if (typeof options.value !== 'string')
|
|
31
|
+
return {};
|
|
32
|
+
const directKeys = resolveDirectKeys(options);
|
|
33
|
+
if (directKeys.length === 0) {
|
|
34
|
+
throw ErrorFactory.createCliError('`--value` requires `--key` or `--keys`.');
|
|
35
|
+
}
|
|
36
|
+
if (directKeys.length !== 1) {
|
|
37
|
+
throw ErrorFactory.createCliError('`--value` supports exactly one selected key.');
|
|
38
|
+
}
|
|
39
|
+
return { [directKeys[0]]: options.value };
|
|
40
|
+
};
|
|
26
41
|
const resolveWranglerEnvs = (options) => {
|
|
27
42
|
const requested = uniq(toStringArray(options.wg));
|
|
28
43
|
if (requested.length === 0)
|
|
29
|
-
return ['
|
|
44
|
+
return [''];
|
|
30
45
|
return requested;
|
|
31
46
|
};
|
|
32
47
|
const parseEnvPath = (options) => {
|
|
@@ -40,9 +55,13 @@ const addOptions = (command) => {
|
|
|
40
55
|
.argument('[provider]', 'Secret provider (cloudflare)', 'cloudflare')
|
|
41
56
|
.option('--wg <env...>', 'Wrangler environment target(s), e.g. d1-proxy kv-proxy')
|
|
42
57
|
.option('--var <configKey...>', 'Config array key(s) from .zintrust.json (e.g. d1_env kv_env)')
|
|
58
|
+
.option('--key <name...>', 'Upload selected secret key(s) directly without group expansion')
|
|
59
|
+
.option('--keys <name...>', 'Upload selected secret key(s) from env source without group expansion')
|
|
60
|
+
.option('--value <value>', 'Inline value for a single `--key` upload')
|
|
43
61
|
.option('--target <id>', 'Cloudflare worker target key from .zintrust.json cloudflare.targets')
|
|
44
62
|
.option('--env_path <path>', 'Path to env file used as source values', '.env')
|
|
45
63
|
.option('-c, --config <path>', 'Wrangler config file to target (optional)')
|
|
64
|
+
.option('--bulk', 'Upload the final key set with one wrangler secret bulk call per target')
|
|
46
65
|
.option('--dry-run', 'Show what would be uploaded without calling wrangler');
|
|
47
66
|
};
|
|
48
67
|
const ensureCloudflareProvider = (providerRaw) => {
|
|
@@ -53,6 +72,8 @@ const ensureCloudflareProvider = (providerRaw) => {
|
|
|
53
72
|
const execute = async (cmd, options) => {
|
|
54
73
|
ensureCloudflareProvider(String(options.args?.[0] ?? 'cloudflare'));
|
|
55
74
|
const cwd = process.cwd();
|
|
75
|
+
const directKeys = resolveDirectKeys(options);
|
|
76
|
+
const inlineValues = resolveInlineValues(options);
|
|
56
77
|
const result = await syncCloudflareSecrets({
|
|
57
78
|
log: cmd,
|
|
58
79
|
cwd,
|
|
@@ -60,8 +81,11 @@ const execute = async (cmd, options) => {
|
|
|
60
81
|
envPath: parseEnvPath(options),
|
|
61
82
|
dryRun: options.dryRun === true,
|
|
62
83
|
configGroups: resolveConfigGroups(options),
|
|
84
|
+
directKeys,
|
|
85
|
+
inlineValues,
|
|
63
86
|
configPath: typeof options.config === 'string' ? options.config.trim() : undefined,
|
|
64
87
|
target: typeof options.target === 'string' ? options.target : undefined,
|
|
88
|
+
bulk: options.bulk === true,
|
|
65
89
|
requireSelection: true,
|
|
66
90
|
});
|
|
67
91
|
reportCloudflareSecretSync(cmd, result);
|
|
@@ -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;
|
|
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;AAmBrE,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,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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;AA+BF,eAAO,MAAM,0BAA0B,GAAI,OAAO,EAAE,QAAQ,SAAS,2BAA2B,EAC9F,OAAO,+BAA+B,CAAC,OAAO,EAAE,QAAQ,CAAC,KACxD,YA0FF,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { ensureProxyEnvLoadedForCwd, maybeRunProxyWatchMode, parseIntOption, } f
|
|
|
4
4
|
import { ensureProxyEntrypoint, ensureWranglerConfig, renderProxyWranglerDevConfig, resolveConfigPath, } from '../commands/ProxyScaffoldUtils.js';
|
|
5
5
|
import { SpawnUtil } from '../utils/spawn.js';
|
|
6
6
|
import { Logger } from '../../config/logger.js';
|
|
7
|
+
import { isNonEmptyString } from '../../helper/index.js';
|
|
7
8
|
import { mkdirSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
8
9
|
import { dirname, join } from '../../node-singletons/path.js';
|
|
9
10
|
export const addWranglerProxyBaseOptions = (command, defaultConfig) => {
|
|
@@ -14,6 +15,24 @@ export const addWranglerProxyBaseOptions = (command, defaultConfig) => {
|
|
|
14
15
|
const toRootedProxyConfigContent = (content) => {
|
|
15
16
|
return content.replaceAll('": "../../', '": "./');
|
|
16
17
|
};
|
|
18
|
+
const isTruthyFlag = (value) => {
|
|
19
|
+
if (!isNonEmptyString(value))
|
|
20
|
+
return false;
|
|
21
|
+
const normalized = value.trim().toLowerCase();
|
|
22
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
|
|
23
|
+
};
|
|
24
|
+
const createWranglerDevSpawnEnv = (runtimeEnv) => {
|
|
25
|
+
if (isTruthyFlag(runtimeEnv['ZIN_WRANGLER_DEV_KEEP_API_TOKEN'])) {
|
|
26
|
+
return runtimeEnv;
|
|
27
|
+
}
|
|
28
|
+
if (!isNonEmptyString(runtimeEnv['CLOUDFLARE_API_TOKEN'])) {
|
|
29
|
+
return runtimeEnv;
|
|
30
|
+
}
|
|
31
|
+
Logger.warn('Ignoring CLOUDFLARE_API_TOKEN for local wrangler dev. Wrangler 4.92+ blocks interactive OAuth login when that variable is exported. Set ZIN_WRANGLER_DEV_KEEP_API_TOKEN=true to preserve token-based auth.');
|
|
32
|
+
const env = { ...runtimeEnv };
|
|
33
|
+
delete env['CLOUDFLARE_API_TOKEN'];
|
|
34
|
+
return env;
|
|
35
|
+
};
|
|
17
36
|
export const createWranglerProxyCommand = (input) => {
|
|
18
37
|
return BaseCommand.create({
|
|
19
38
|
name: input.name,
|
|
@@ -66,6 +85,7 @@ export const createWranglerProxyCommand = (input) => {
|
|
|
66
85
|
if (port !== undefined) {
|
|
67
86
|
args.push('--port', String(port));
|
|
68
87
|
}
|
|
88
|
+
const wranglerSpawnEnv = createWranglerDevSpawnEnv(process.env);
|
|
69
89
|
const exitCode = await withWranglerDevVarsSnapshot({
|
|
70
90
|
cwd: wranglerDevVarsCwd,
|
|
71
91
|
projectRoot,
|
|
@@ -76,7 +96,7 @@ export const createWranglerProxyCommand = (input) => {
|
|
|
76
96
|
return SpawnUtil.spawnAndWait({
|
|
77
97
|
command: 'wrangler',
|
|
78
98
|
args,
|
|
79
|
-
env:
|
|
99
|
+
env: wranglerSpawnEnv,
|
|
80
100
|
forwardSignals: false,
|
|
81
101
|
});
|
|
82
102
|
});
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v1.8.
|
|
2
|
+
* @zintrust/core v1.8.6
|
|
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-05-
|
|
8
|
+
* Built: 2026-05-19T17:44:54.279Z
|
|
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-05-
|
|
24
|
+
export const ZINTRUST_BUILD_DATE = '2026-05-19T17:44:54.246Z'; // 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":"SmtpProxyServer.d.ts","sourceRoot":"","sources":["../../../../src/proxy/smtp/SmtpProxyServer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SmtpProxyServer.d.ts","sourceRoot":"","sources":["../../../../src/proxy/smtp/SmtpProxyServer.ts"],"names":[],"mappings":"AAyBA,KAAK,cAAc,GAAG,OAAO,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AA6UH,eAAO,MAAM,eAAe;sBACH,cAAc,GAAQ,OAAO,CAAC,IAAI,CAAC;EA2B1D,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { Env } from '../../config/env.js';
|
|
|
3
3
|
import { Logger } from '../../config/logger.js';
|
|
4
4
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
5
|
import { isNonEmptyString, isObject } from '../../helper/index.js';
|
|
6
|
-
import { SmtpDriver
|
|
6
|
+
import { SmtpDriver } from '../../tools/mail/drivers/Smtp.js';
|
|
7
7
|
import { ErrorHandler } from '../ErrorHandler.js';
|
|
8
8
|
import { createProxyServer } from '../ProxyServer.js';
|
|
9
9
|
import { resolveProxySigningConfig } from '../ProxySigningConfigResolver.js';
|