@karmaniverous/get-dotenv 6.2.2 → 6.2.4
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/dist/chunks/AwsRestJsonProtocol-Bq1HE-Ln.mjs +932 -0
- package/dist/chunks/createCli-BY6_cfZr.mjs +439 -0
- package/dist/chunks/externalDataInterceptor-CbsdEYa-.mjs +19 -0
- package/dist/chunks/getSSOTokenFromFile-hUSpR7Wf.mjs +22 -0
- package/dist/chunks/helpConfig-CGejgwWW.mjs +12 -0
- package/dist/chunks/index-B5JKTBOL.mjs +443 -0
- package/dist/chunks/index-BEJFiHMX.mjs +522 -0
- package/dist/chunks/index-BPYF6K_G.mjs +82 -0
- package/dist/chunks/index-Bc3h0a95.mjs +374 -0
- package/dist/chunks/index-BpCF5UKx.mjs +272 -0
- package/dist/chunks/index-C_wqbTwI.mjs +187 -0
- package/dist/chunks/index-CeCufHlm.mjs +9374 -0
- package/dist/chunks/index-Cu7rdyqN.mjs +102 -0
- package/dist/chunks/index-DWAtHEA-.mjs +379 -0
- package/dist/chunks/index-Dp1Ip6Ra.mjs +354 -0
- package/dist/chunks/index-DyU5pKKi.mjs +24 -0
- package/dist/chunks/index-c7zKtEuy.mjs +578 -0
- package/dist/chunks/index-cIunyiUQ.mjs +702 -0
- package/dist/chunks/invoke-DuRPU1oC.mjs +60 -0
- package/dist/chunks/loadModuleDefault-Dj8B3Stt.mjs +123 -0
- package/dist/chunks/loadSso-w1eTVg0O.mjs +412 -0
- package/dist/chunks/loader-DnhPeGfq.mjs +346 -0
- package/dist/chunks/overlayEnv-Bs2kVayG.mjs +234 -0
- package/dist/chunks/package-boo9EyYs.mjs +5 -0
- package/dist/chunks/parseKnownFiles-B9cDK21V.mjs +23 -0
- package/dist/chunks/readMergedOptions-Nt0TR7dX.mjs +1626 -0
- package/dist/chunks/resolveCliOptions-TFRzhB2c.mjs +138 -0
- package/dist/chunks/sdk-stream-mixin-BZoJ5jy9.mjs +167 -0
- package/dist/chunks/spawnEnv-CN8a7cNR.mjs +306 -0
- package/dist/chunks/types-DJ-BGABd.mjs +59 -0
- package/dist/chunks/validate-CDl0rE6k.mjs +61 -0
- package/dist/cli.mjs +39 -19307
- package/dist/cliHost.mjs +20 -2800
- package/dist/config.mjs +10 -509
- package/dist/env-overlay.mjs +6 -337
- package/dist/getdotenv.cli.mjs +39 -19305
- package/dist/index.mjs +39 -19396
- package/dist/plugins-aws.d.ts +1 -4
- package/dist/plugins-aws.mjs +65 -2568
- package/dist/plugins-batch.mjs +16 -2573
- package/dist/plugins-cmd.mjs +19 -3094
- package/dist/plugins-init.d.ts +8 -0
- package/dist/plugins-init.mjs +85 -2297
- package/dist/plugins.mjs +36 -18817
- package/package.json +1 -2
- package/dist/templates/cli/index.ts +0 -25
- package/dist/templates/cli/plugins/hello/defaultAction.ts +0 -27
- package/dist/templates/cli/plugins/hello/index.ts +0 -26
- package/dist/templates/cli/plugins/hello/options.ts +0 -31
- package/dist/templates/cli/plugins/hello/strangerAction.ts +0 -20
- package/dist/templates/cli/plugins/hello/types.ts +0 -13
- package/dist/templates/config/js/getdotenv.config.js +0 -20
- package/dist/templates/config/json/local/getdotenv.config.local.json +0 -7
- package/dist/templates/config/json/public/getdotenv.config.json +0 -9
- package/dist/templates/config/public/getdotenv.config.json +0 -8
- package/dist/templates/config/ts/getdotenv.config.ts +0 -28
- package/dist/templates/config/yaml/local/getdotenv.config.local.yaml +0 -7
- package/dist/templates/config/yaml/public/getdotenv.config.yaml +0 -7
- package/dist/templates/defaultAction.ts +0 -27
- package/dist/templates/getdotenv.config.js +0 -20
- package/dist/templates/getdotenv.config.json +0 -9
- package/dist/templates/getdotenv.config.local.json +0 -7
- package/dist/templates/getdotenv.config.local.yaml +0 -7
- package/dist/templates/getdotenv.config.ts +0 -28
- package/dist/templates/getdotenv.config.yaml +0 -7
- package/dist/templates/hello/defaultAction.ts +0 -27
- package/dist/templates/hello/index.ts +0 -26
- package/dist/templates/hello/options.ts +0 -31
- package/dist/templates/hello/strangerAction.ts +0 -20
- package/dist/templates/hello/types.ts +0 -13
- package/dist/templates/index.ts +0 -26
- package/dist/templates/js/getdotenv.config.js +0 -20
- package/dist/templates/json/local/getdotenv.config.local.json +0 -7
- package/dist/templates/json/public/getdotenv.config.json +0 -9
- package/dist/templates/local/getdotenv.config.local.json +0 -7
- package/dist/templates/local/getdotenv.config.local.yaml +0 -7
- package/dist/templates/options.ts +0 -31
- package/dist/templates/plugins/hello/defaultAction.ts +0 -27
- package/dist/templates/plugins/hello/index.ts +0 -26
- package/dist/templates/plugins/hello/options.ts +0 -31
- package/dist/templates/plugins/hello/strangerAction.ts +0 -20
- package/dist/templates/plugins/hello/types.ts +0 -13
- package/dist/templates/public/getdotenv.config.json +0 -9
- package/dist/templates/public/getdotenv.config.yaml +0 -7
- package/dist/templates/strangerAction.ts +0 -20
- package/dist/templates/ts/getdotenv.config.ts +0 -28
- package/dist/templates/types.ts +0 -13
- package/dist/templates/yaml/local/getdotenv.config.local.yaml +0 -7
- package/dist/templates/yaml/public/getdotenv.config.yaml +0 -7
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { e as baseRootOptionDefaults, j as defaultsDeep } from './readMergedOptions-Nt0TR7dX.mjs';
|
|
2
|
+
import 'fs-extra';
|
|
3
|
+
import 'crypto';
|
|
4
|
+
import 'path';
|
|
5
|
+
import 'url';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Base CLI options derived from the shared root option defaults.
|
|
9
|
+
* Used for type-safe initialization of CLI options bags.
|
|
10
|
+
*/
|
|
11
|
+
const baseGetDotenvCliOptions = baseRootOptionDefaults;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a tri-state optional boolean flag under exactOptionalPropertyTypes.
|
|
15
|
+
* - If the user explicitly enabled the flag, return true.
|
|
16
|
+
* - If the user explicitly disabled (the "...-off" variant), return undefined (unset).
|
|
17
|
+
* - Otherwise, adopt the default (true → set; false/undefined → unset).
|
|
18
|
+
*
|
|
19
|
+
* @param exclude - The "on" flag value as parsed by Commander.
|
|
20
|
+
* @param excludeOff - The "off" toggle (present when specified) as parsed by Commander.
|
|
21
|
+
* @param defaultValue - The generator default to adopt when no explicit toggle is present.
|
|
22
|
+
* @returns boolean | undefined — use `undefined` to indicate "unset" (do not emit).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* resolveExclusion(undefined, undefined, true); // => true
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
const resolveExclusion = (exclude, excludeOff, defaultValue) => exclude ? true : excludeOff ? undefined : defaultValue ? true : undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve an optional flag with "--exclude-all" overrides.
|
|
32
|
+
* If excludeAll is set and the individual "...-off" is not, force true.
|
|
33
|
+
* If excludeAllOff is set and the individual flag is not explicitly set, unset.
|
|
34
|
+
* Otherwise, adopt the default (true → set; false/undefined → unset).
|
|
35
|
+
*
|
|
36
|
+
* @param exclude - Individual include/exclude flag.
|
|
37
|
+
* @param excludeOff - Individual "...-off" flag.
|
|
38
|
+
* @param defaultValue - Default for the individual flag.
|
|
39
|
+
* @param excludeAll - Global "exclude-all" flag.
|
|
40
|
+
* @param excludeAllOff - Global "exclude-all-off" flag.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* resolveExclusionAll(undefined, undefined, false, true, undefined) =\> true
|
|
44
|
+
*/
|
|
45
|
+
const resolveExclusionAll = (exclude, excludeOff, defaultValue, excludeAll, excludeAllOff) =>
|
|
46
|
+
// Order of precedence:
|
|
47
|
+
// 1) Individual explicit "on" wins outright.
|
|
48
|
+
// 2) Individual explicit "off" wins over any global.
|
|
49
|
+
// 3) Global exclude-all forces true when not explicitly turned off.
|
|
50
|
+
// 4) Global exclude-all-off unsets when the individual wasn't explicitly enabled.
|
|
51
|
+
// 5) Fall back to the default (true => set; false/undefined => unset).
|
|
52
|
+
(() => {
|
|
53
|
+
// Individual "on"
|
|
54
|
+
if (exclude === true)
|
|
55
|
+
return true;
|
|
56
|
+
// Individual "off"
|
|
57
|
+
if (excludeOff === true)
|
|
58
|
+
return undefined;
|
|
59
|
+
// Global "exclude-all" ON (unless explicitly turned off)
|
|
60
|
+
if (excludeAll === true)
|
|
61
|
+
return true;
|
|
62
|
+
// Global "exclude-all-off" (unless explicitly enabled)
|
|
63
|
+
if (excludeAllOff === true)
|
|
64
|
+
return undefined;
|
|
65
|
+
// Default
|
|
66
|
+
return defaultValue ? true : undefined;
|
|
67
|
+
})();
|
|
68
|
+
/**
|
|
69
|
+
* exactOptionalPropertyTypes-safe setter for optional boolean flags:
|
|
70
|
+
* delete when undefined; assign when defined — without requiring an index signature on T.
|
|
71
|
+
*
|
|
72
|
+
* @typeParam T - Target object type.
|
|
73
|
+
* @param obj - The object to write to.
|
|
74
|
+
* @param key - The optional boolean property key of {@link T}.
|
|
75
|
+
* @param value - The value to set or `undefined` to unset.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* Writes through a local `Record<string, unknown>` view to avoid requiring an index signature on {@link T}.
|
|
79
|
+
*/
|
|
80
|
+
const setOptionalFlag = (obj, key, value) => {
|
|
81
|
+
const target = obj;
|
|
82
|
+
const k = key;
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
84
|
+
if (value === undefined)
|
|
85
|
+
delete target[k];
|
|
86
|
+
else
|
|
87
|
+
target[k] = value;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Merge and normalize raw Commander options (current + parent + defaults)
|
|
92
|
+
* into a GetDotenvCliOptions-like object. Types are intentionally wide to
|
|
93
|
+
* avoid cross-layer coupling; callers may cast as needed.
|
|
94
|
+
*/
|
|
95
|
+
const resolveCliOptions = (rawCliOptions, defaults, parentJson) => {
|
|
96
|
+
const parent = typeof parentJson === 'string' && parentJson.length > 0
|
|
97
|
+
? JSON.parse(parentJson)
|
|
98
|
+
: undefined;
|
|
99
|
+
const { command, debugOff, excludeAll, excludeAllOff, excludeDynamicOff, excludeEnvOff, excludeGlobalOff, excludePrivateOff, excludePublicOff, loadProcessOff, logOff, entropyWarn, entropyWarnOff, scripts, shellOff, ...rest } = rawCliOptions;
|
|
100
|
+
const current = { ...rest };
|
|
101
|
+
if (typeof scripts === 'string') {
|
|
102
|
+
try {
|
|
103
|
+
current.scripts = JSON.parse(scripts);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// ignore parse errors; leave scripts undefined
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const merged = defaultsDeep({}, defaults, parent ?? {}, current);
|
|
110
|
+
const d = defaults;
|
|
111
|
+
setOptionalFlag(merged, 'debug', resolveExclusion(merged.debug, debugOff, d.debug));
|
|
112
|
+
setOptionalFlag(merged, 'excludeDynamic', resolveExclusionAll(merged.excludeDynamic, excludeDynamicOff, d.excludeDynamic, excludeAll, excludeAllOff));
|
|
113
|
+
setOptionalFlag(merged, 'excludeEnv', resolveExclusionAll(merged.excludeEnv, excludeEnvOff, d.excludeEnv, excludeAll, excludeAllOff));
|
|
114
|
+
setOptionalFlag(merged, 'excludeGlobal', resolveExclusionAll(merged.excludeGlobal, excludeGlobalOff, d.excludeGlobal, excludeAll, excludeAllOff));
|
|
115
|
+
setOptionalFlag(merged, 'excludePrivate', resolveExclusionAll(merged.excludePrivate, excludePrivateOff, d.excludePrivate, excludeAll, excludeAllOff));
|
|
116
|
+
setOptionalFlag(merged, 'excludePublic', resolveExclusionAll(merged.excludePublic, excludePublicOff, d.excludePublic, excludeAll, excludeAllOff));
|
|
117
|
+
setOptionalFlag(merged, 'log', resolveExclusion(merged.log, logOff, d.log));
|
|
118
|
+
setOptionalFlag(merged, 'loadProcess', resolveExclusion(merged.loadProcess, loadProcessOff, d.loadProcess));
|
|
119
|
+
// warnEntropy (tri-state)
|
|
120
|
+
setOptionalFlag(merged, 'warnEntropy', resolveExclusion(merged.warnEntropy, entropyWarnOff, d.warnEntropy));
|
|
121
|
+
// Normalize shell for predictability: explicit default shell per OS.
|
|
122
|
+
const defaultShell = process.platform === 'win32' ? 'powershell.exe' : '/bin/bash';
|
|
123
|
+
let resolvedShell = merged.shell;
|
|
124
|
+
if (shellOff)
|
|
125
|
+
resolvedShell = false;
|
|
126
|
+
else if (resolvedShell === true || resolvedShell === undefined) {
|
|
127
|
+
resolvedShell = defaultShell;
|
|
128
|
+
}
|
|
129
|
+
else if (typeof resolvedShell !== 'string' &&
|
|
130
|
+
typeof defaults.shell === 'string') {
|
|
131
|
+
resolvedShell = defaults.shell;
|
|
132
|
+
}
|
|
133
|
+
merged.shell = resolvedShell;
|
|
134
|
+
const cmd = typeof command === 'string' ? command : undefined;
|
|
135
|
+
return cmd !== undefined ? { merged, command: cmd } : { merged };
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export { baseGetDotenvCliOptions as b, resolveCliOptions as r };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { m as fromBase64, n as toBase64, o as toHex, t as toUtf8, q as fromArrayBuffer, r as streamCollector$1 } from './index-CeCufHlm.mjs';
|
|
2
|
+
import { Readable } from 'stream';
|
|
3
|
+
|
|
4
|
+
const isReadableStream = (stream) => typeof ReadableStream === "function" &&
|
|
5
|
+
(stream?.constructor?.name === ReadableStream.name || stream instanceof ReadableStream);
|
|
6
|
+
|
|
7
|
+
const streamCollector = async (stream) => {
|
|
8
|
+
if ((typeof Blob === "function" && stream instanceof Blob) || stream.constructor?.name === "Blob") {
|
|
9
|
+
if (Blob.prototype.arrayBuffer !== undefined) {
|
|
10
|
+
return new Uint8Array(await stream.arrayBuffer());
|
|
11
|
+
}
|
|
12
|
+
return collectBlob(stream);
|
|
13
|
+
}
|
|
14
|
+
return collectStream(stream);
|
|
15
|
+
};
|
|
16
|
+
async function collectBlob(blob) {
|
|
17
|
+
const base64 = await readToBase64(blob);
|
|
18
|
+
const arrayBuffer = fromBase64(base64);
|
|
19
|
+
return new Uint8Array(arrayBuffer);
|
|
20
|
+
}
|
|
21
|
+
async function collectStream(stream) {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
const reader = stream.getReader();
|
|
24
|
+
let isDone = false;
|
|
25
|
+
let length = 0;
|
|
26
|
+
while (!isDone) {
|
|
27
|
+
const { done, value } = await reader.read();
|
|
28
|
+
if (value) {
|
|
29
|
+
chunks.push(value);
|
|
30
|
+
length += value.length;
|
|
31
|
+
}
|
|
32
|
+
isDone = done;
|
|
33
|
+
}
|
|
34
|
+
const collected = new Uint8Array(length);
|
|
35
|
+
let offset = 0;
|
|
36
|
+
for (const chunk of chunks) {
|
|
37
|
+
collected.set(chunk, offset);
|
|
38
|
+
offset += chunk.length;
|
|
39
|
+
}
|
|
40
|
+
return collected;
|
|
41
|
+
}
|
|
42
|
+
function readToBase64(blob) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const reader = new FileReader();
|
|
45
|
+
reader.onloadend = () => {
|
|
46
|
+
if (reader.readyState !== 2) {
|
|
47
|
+
return reject(new Error("Reader aborted too early"));
|
|
48
|
+
}
|
|
49
|
+
const result = (reader.result ?? "");
|
|
50
|
+
const commaIndex = result.indexOf(",");
|
|
51
|
+
const dataOffset = commaIndex > -1 ? commaIndex + 1 : result.length;
|
|
52
|
+
resolve(result.substring(dataOffset));
|
|
53
|
+
};
|
|
54
|
+
reader.onabort = () => reject(new Error("Read aborted"));
|
|
55
|
+
reader.onerror = () => reject(reader.error);
|
|
56
|
+
reader.readAsDataURL(blob);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED$1 = "The stream has already been transformed.";
|
|
61
|
+
const sdkStreamMixin$1 = (stream) => {
|
|
62
|
+
if (!isBlobInstance(stream) && !isReadableStream(stream)) {
|
|
63
|
+
const name = stream?.__proto__?.constructor?.name || stream;
|
|
64
|
+
throw new Error(`Unexpected stream implementation, expect Blob or ReadableStream, got ${name}`);
|
|
65
|
+
}
|
|
66
|
+
let transformed = false;
|
|
67
|
+
const transformToByteArray = async () => {
|
|
68
|
+
if (transformed) {
|
|
69
|
+
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED$1);
|
|
70
|
+
}
|
|
71
|
+
transformed = true;
|
|
72
|
+
return await streamCollector(stream);
|
|
73
|
+
};
|
|
74
|
+
const blobToWebStream = (blob) => {
|
|
75
|
+
if (typeof blob.stream !== "function") {
|
|
76
|
+
throw new Error("Cannot transform payload Blob to web stream. Please make sure the Blob.stream() is polyfilled.\n" +
|
|
77
|
+
"If you are using React Native, this API is not yet supported, see: https://react-native.canny.io/feature-requests/p/fetch-streaming-body");
|
|
78
|
+
}
|
|
79
|
+
return blob.stream();
|
|
80
|
+
};
|
|
81
|
+
return Object.assign(stream, {
|
|
82
|
+
transformToByteArray: transformToByteArray,
|
|
83
|
+
transformToString: async (encoding) => {
|
|
84
|
+
const buf = await transformToByteArray();
|
|
85
|
+
if (encoding === "base64") {
|
|
86
|
+
return toBase64(buf);
|
|
87
|
+
}
|
|
88
|
+
else if (encoding === "hex") {
|
|
89
|
+
return toHex(buf);
|
|
90
|
+
}
|
|
91
|
+
else if (encoding === undefined || encoding === "utf8" || encoding === "utf-8") {
|
|
92
|
+
return toUtf8(buf);
|
|
93
|
+
}
|
|
94
|
+
else if (typeof TextDecoder === "function") {
|
|
95
|
+
return new TextDecoder(encoding).decode(buf);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
throw new Error("TextDecoder is not available, please make sure polyfill is provided.");
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
transformToWebStream: () => {
|
|
102
|
+
if (transformed) {
|
|
103
|
+
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED$1);
|
|
104
|
+
}
|
|
105
|
+
transformed = true;
|
|
106
|
+
if (isBlobInstance(stream)) {
|
|
107
|
+
return blobToWebStream(stream);
|
|
108
|
+
}
|
|
109
|
+
else if (isReadableStream(stream)) {
|
|
110
|
+
return stream;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
throw new Error(`Cannot transform payload to web stream, got ${stream}`);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
const isBlobInstance = (stream) => typeof Blob === "function" && stream instanceof Blob;
|
|
119
|
+
|
|
120
|
+
const ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED = "The stream has already been transformed.";
|
|
121
|
+
const sdkStreamMixin = (stream) => {
|
|
122
|
+
if (!(stream instanceof Readable)) {
|
|
123
|
+
try {
|
|
124
|
+
return sdkStreamMixin$1(stream);
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
const name = stream?.__proto__?.constructor?.name || stream;
|
|
128
|
+
throw new Error(`Unexpected stream implementation, expect Stream.Readable instance, got ${name}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
let transformed = false;
|
|
132
|
+
const transformToByteArray = async () => {
|
|
133
|
+
if (transformed) {
|
|
134
|
+
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED);
|
|
135
|
+
}
|
|
136
|
+
transformed = true;
|
|
137
|
+
return await streamCollector$1(stream);
|
|
138
|
+
};
|
|
139
|
+
return Object.assign(stream, {
|
|
140
|
+
transformToByteArray,
|
|
141
|
+
transformToString: async (encoding) => {
|
|
142
|
+
const buf = await transformToByteArray();
|
|
143
|
+
if (encoding === undefined || Buffer.isEncoding(encoding)) {
|
|
144
|
+
return fromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength).toString(encoding);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const decoder = new TextDecoder(encoding);
|
|
148
|
+
return decoder.decode(buf);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
transformToWebStream: () => {
|
|
152
|
+
if (transformed) {
|
|
153
|
+
throw new Error(ERR_MSG_STREAM_HAS_BEEN_TRANSFORMED);
|
|
154
|
+
}
|
|
155
|
+
if (stream.readableFlowing !== null) {
|
|
156
|
+
throw new Error("The stream has been consumed by other callbacks.");
|
|
157
|
+
}
|
|
158
|
+
if (typeof Readable.toWeb !== "function") {
|
|
159
|
+
throw new Error("Readable.toWeb() is not supported. Please ensure a polyfill is available.");
|
|
160
|
+
}
|
|
161
|
+
transformed = true;
|
|
162
|
+
return Readable.toWeb(stream);
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export { sdkStreamMixin as s };
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { execa, execaCommand } from 'execa';
|
|
2
|
+
import 'fs-extra';
|
|
3
|
+
import 'crypto';
|
|
4
|
+
import 'path';
|
|
5
|
+
import 'url';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Minimal tokenizer for shell-off execution.
|
|
9
|
+
* Splits by whitespace while preserving quoted segments (single or double quotes).
|
|
10
|
+
*
|
|
11
|
+
* @param command - The command string to tokenize.
|
|
12
|
+
* @param opts - Tokenization options (e.g. quote handling).
|
|
13
|
+
*/
|
|
14
|
+
const tokenize = (command, opts) => {
|
|
15
|
+
const out = [];
|
|
16
|
+
let cur = '';
|
|
17
|
+
let quote = null;
|
|
18
|
+
const preserve = opts && opts.preserveDoubledQuotes === true ? true : false;
|
|
19
|
+
for (let i = 0; i < command.length; i++) {
|
|
20
|
+
const c = command.charAt(i);
|
|
21
|
+
if (quote) {
|
|
22
|
+
if (c === quote) {
|
|
23
|
+
// Support doubled quotes inside a quoted segment:
|
|
24
|
+
// default: "" -> " and '' -> ' (Windows/PowerShell style)
|
|
25
|
+
// preserve: keep as "" to allow empty string literals in Node -e payloads
|
|
26
|
+
const next = command.charAt(i + 1);
|
|
27
|
+
if (next === quote) {
|
|
28
|
+
if (preserve) {
|
|
29
|
+
// Keep "" as-is; append both and continue within the quoted segment.
|
|
30
|
+
cur += quote + quote;
|
|
31
|
+
i += 1; // skip the second quote char (we already appended both)
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Collapse to a single literal quote
|
|
35
|
+
cur += quote;
|
|
36
|
+
i += 1; // skip the second quote
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// end of quoted segment
|
|
41
|
+
quote = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
cur += c;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
if (c === '"' || c === "'") {
|
|
50
|
+
quote = c;
|
|
51
|
+
}
|
|
52
|
+
else if (/\s/.test(c)) {
|
|
53
|
+
if (cur) {
|
|
54
|
+
out.push(cur);
|
|
55
|
+
cur = '';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
cur += c;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (cur)
|
|
64
|
+
out.push(cur);
|
|
65
|
+
return out;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const dbg = (...args) => {
|
|
69
|
+
if (process.env.GETDOTENV_DEBUG) {
|
|
70
|
+
// Use stderr to avoid interfering with stdout assertions
|
|
71
|
+
console.error('[getdotenv:run]', ...args);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Helper to decide whether to capture child stdio.
|
|
76
|
+
* Checks GETDOTENV_STDIO env var or the provided bag capture flag.
|
|
77
|
+
*/
|
|
78
|
+
const shouldCapture = (bagCapture) => process.env.GETDOTENV_STDIO === 'pipe' || Boolean(bagCapture);
|
|
79
|
+
// Strip repeated symmetric outer quotes (single or double) until stable.
|
|
80
|
+
// This is safe for argv arrays passed to execa (no quoting needed) and avoids
|
|
81
|
+
// passing quote characters through to Node (e.g., for `node -e "<code>"`).
|
|
82
|
+
// Handles stacked quotes from shells like PowerShell: """code""" -> code.
|
|
83
|
+
const stripOuterQuotes = (s) => {
|
|
84
|
+
let out = s;
|
|
85
|
+
// Repeatedly trim only when the entire string is wrapped in matching quotes.
|
|
86
|
+
// Stop as soon as the ends are asymmetric or no quotes remain.
|
|
87
|
+
while (out.length >= 2) {
|
|
88
|
+
const a = out.charAt(0);
|
|
89
|
+
const b = out.charAt(out.length - 1);
|
|
90
|
+
const symmetric = (a === '"' && b === '"') || (a === "'" && b === "'");
|
|
91
|
+
if (!symmetric)
|
|
92
|
+
break;
|
|
93
|
+
out = out.slice(1, -1);
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
};
|
|
97
|
+
// Extract exitCode/stdout/stderr from execa result or error in a tolerant way.
|
|
98
|
+
const pickResult = (r) => {
|
|
99
|
+
const exit = r.exitCode;
|
|
100
|
+
const stdoutVal = r.stdout;
|
|
101
|
+
const stderrVal = r.stderr;
|
|
102
|
+
return {
|
|
103
|
+
exitCode: typeof exit === 'number' ? exit : Number.NaN,
|
|
104
|
+
stdout: typeof stdoutVal === 'string' ? stdoutVal : '',
|
|
105
|
+
stderr: typeof stderrVal === 'string' ? stderrVal : '',
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
// Convert NodeJS.ProcessEnv (string | undefined values) to the shape execa
|
|
109
|
+
// expects (Readonly<Partial<Record<string, string>>>), dropping undefineds.
|
|
110
|
+
const sanitizeEnv = (env) => {
|
|
111
|
+
if (!env)
|
|
112
|
+
return undefined;
|
|
113
|
+
const entries = Object.entries(env).filter((e) => typeof e[1] === 'string');
|
|
114
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Core executor that normalizes shell/plain forms and capture/inherit modes.
|
|
118
|
+
* Returns captured buffers; callers may stream stdout when desired.
|
|
119
|
+
*/
|
|
120
|
+
async function _execNormalized(command, shell, opts = {}) {
|
|
121
|
+
const envSan = sanitizeEnv(opts.env);
|
|
122
|
+
const timeoutBits = typeof opts.timeoutMs === 'number'
|
|
123
|
+
? { timeout: opts.timeoutMs, killSignal: 'SIGKILL' }
|
|
124
|
+
: {};
|
|
125
|
+
const stdio = opts.stdio ?? 'pipe';
|
|
126
|
+
if (shell === false) {
|
|
127
|
+
let file;
|
|
128
|
+
let args = [];
|
|
129
|
+
if (typeof command === 'string') {
|
|
130
|
+
const tokens = tokenize(command);
|
|
131
|
+
file = tokens[0];
|
|
132
|
+
args = tokens.slice(1);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
file = command[0];
|
|
136
|
+
args = command.slice(1).map(stripOuterQuotes);
|
|
137
|
+
}
|
|
138
|
+
if (!file)
|
|
139
|
+
return { exitCode: 0, stdout: '', stderr: '' };
|
|
140
|
+
dbg('exec (plain)', { file, args, stdio });
|
|
141
|
+
try {
|
|
142
|
+
const ok = pickResult((await execa(file, args, {
|
|
143
|
+
...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
|
|
144
|
+
...(envSan !== undefined ? { env: envSan } : {}),
|
|
145
|
+
stdio,
|
|
146
|
+
...timeoutBits,
|
|
147
|
+
})));
|
|
148
|
+
dbg('exit (plain)', { exitCode: ok.exitCode });
|
|
149
|
+
return ok;
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
const out = pickResult(e);
|
|
153
|
+
dbg('exit:error (plain)', { exitCode: out.exitCode });
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Shell path (string|true|URL): execaCommand handles shell resolution.
|
|
158
|
+
const commandStr = typeof command === 'string' ? command : command.join(' ');
|
|
159
|
+
dbg('exec (shell)', {
|
|
160
|
+
command: commandStr,
|
|
161
|
+
shell: typeof shell === 'string' ? shell : 'custom',
|
|
162
|
+
stdio,
|
|
163
|
+
});
|
|
164
|
+
try {
|
|
165
|
+
const ok = pickResult((await execaCommand(commandStr, {
|
|
166
|
+
shell,
|
|
167
|
+
...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),
|
|
168
|
+
...(envSan !== undefined ? { env: envSan } : {}),
|
|
169
|
+
stdio,
|
|
170
|
+
...timeoutBits,
|
|
171
|
+
})));
|
|
172
|
+
dbg('exit (shell)', { exitCode: ok.exitCode });
|
|
173
|
+
return ok;
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
const out = pickResult(e);
|
|
177
|
+
dbg('exit:error (shell)', { exitCode: out.exitCode });
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Execute a command and capture stdout/stderr (buffered).
|
|
183
|
+
*
|
|
184
|
+
* @param command - Command string (shell) or argv array (shell-off supported).
|
|
185
|
+
* @param shell - Shell setting (false for plain execution).
|
|
186
|
+
* @param opts - Execution options (cwd/env/timeout).
|
|
187
|
+
* @returns A promise resolving to the captured result.
|
|
188
|
+
*/
|
|
189
|
+
async function runCommandResult(command, shell, opts = {}) {
|
|
190
|
+
// Build opts without injecting undefined (exactOptionalPropertyTypes-safe)
|
|
191
|
+
const coreOpts = { stdio: 'pipe' };
|
|
192
|
+
if (opts.cwd !== undefined) {
|
|
193
|
+
coreOpts.cwd = opts.cwd;
|
|
194
|
+
}
|
|
195
|
+
if (opts.env !== undefined) {
|
|
196
|
+
coreOpts.env = opts.env;
|
|
197
|
+
}
|
|
198
|
+
if (opts.timeoutMs !== undefined) {
|
|
199
|
+
coreOpts.timeoutMs = opts.timeoutMs;
|
|
200
|
+
}
|
|
201
|
+
return _execNormalized(command, shell, coreOpts);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Execute a command and return its exit code.
|
|
205
|
+
*
|
|
206
|
+
* @param command - Command string (shell) or argv array (shell-off supported).
|
|
207
|
+
* @param shell - Shell setting (false for plain execution).
|
|
208
|
+
* @param opts - Execution options (cwd/env/stdio).
|
|
209
|
+
* @returns A promise resolving to the process exit code.
|
|
210
|
+
*/
|
|
211
|
+
async function runCommand(command, shell, opts) {
|
|
212
|
+
// Build opts without injecting undefined (exactOptionalPropertyTypes-safe)
|
|
213
|
+
const callOpts = {};
|
|
214
|
+
if (opts.cwd !== undefined) {
|
|
215
|
+
callOpts.cwd = opts.cwd;
|
|
216
|
+
}
|
|
217
|
+
if (opts.env !== undefined) {
|
|
218
|
+
callOpts.env = opts.env;
|
|
219
|
+
}
|
|
220
|
+
if (opts.stdio !== undefined)
|
|
221
|
+
callOpts.stdio = opts.stdio;
|
|
222
|
+
const ok = await _execNormalized(command, shell, callOpts);
|
|
223
|
+
if (opts.stdio === 'pipe' && ok.stdout) {
|
|
224
|
+
process.stdout.write(ok.stdout + (ok.stdout.endsWith('\n') ? '' : '\n'));
|
|
225
|
+
}
|
|
226
|
+
return typeof ok.exitCode === 'number' ? ok.exitCode : Number.NaN;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Batch services (neutral): resolve command and shell settings.
|
|
231
|
+
* Shared by the generator path and the batch plugin to avoid circular deps.
|
|
232
|
+
*/
|
|
233
|
+
/**
|
|
234
|
+
* Resolve a command string from the {@link ScriptsTable} table.
|
|
235
|
+
* A script may be expressed as a string or an object with a `cmd` property.
|
|
236
|
+
*
|
|
237
|
+
* @param scripts - Optional scripts table.
|
|
238
|
+
* @param command - User-provided command name or string.
|
|
239
|
+
* @returns Resolved command string (falls back to the provided command).
|
|
240
|
+
*/
|
|
241
|
+
const resolveCommand = (scripts, command) => scripts && typeof scripts[command] === 'object'
|
|
242
|
+
? scripts[command].cmd
|
|
243
|
+
: (scripts?.[command] ?? command);
|
|
244
|
+
/**
|
|
245
|
+
* Resolve the shell setting for a given command:
|
|
246
|
+
* - If the script entry is an object, prefer its `shell` override.
|
|
247
|
+
* - Otherwise use the provided `shell` (string | boolean).
|
|
248
|
+
*
|
|
249
|
+
* @param scripts - Optional scripts table.
|
|
250
|
+
* @param command - User-provided command name or string.
|
|
251
|
+
* @param shell - Global shell preference (string | boolean).
|
|
252
|
+
*/
|
|
253
|
+
const resolveShell = (scripts, command, shell) => scripts && typeof scripts[command] === 'object'
|
|
254
|
+
? (scripts[command].shell ?? false)
|
|
255
|
+
: (shell ?? false);
|
|
256
|
+
|
|
257
|
+
const dropUndefined = (bag) => Object.fromEntries(Object.entries(bag).filter((e) => typeof e[1] === 'string'));
|
|
258
|
+
/**
|
|
259
|
+
* Build a sanitized environment object for spawning child processes.
|
|
260
|
+
* Merges `base` and `overlay`, drops undefined values, and handles platform-specific
|
|
261
|
+
* normalization (e.g. case-insensitivity on Windows).
|
|
262
|
+
*
|
|
263
|
+
* @param base - Base environment (usually `process.env`).
|
|
264
|
+
* @param overlay - Environment variables to overlay.
|
|
265
|
+
*/
|
|
266
|
+
const buildSpawnEnv = (base, overlay) => {
|
|
267
|
+
const raw = {
|
|
268
|
+
...(base ?? {}),
|
|
269
|
+
...(overlay ?? {}),
|
|
270
|
+
};
|
|
271
|
+
// Drop undefined first
|
|
272
|
+
const entries = Object.entries(dropUndefined(raw));
|
|
273
|
+
if (process.platform === 'win32') {
|
|
274
|
+
// Windows: keys are case-insensitive; collapse duplicates
|
|
275
|
+
const byLower = new Map();
|
|
276
|
+
for (const [k, v] of entries) {
|
|
277
|
+
byLower.set(k.toLowerCase(), [k, v]); // last wins; preserve latest casing
|
|
278
|
+
}
|
|
279
|
+
const out = {};
|
|
280
|
+
for (const [, [k, v]] of byLower)
|
|
281
|
+
out[k] = v;
|
|
282
|
+
// HOME fallback from USERPROFILE (common expectation)
|
|
283
|
+
if (!Object.prototype.hasOwnProperty.call(out, 'HOME')) {
|
|
284
|
+
const up = out['USERPROFILE'];
|
|
285
|
+
if (typeof up === 'string' && up.length > 0)
|
|
286
|
+
out['HOME'] = up;
|
|
287
|
+
}
|
|
288
|
+
// Normalize TMP/TEMP coherence (pick any present; reflect to both)
|
|
289
|
+
const tmp = out['TMP'] ?? out['TEMP'];
|
|
290
|
+
if (typeof tmp === 'string' && tmp.length > 0) {
|
|
291
|
+
out['TMP'] = tmp;
|
|
292
|
+
out['TEMP'] = tmp;
|
|
293
|
+
}
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
// POSIX: keep keys as-is
|
|
297
|
+
const out = Object.fromEntries(entries);
|
|
298
|
+
// Ensure TMPDIR exists when any temp key is present (best-effort)
|
|
299
|
+
const tmpdir = out['TMPDIR'] ?? out['TMP'] ?? out['TEMP'];
|
|
300
|
+
if (typeof tmpdir === 'string' && tmpdir.length > 0) {
|
|
301
|
+
out['TMPDIR'] = tmpdir;
|
|
302
|
+
}
|
|
303
|
+
return out;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export { runCommandResult as a, buildSpawnEnv as b, resolveCommand as c, resolveShell as d, runCommand as r, shouldCapture as s, tokenize as t };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { d as definePlugin } from './readMergedOptions-Nt0TR7dX.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a namespace-only parent plugin (a group command) for composing plugins
|
|
5
|
+
* under a shared prefix.
|
|
6
|
+
*
|
|
7
|
+
* This is a convenience wrapper around {@link definePlugin} that performs no
|
|
8
|
+
* action by default and exists only for command organization.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* program.use(
|
|
13
|
+
* groupPlugins({
|
|
14
|
+
* ns: 'getdotenv',
|
|
15
|
+
* description: 'getdotenv utility functions',
|
|
16
|
+
* aliases: ['gd'],
|
|
17
|
+
* }).use(initPlugin()),
|
|
18
|
+
* );
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @typeParam TOptions - The host option bag type.
|
|
22
|
+
* @param options - Group plugin options.
|
|
23
|
+
* @returns A plugin instance that can `.use(...)` child plugins.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
function groupPlugins(options) {
|
|
28
|
+
const ns = typeof options.ns === 'string' && options.ns.trim().length > 0
|
|
29
|
+
? options.ns.trim()
|
|
30
|
+
: '';
|
|
31
|
+
if (!ns)
|
|
32
|
+
throw new Error('groupPlugins: options.ns must be a non-empty string.');
|
|
33
|
+
return definePlugin({
|
|
34
|
+
ns,
|
|
35
|
+
async setup(cli) {
|
|
36
|
+
if (typeof options.description === 'string')
|
|
37
|
+
cli.description(options.description);
|
|
38
|
+
if (typeof options.summary === 'string')
|
|
39
|
+
cli.summary(options.summary);
|
|
40
|
+
if (typeof options.helpGroup === 'string')
|
|
41
|
+
cli.helpGroup(options.helpGroup);
|
|
42
|
+
if (Array.isArray(options.aliases) && options.aliases.length > 0) {
|
|
43
|
+
cli.aliases(options.aliases);
|
|
44
|
+
}
|
|
45
|
+
if (typeof options.configure === 'function') {
|
|
46
|
+
await options.configure(cli);
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Identity helper to define a scripts table while preserving a concrete TShell
|
|
55
|
+
* type parameter in downstream inference.
|
|
56
|
+
*/
|
|
57
|
+
const defineScripts = () => (t) => t;
|
|
58
|
+
|
|
59
|
+
export { defineScripts as d, groupPlugins as g };
|