dotsec 4.0.0-alpha.2 → 4.0.0-alpha.23
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/CHANGELOG.md +84 -0
- package/README.md +105 -63
- package/bin/dotsec.js +1 -1
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1379 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1368 -37
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.d.ts +234 -0
- package/dist/index.js +210 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +188 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import Ajv from 'ajv';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
export { default as Table } from 'cli-table';
|
|
5
|
+
|
|
6
|
+
declare const backgroundColors: readonly ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "black-bright", "gray", "grey", "red-bright", "green-bright", "yellow-bright", "blue-bright", "magenta-bright", "cyan-bright", "white-bright"];
|
|
7
|
+
type BackgroundColor = typeof backgroundColors[number];
|
|
8
|
+
|
|
9
|
+
type DotsecCliPluginHandler<HandlerArgs extends Record<string, unknown>, HandlerResult, T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
10
|
+
encryptionEngineName?: string;
|
|
11
|
+
triggerOptionValue: string;
|
|
12
|
+
usage?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
summary?: string;
|
|
15
|
+
options?: {
|
|
16
|
+
[key in keyof T]: DotsecCliOption;
|
|
17
|
+
};
|
|
18
|
+
requiredOptions?: {
|
|
19
|
+
[key in keyof T]: DotsecCliOption;
|
|
20
|
+
};
|
|
21
|
+
handler: (options: HandlerArgs & T) => Promise<HandlerResult>;
|
|
22
|
+
};
|
|
23
|
+
type DotsecCliPluginEncryptHandler<HandlerPluginArgs extends Record<string, unknown> = Record<string, unknown>> = DotsecCliPluginHandler<{
|
|
24
|
+
plaintext: string;
|
|
25
|
+
ciphertext?: string;
|
|
26
|
+
}, string, HandlerPluginArgs>;
|
|
27
|
+
type DotsecCliPluginDecryptHandler<HandlerPluginArgs extends Record<string, unknown> = Record<string, unknown>> = DotsecCliPluginHandler<{
|
|
28
|
+
ciphertext: string;
|
|
29
|
+
}, string, HandlerPluginArgs>;
|
|
30
|
+
type DotsecCliPluginRunHandler<HandlerPluginArgs extends Record<string, unknown> = Record<string, unknown>> = DotsecCliPluginHandler<{
|
|
31
|
+
ciphertext: string;
|
|
32
|
+
}, string, HandlerPluginArgs>;
|
|
33
|
+
type DotsecCliPluginPushHandler<HandlerPluginArgs extends Record<string, unknown> = Record<string, unknown>> = DotsecCliPluginHandler<{
|
|
34
|
+
push: Record<string, string>;
|
|
35
|
+
yes?: boolean;
|
|
36
|
+
}, string, HandlerPluginArgs>;
|
|
37
|
+
type DotsecCliOption = [
|
|
38
|
+
flags: string,
|
|
39
|
+
description?: string,
|
|
40
|
+
defaultValue?: string | boolean | string[]
|
|
41
|
+
] | {
|
|
42
|
+
flags: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
defaultValue?: string | boolean | string[];
|
|
45
|
+
choices?: string[];
|
|
46
|
+
fn?: (value: string, previous: unknown) => unknown;
|
|
47
|
+
regexp?: RegExp;
|
|
48
|
+
env?: string;
|
|
49
|
+
};
|
|
50
|
+
type DotsecPluginConfig = {
|
|
51
|
+
name?: string;
|
|
52
|
+
config?: {
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
};
|
|
55
|
+
push?: {
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
type DotsecPlugins = {
|
|
60
|
+
plugins: DotsecPluginUserConfigWithNamespace;
|
|
61
|
+
};
|
|
62
|
+
type Meh<T extends DotsecPluginModuleConfig> = T extends DotsecPluginModuleConfig ? T : never;
|
|
63
|
+
type DotsecPluginModuleConfig = {
|
|
64
|
+
plugin: DotsecPluginUserConfigWithNamespace;
|
|
65
|
+
api?: Record<string, unknown>;
|
|
66
|
+
cliHandlersOptions?: {
|
|
67
|
+
encrypt?: Record<string, unknown>;
|
|
68
|
+
decrypt?: Record<string, unknown>;
|
|
69
|
+
run?: Record<string, unknown>;
|
|
70
|
+
push?: Record<string, unknown>;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
type DotsecPluginModuleBuilderConfig = {
|
|
74
|
+
[key: string]: {
|
|
75
|
+
userConfig: DotsecPluginConfig;
|
|
76
|
+
api?: Record<string, unknown>;
|
|
77
|
+
cliHandlersOptions?: {
|
|
78
|
+
encrypt?: Record<string, unknown>;
|
|
79
|
+
decrypt?: Record<string, unknown>;
|
|
80
|
+
run?: Record<string, unknown>;
|
|
81
|
+
push?: Record<string, unknown>;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
type DotsecPluginModule<T extends DotsecPluginModuleConfig = DotsecPluginModuleConfig> = (options: {
|
|
86
|
+
dotsecConfig: DotsecConfig<{
|
|
87
|
+
plugins: T["plugin"];
|
|
88
|
+
}>;
|
|
89
|
+
ajv: Ajv;
|
|
90
|
+
configFile: string;
|
|
91
|
+
}) => Promise<{
|
|
92
|
+
name: keyof T["plugin"] | string;
|
|
93
|
+
encryptionEngineName?: string;
|
|
94
|
+
api?: T["api"] extends Record<string, unknown> ? T["api"] : never;
|
|
95
|
+
addCliCommand?: (options: {
|
|
96
|
+
program: Command;
|
|
97
|
+
}) => Promise<void>;
|
|
98
|
+
cliHandlers?: {
|
|
99
|
+
encrypt?: DotsecCliPluginEncryptHandler<T["cliHandlersOptions"] extends {
|
|
100
|
+
encrypt: Record<string, unknown>;
|
|
101
|
+
} ? T["cliHandlersOptions"]["encrypt"] : Record<string, unknown>>;
|
|
102
|
+
decrypt?: DotsecCliPluginDecryptHandler<T["cliHandlersOptions"] extends {
|
|
103
|
+
decrypt: Record<string, unknown>;
|
|
104
|
+
} ? T["cliHandlersOptions"]["decrypt"] : Record<string, unknown>>;
|
|
105
|
+
run?: DotsecCliPluginRunHandler<T["cliHandlersOptions"] extends {
|
|
106
|
+
run: Record<string, unknown>;
|
|
107
|
+
} ? T["cliHandlersOptions"]["run"] : Record<string, unknown>>;
|
|
108
|
+
push?: DotsecCliPluginPushHandler<T["cliHandlersOptions"] extends {
|
|
109
|
+
push: Record<string, unknown>;
|
|
110
|
+
} ? T["cliHandlersOptions"]["push"] : Record<string, unknown>>;
|
|
111
|
+
};
|
|
112
|
+
}>;
|
|
113
|
+
type DotsecPluginModuleBuilder<T extends DotsecPluginModuleBuilderConfig = DotsecPluginModuleBuilderConfig> = {
|
|
114
|
+
[pluginName: string]: {
|
|
115
|
+
userConfig: T[keyof T]["userConfig"];
|
|
116
|
+
module: (options: {
|
|
117
|
+
dotsecConfig: DotsecConfig<{
|
|
118
|
+
plugins: {
|
|
119
|
+
[key in keyof T]: T[keyof T]["userConfig"];
|
|
120
|
+
};
|
|
121
|
+
}>;
|
|
122
|
+
ajv: Ajv;
|
|
123
|
+
configFile: string;
|
|
124
|
+
}) => Promise<{
|
|
125
|
+
name: keyof T["userConfig"] | string;
|
|
126
|
+
encryptionEngineName?: string;
|
|
127
|
+
api?: T["api"] extends Record<string, unknown> ? T["api"] : never;
|
|
128
|
+
addCliCommand?: (options: {
|
|
129
|
+
program: Command;
|
|
130
|
+
}) => Promise<void>;
|
|
131
|
+
cliHandlers?: {
|
|
132
|
+
encrypt?: DotsecCliPluginEncryptHandler<T["cliHandlersOptions"] extends {
|
|
133
|
+
encrypt: Record<string, unknown>;
|
|
134
|
+
} ? T["cliHandlersOptions"]["encrypt"] : Record<string, unknown>>;
|
|
135
|
+
decrypt?: DotsecCliPluginDecryptHandler<T["cliHandlersOptions"] extends {
|
|
136
|
+
decrypt: Record<string, unknown>;
|
|
137
|
+
} ? T["cliHandlersOptions"]["decrypt"] : Record<string, unknown>>;
|
|
138
|
+
run?: DotsecCliPluginRunHandler<T["cliHandlersOptions"] extends {
|
|
139
|
+
run: Record<string, unknown>;
|
|
140
|
+
} ? T["cliHandlersOptions"]["run"] : Record<string, unknown>>;
|
|
141
|
+
push?: DotsecCliPluginPushHandler<T["cliHandlersOptions"] extends {
|
|
142
|
+
push: Record<string, unknown>;
|
|
143
|
+
} ? T["cliHandlersOptions"]["push"] : Record<string, unknown>>;
|
|
144
|
+
};
|
|
145
|
+
}>;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
type DotsecPluginUserConfigWithNamespace<T extends {
|
|
149
|
+
[key: string]: DotsecPluginConfig;
|
|
150
|
+
} = {
|
|
151
|
+
[key: string]: DotsecPluginConfig;
|
|
152
|
+
}> = T;
|
|
153
|
+
|
|
154
|
+
type DotsecConfig<T extends DotsecPlugins = DotsecPlugins> = {
|
|
155
|
+
plugins?: Array<keyof T["plugins"]>;
|
|
156
|
+
defaults?: {
|
|
157
|
+
encryptionEngine?: keyof T["plugins"];
|
|
158
|
+
plugins?: {
|
|
159
|
+
[PluginKey in keyof T["plugins"]]?: {
|
|
160
|
+
name?: T["plugins"][PluginKey]["name"];
|
|
161
|
+
} & T["plugins"][PluginKey]["config"];
|
|
162
|
+
};
|
|
163
|
+
options?: {
|
|
164
|
+
envFile?: string;
|
|
165
|
+
secFile?: string;
|
|
166
|
+
createManifest?: boolean;
|
|
167
|
+
showRedacted?: boolean;
|
|
168
|
+
showOutputPrefix?: boolean;
|
|
169
|
+
outputPrefix?: string;
|
|
170
|
+
showBackgroundColor?: boolean;
|
|
171
|
+
outputBackgroundColor?: BackgroundColor;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
redaction?: {
|
|
175
|
+
ignore?: string[];
|
|
176
|
+
};
|
|
177
|
+
push?: {
|
|
178
|
+
[key: string]: {
|
|
179
|
+
[PluginKey in keyof T["plugins"]]?: T["plugins"][PluginKey]["push"];
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
type DotsecEncryptionEngineFactoryProps = {
|
|
185
|
+
verbose?: boolean;
|
|
186
|
+
};
|
|
187
|
+
type DotsecEncryptionEngine<T = Record<string, unknown>> = {
|
|
188
|
+
encrypt(plaintext: string, ciphertext?: string): Promise<string>;
|
|
189
|
+
decrypt(ciphertext: string): Promise<string>;
|
|
190
|
+
} & T;
|
|
191
|
+
type DotsecEncryptionEngineFactory<T = Record<string, unknown>, V extends Record<string, unknown> = Record<string, unknown>> = {
|
|
192
|
+
(options: DotsecEncryptionEngineFactoryProps & T): Promise<DotsecEncryptionEngine<V>>;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
type FromEnv<T extends string = string> = T | {
|
|
196
|
+
fromEnv: string;
|
|
197
|
+
required?: boolean;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
type ParseResult = {
|
|
201
|
+
type: "value" | "comment" | "whitespace";
|
|
202
|
+
key?: string;
|
|
203
|
+
value?: string;
|
|
204
|
+
raw?: string;
|
|
205
|
+
}[];
|
|
206
|
+
declare const parse: (src: string) => {
|
|
207
|
+
blocks: ParseResult;
|
|
208
|
+
obj: Record<string, string>;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
declare const promptExecute: ({ skip, message, execute, }: {
|
|
212
|
+
skip?: boolean | undefined;
|
|
213
|
+
message: string;
|
|
214
|
+
execute: () => unknown | Promise<unknown>;
|
|
215
|
+
}) => Promise<void>;
|
|
216
|
+
|
|
217
|
+
declare const resolveFromEnv: (options: {
|
|
218
|
+
fromEnvValue?: string;
|
|
219
|
+
env: NodeJS.ProcessEnv;
|
|
220
|
+
variables: Record<string, string>;
|
|
221
|
+
}) => string | undefined;
|
|
222
|
+
|
|
223
|
+
declare const readContentsFromFile: (filePath: string) => Promise<string>;
|
|
224
|
+
declare const writeContentsToFile: (filePath: string, contents: string) => Promise<void>;
|
|
225
|
+
declare const promptOverwriteIfFileExists: ({ filePath, skip, }: {
|
|
226
|
+
filePath: string;
|
|
227
|
+
skip?: boolean | undefined;
|
|
228
|
+
}) => Promise<prompts.Answers<"overwrite"> | undefined>;
|
|
229
|
+
|
|
230
|
+
declare const writeLine: (str: string) => void;
|
|
231
|
+
declare const emphasis: (str: string) => string;
|
|
232
|
+
declare const strong: (str: string) => string;
|
|
233
|
+
|
|
234
|
+
export { DotsecConfig, DotsecEncryptionEngine, DotsecEncryptionEngineFactory, DotsecEncryptionEngineFactoryProps, DotsecPluginModule, DotsecPluginModuleBuilder, DotsecPluginModuleBuilderConfig, DotsecPluginUserConfigWithNamespace, FromEnv, Meh, ParseResult, emphasis, parse, promptExecute, promptOverwriteIfFileExists, readContentsFromFile, resolveFromEnv, strong, writeContentsToFile, writeLine };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,211 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var prompts = require('prompts');
|
|
4
|
+
var dotenvExpand = require('dotenv-expand');
|
|
5
|
+
var fs = require('fs/promises');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var chalk = require('chalk');
|
|
8
|
+
var cliTable = require('cli-table');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var prompts__default = /*#__PURE__*/_interopDefault(prompts);
|
|
13
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
14
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
15
|
+
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
16
|
+
var cliTable__default = /*#__PURE__*/_interopDefault(cliTable);
|
|
17
|
+
|
|
18
|
+
// src/lib/parse.ts
|
|
19
|
+
var LINE = /^(#.*)|(\s?\r?\n)|(?:^|^)\s*(?:export\s+)?([\w.-]*)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?(\s*)(#.*)?(?:$|$)/gm;
|
|
20
|
+
var parse = (src) => {
|
|
21
|
+
const obj = {};
|
|
22
|
+
const blocks = [];
|
|
23
|
+
let lines = src.toString();
|
|
24
|
+
lines = lines.replace(/\r\n?/gm, "\n");
|
|
25
|
+
let match;
|
|
26
|
+
while ((match = LINE.exec(lines)) != null) {
|
|
27
|
+
const key = match[3];
|
|
28
|
+
if (match?.[1]?.[0] === "#") {
|
|
29
|
+
blocks.push({ type: "comment", raw: match[1] });
|
|
30
|
+
} else if (match?.[2]) {
|
|
31
|
+
blocks.push({ type: "whitespace", raw: match[2] });
|
|
32
|
+
} else {
|
|
33
|
+
let value = match[4] || "";
|
|
34
|
+
value = value.trim();
|
|
35
|
+
const maybeQuote = value[0];
|
|
36
|
+
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
37
|
+
if (maybeQuote === '"') {
|
|
38
|
+
value = value.replace(/\\n/g, "\n");
|
|
39
|
+
value = value.replace(/\\r/g, "\r");
|
|
40
|
+
}
|
|
41
|
+
obj[key] = value;
|
|
42
|
+
blocks.push({
|
|
43
|
+
type: "value",
|
|
44
|
+
key,
|
|
45
|
+
value,
|
|
46
|
+
raw: value + (match[5] ? match[5] : "") + (match[6] ? match[6] : "")
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { blocks, obj };
|
|
51
|
+
};
|
|
52
|
+
if (undefined) {
|
|
53
|
+
const { it, expect } = undefined;
|
|
54
|
+
it("parse", () => {
|
|
55
|
+
const input1 = "KEY=value";
|
|
56
|
+
const input2 = 'KEY="value"';
|
|
57
|
+
const input3 = "KEY='value'";
|
|
58
|
+
const input4 = "KEY=value # this is a comment";
|
|
59
|
+
expect(parse(input1)).toMatchInlineSnapshot(`
|
|
60
|
+
{
|
|
61
|
+
"blocks": [
|
|
62
|
+
{
|
|
63
|
+
"key": "KEY",
|
|
64
|
+
"raw": "value",
|
|
65
|
+
"type": "value",
|
|
66
|
+
"value": "value",
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
"obj": {
|
|
70
|
+
"KEY": "value",
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
`);
|
|
74
|
+
expect(parse(input2)).toMatchInlineSnapshot(`
|
|
75
|
+
{
|
|
76
|
+
"blocks": [
|
|
77
|
+
{
|
|
78
|
+
"key": "KEY",
|
|
79
|
+
"raw": "value",
|
|
80
|
+
"type": "value",
|
|
81
|
+
"value": "value",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
"obj": {
|
|
85
|
+
"KEY": "value",
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
`);
|
|
89
|
+
expect(parse(input3)).toMatchInlineSnapshot(`
|
|
90
|
+
{
|
|
91
|
+
"blocks": [
|
|
92
|
+
{
|
|
93
|
+
"key": "KEY",
|
|
94
|
+
"raw": "value",
|
|
95
|
+
"type": "value",
|
|
96
|
+
"value": "value",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
"obj": {
|
|
100
|
+
"KEY": "value",
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
`);
|
|
104
|
+
expect(parse(input4)).toMatchInlineSnapshot(`
|
|
105
|
+
{
|
|
106
|
+
"blocks": [
|
|
107
|
+
{
|
|
108
|
+
"key": "KEY",
|
|
109
|
+
"raw": "value# this is a comment",
|
|
110
|
+
"type": "value",
|
|
111
|
+
"value": "value",
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
"obj": {
|
|
115
|
+
"KEY": "value",
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
`);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
var promptExecute = async ({
|
|
122
|
+
skip,
|
|
123
|
+
message,
|
|
124
|
+
execute
|
|
125
|
+
}) => {
|
|
126
|
+
let shouldExecute = false;
|
|
127
|
+
if (skip) {
|
|
128
|
+
shouldExecute = true;
|
|
129
|
+
} else {
|
|
130
|
+
const promptResponse = await prompts__default.default({
|
|
131
|
+
type: "confirm",
|
|
132
|
+
name: "confirm",
|
|
133
|
+
message
|
|
134
|
+
});
|
|
135
|
+
if (promptResponse.confirm === true) {
|
|
136
|
+
shouldExecute = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (shouldExecute) {
|
|
140
|
+
await execute();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var resolveFromEnv = (options) => {
|
|
144
|
+
const { fromEnvValue, env, variables } = options;
|
|
145
|
+
if (!fromEnvValue) {
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
return dotenvExpand.expand({
|
|
149
|
+
ignoreProcessEnv: true,
|
|
150
|
+
parsed: {
|
|
151
|
+
// add standard env variables
|
|
152
|
+
...env,
|
|
153
|
+
// add custom env variables, either from .env or .sec, (or empty object if none)
|
|
154
|
+
...variables,
|
|
155
|
+
RESOLVED: fromEnvValue || ""
|
|
156
|
+
}
|
|
157
|
+
}).parsed?.RESOLVED;
|
|
158
|
+
};
|
|
159
|
+
var readContentsFromFile = async (filePath) => {
|
|
160
|
+
return await fs__default.default.readFile(filePath, "utf-8");
|
|
161
|
+
};
|
|
162
|
+
var writeContentsToFile = async (filePath, contents) => {
|
|
163
|
+
return await fs__default.default.writeFile(filePath, contents, "utf-8");
|
|
164
|
+
};
|
|
165
|
+
var fileExists = async (source) => {
|
|
166
|
+
try {
|
|
167
|
+
await fs.stat(source);
|
|
168
|
+
return true;
|
|
169
|
+
} catch {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
var promptOverwriteIfFileExists = async ({
|
|
174
|
+
filePath,
|
|
175
|
+
skip
|
|
176
|
+
}) => {
|
|
177
|
+
let overwriteResponse;
|
|
178
|
+
if (await fileExists(filePath) && skip !== true) {
|
|
179
|
+
overwriteResponse = await prompts__default.default({
|
|
180
|
+
type: "confirm",
|
|
181
|
+
name: "overwrite",
|
|
182
|
+
message: () => {
|
|
183
|
+
return `Overwrite './${path__default.default.relative(process.cwd(), filePath)}' ?`;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
} else {
|
|
187
|
+
overwriteResponse = void 0;
|
|
188
|
+
}
|
|
189
|
+
return overwriteResponse;
|
|
190
|
+
};
|
|
191
|
+
var writeLine = (str) => {
|
|
192
|
+
process.stdout.write(str);
|
|
193
|
+
};
|
|
194
|
+
var emphasis = (str) => chalk__default.default.yellowBright(str);
|
|
195
|
+
var strong = (str) => chalk__default.default.yellow.bold(str);
|
|
196
|
+
|
|
197
|
+
Object.defineProperty(exports, 'Table', {
|
|
198
|
+
enumerable: true,
|
|
199
|
+
get: function () { return cliTable__default.default; }
|
|
200
|
+
});
|
|
201
|
+
exports.emphasis = emphasis;
|
|
202
|
+
exports.parse = parse;
|
|
203
|
+
exports.promptExecute = promptExecute;
|
|
204
|
+
exports.promptOverwriteIfFileExists = promptOverwriteIfFileExists;
|
|
205
|
+
exports.readContentsFromFile = readContentsFromFile;
|
|
206
|
+
exports.resolveFromEnv = resolveFromEnv;
|
|
207
|
+
exports.strong = strong;
|
|
208
|
+
exports.writeContentsToFile = writeContentsToFile;
|
|
209
|
+
exports.writeLine = writeLine;
|
|
210
|
+
//# sourceMappingURL=out.js.map
|
|
2
211
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/prompts.ts","../src/utils/fromEnv.ts","../src/lib/io.ts","../src/utils/logging.ts"],"sourcesContent":["export type {\n\tDotsecEncryptionEngine,\n\tDotsecEncryptionEngineFactory,\n\tDotsecEncryptionEngineFactoryProps,\n\tFromEnv,\n\tDotsecPluginUserConfigWithNamespace,\n\tDotsecPluginModule,\n\tDotsecPluginModuleBuilder,\n\tMeh,\n\tDotsecPluginModuleBuilderConfig,\n\tDotsecConfig,\n} from \"./types\";\nexport { promptExecute } from \"./utils/prompts\";\nexport { resolveFromEnv } from \"./utils/fromEnv\";\nexport {\n\tpromptOverwriteIfFileExists,\n\treadContentsFromFile,\n\twriteContentsToFile,\n} from \"./lib/io\";\n// import dotsec from \"./dotsec\";\n// export default dotsec;\n\nexport { Table, emphasis, strong, writeLine } from \"./utils/logging\";\n","import prompts from \"prompts\";\n\nexport const promptConfirm = async ({\n\tpredicate,\n\tskip,\n\tmessage,\n}: {\n\tpredicate?: (...args: unknown[]) => Promise<boolean> | boolean;\n\tskip?: boolean;\n\tmessage: string;\n}): Promise<boolean> => {\n\tif (skip === true) {\n\t\treturn true;\n\t} else {\n\t\tconst result = predicate ? await predicate() : true;\n\t\tif (result) {\n\t\t\tconst confirmResult = await prompts({\n\t\t\t\ttype: \"confirm\",\n\t\t\t\tname: \"confirm\",\n\t\t\t\tmessage: () => {\n\t\t\t\t\treturn message;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (confirmResult.confirm === true) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nexport const promptExecute = async ({\n\tskip,\n\tmessage,\n\texecute,\n}: {\n\tskip?: boolean;\n\tmessage: string;\n\texecute: () => unknown | Promise<unknown>;\n}) => {\n\tlet shouldExecute = false;\n\tif (skip) {\n\t\tshouldExecute = true;\n\t} else {\n\t\tconst promptResponse = await prompts({\n\t\t\ttype: \"confirm\",\n\t\t\tname: \"confirm\",\n\t\t\tmessage,\n\t\t});\n\n\t\tif (promptResponse.confirm === true) {\n\t\t\tshouldExecute = true;\n\t\t}\n\t}\n\n\tif (shouldExecute) {\n\t\tawait execute();\n\t}\n};\n","import { expand } from \"dotenv-expand\";\n\nexport const resolveFromEnv = (options: {\n\tfromEnvValue?: string;\n\tenv: NodeJS.ProcessEnv;\n\tvariables: Record<string, string>;\n}) => {\n\tconst { fromEnvValue, env, variables } = options;\n\n\tif (!fromEnvValue) {\n\t\treturn \"\";\n\t}\n\n\treturn (\n\t\texpand({\n\t\t\tignoreProcessEnv: true,\n\t\t\tparsed: {\n\t\t\t\t// add standard env variables\n\t\t\t\t...(env as Record<string, string>),\n\t\t\t\t// add custom env variables, either from .env or .sec, (or empty object if none)\n\t\t\t\t...variables,\n\t\t\t\tRESOLVED: fromEnvValue || \"\",\n\t\t\t},\n\t\t}) as { parsed?: { RESOLVED?: string } }\n\t).parsed?.RESOLVED;\n};\n","import fs, { stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport prompts from \"prompts\";\n\nexport const readContentsFromFile = async (\n\tfilePath: string,\n): Promise<string> => {\n\treturn await fs.readFile(filePath, \"utf-8\");\n};\n\nexport const writeContentsToFile = async (\n\tfilePath: string,\n\tcontents: string,\n): Promise<void> => {\n\treturn await fs.writeFile(filePath, contents, \"utf-8\");\n};\n\nexport const fileExists = async (source: string): Promise<boolean> => {\n\ttry {\n\t\tawait stat(source);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport const promptOverwriteIfFileExists = async ({\n\tfilePath,\n\tskip,\n}: {\n\tfilePath: string;\n\tskip?: boolean;\n}) => {\n\tlet overwriteResponse: prompts.Answers<\"overwrite\"> | undefined;\n\n\tif ((await fileExists(filePath)) && skip !== true) {\n\t\toverwriteResponse = await prompts({\n\t\t\ttype: \"confirm\",\n\t\t\tname: \"overwrite\",\n\t\t\tmessage: () => {\n\t\t\t\treturn `Overwrite './${path.relative(process.cwd(), filePath)}' ?`;\n\t\t\t},\n\t\t});\n\t} else {\n\t\toverwriteResponse = undefined;\n\t}\n\treturn overwriteResponse;\n};\n","import chalk from \"chalk\";\nimport Table from \"cli-table\";\nexport { Table };\n\nlet _logger: Pick<Console, \"info\" | \"error\" | \"table\">;\nexport const getLogger = () => {\n\tif (!_logger) {\n\t\t_logger = console;\n\t}\n\n\treturn _logger;\n};\nexport const writeLine = (str: string) => {\n\tprocess.stdout.write(str);\n};\nexport const emphasis = (str: string): string => chalk.yellowBright(str);\nexport const strong = (str: string): string => chalk.yellow.bold(str);\n\nexport const clientLogger = {\n\tdebug(content: object) {\n\t\tconsole.log(content);\n\t},\n\tinfo(content: object) {\n\t\tconsole.log(content);\n\t},\n\twarn(content: object) {\n\t\tconsole.log(content);\n\t},\n\terror(content: object) {\n\t\tconsole.error(content);\n\t},\n};\n"],"mappings":"6iBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,QAAA,aAAAC,EAAA,kBAAAC,EAAA,gCAAAC,EAAA,yBAAAC,EAAA,mBAAAC,EAAA,WAAAC,EAAA,wBAAAC,EAAA,cAAAC,IAAA,eAAAC,EAAAX,GCAA,IAAAY,EAAoB,sBAgCb,IAAMC,EAAgB,MAAO,CACnC,KAAAC,EACA,QAAAC,EACA,QAAAC,CACD,IAIM,CACL,IAAIC,EAAgB,IAChBH,IAGoB,QAAM,EAAAI,SAAQ,CACpC,KAAM,UACN,KAAM,UACN,QAAAH,CACD,CAAC,GAEkB,UAAY,MAC9BE,EAAgB,IAIdA,GACH,MAAMD,EAAQ,CAEhB,EC3DA,IAAAG,EAAuB,yBAEVC,EAAkBC,GAIzB,CACL,GAAM,CAAE,aAAAC,EAAc,IAAAC,EAAK,UAAAC,CAAU,EAAIH,EAEzC,OAAKC,KAKJ,UAAO,CACN,iBAAkB,GAClB,OAAQ,CAEP,GAAIC,EAEJ,GAAGC,EACH,SAAUF,GAAgB,EAC3B,CACD,CAAC,EACA,QAAQ,SAdF,EAeT,ECzBA,IAAAG,EAAyB,0BACzBC,EAAiB,mBACjBC,EAAoB,sBAEPC,EAAuB,MACnCC,GAEO,MAAM,EAAAC,QAAG,SAASD,EAAU,OAAO,EAG9BE,EAAsB,MAClCF,EACAG,IAEO,MAAM,EAAAF,QAAG,UAAUD,EAAUG,EAAU,OAAO,EAGzCC,EAAa,MAAOC,GAAqC,CACrE,GAAI,CACH,eAAM,QAAKA,CAAM,EACV,EACR,MAAE,CACD,MAAO,EACR,CACD,EAEaC,EAA8B,MAAO,CACjD,SAAAN,EACA,KAAAO,CACD,IAGM,CACL,IAAIC,EAEJ,OAAK,MAAMJ,EAAWJ,CAAQ,GAAMO,IAAS,GAC5CC,EAAoB,QAAM,EAAAC,SAAQ,CACjC,KAAM,UACN,KAAM,YACN,QAAS,IACD,gBAAgB,EAAAC,QAAK,SAAS,QAAQ,IAAI,EAAGV,CAAQ,MAE9D,CAAC,EAEDQ,EAAoB,OAEdA,CACR,EC/CA,IAAAG,EAAkB,oBAClBC,EAAkB,wBAWX,IAAMC,EAAaC,GAAgB,CACzC,QAAQ,OAAO,MAAMA,CAAG,CACzB,EACaC,EAAYD,GAAwB,EAAAE,QAAM,aAAaF,CAAG,EAC1DG,EAAUH,GAAwB,EAAAE,QAAM,OAAO,KAAKF,CAAG","names":["src_exports","__export","Table","emphasis","promptExecute","promptOverwriteIfFileExists","readContentsFromFile","resolveFromEnv","strong","writeContentsToFile","writeLine","__toCommonJS","import_prompts","promptExecute","skip","message","execute","shouldExecute","prompts","import_dotenv_expand","resolveFromEnv","options","fromEnvValue","env","variables","import_promises","import_node_path","import_prompts","readContentsFromFile","filePath","fs","writeContentsToFile","contents","fileExists","source","promptOverwriteIfFileExists","skip","overwriteResponse","prompts","path","import_chalk","import_cli_table","writeLine","str","emphasis","chalk","strong"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/parse.ts","../src/utils/prompts.ts","../src/utils/fromEnv.ts","../src/lib/io.ts","../src/utils/logging.ts"],"names":["prompts"],"mappings":"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","sourcesContent":["const LINE =\n\t/^(#.*)|(\\s?\\r?\\n)|(?:^|^)\\s*(?:export\\s+)?([\\w.-]*)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?(\\s*)(#.*)?(?:$|$)/gm;\n\nexport type ParseResult = {\n\ttype: \"value\" | \"comment\" | \"whitespace\";\n\tkey?: string;\n\tvalue?: string;\n\traw?: string;\n}[];\n\n// Parser src into an Object\nexport const parse = (src: string) => {\n\tconst obj: Record<string, string> = {};\n\tconst blocks: ParseResult = [];\n\n\t// Convert buffer to string\n\tlet lines = src.toString();\n\n\t// Convert line breaks to same format\n\tlines = lines.replace(/\\r\\n?/gm, \"\\n\");\n\n\tlet match;\n\twhile ((match = LINE.exec(lines)) != null) {\n\t\tconst key = match[3];\n\n\t\tif (match?.[1]?.[0] === \"#\") {\n\t\t\tblocks.push({ type: \"comment\", raw: match[1] });\n\t\t} else if (match?.[2]) {\n\t\t\tblocks.push({ type: \"whitespace\", raw: match[2] });\n\t\t} else {\n\t\t\t// Default undefined or null to empty string\n\t\t\tlet value = match[4] || \"\";\n\n\t\t\t// Remove whitespace\n\t\t\tvalue = value.trim();\n\n\t\t\t// Check if double quoted\n\t\t\tconst maybeQuote = value[0];\n\n\t\t\t// Remove surrounding quotes\n\t\t\tvalue = value.replace(/^(['\"`])([\\s\\S]*)\\1$/gm, \"$2\");\n\n\t\t\t// Expand newlines if double quoted\n\t\t\tif (maybeQuote === '\"') {\n\t\t\t\tvalue = value.replace(/\\\\n/g, \"\\n\");\n\t\t\t\tvalue = value.replace(/\\\\r/g, \"\\r\");\n\t\t\t}\n\n\t\t\tobj[key] = value;\n\n\t\t\t// Add to object\n\t\t\tblocks.push({\n\t\t\t\ttype: \"value\",\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\traw: value + (match[5] ? match[5] : \"\") + (match[6] ? match[6] : \"\"),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn { blocks, obj };\n};\n\nif (import.meta.vitest) {\n\tconst { it, expect } = import.meta.vitest;\n\n\tit(\"parse\", () => {\n\t\tconst input1 = \"KEY=value\";\n\t\tconst input2 = 'KEY=\"value\"';\n\t\tconst input3 = \"KEY='value'\";\n\t\tconst input4 = \"KEY=value # this is a comment\";\n\n\t\t// const expectedResult1 = [\n\t\t// { type: 'value', key: 'KEY', value: 'value', raw: 'value' },\n\t\t// ];\n\t\t// const expectedResult2 = [\n\t\t// { type: 'value', key: 'KEY', value: 'value', raw: '\"value\"' },\n\t\t// ];\n\t\t// const expectedResult3 = [\n\t\t// { type: 'value', key: 'KEY', value: 'value', raw: \"'value'\" },\n\t\t// ];\n\t\t// const expectedResult4 = [\n\t\t// {\n\t\t// type: 'value',\n\t\t// key: 'KEY',\n\t\t// value: 'value',\n\t\t// raw: 'value # this is a comment',\n\t\t// },\n\t\t// ];\n\n\t\texpect(parse(input1)).toMatchInlineSnapshot(`\n\t\t\t{\n\t\t\t \"blocks\": [\n\t\t\t {\n\t\t\t \"key\": \"KEY\",\n\t\t\t \"raw\": \"value\",\n\t\t\t \"type\": \"value\",\n\t\t\t \"value\": \"value\",\n\t\t\t },\n\t\t\t ],\n\t\t\t \"obj\": {\n\t\t\t \"KEY\": \"value\",\n\t\t\t },\n\t\t\t}\n\t\t`);\n\t\texpect(parse(input2)).toMatchInlineSnapshot(`\n\t\t\t{\n\t\t\t \"blocks\": [\n\t\t\t {\n\t\t\t \"key\": \"KEY\",\n\t\t\t \"raw\": \"value\",\n\t\t\t \"type\": \"value\",\n\t\t\t \"value\": \"value\",\n\t\t\t },\n\t\t\t ],\n\t\t\t \"obj\": {\n\t\t\t \"KEY\": \"value\",\n\t\t\t },\n\t\t\t}\n\t\t`);\n\t\texpect(parse(input3)).toMatchInlineSnapshot(`\n\t\t\t{\n\t\t\t \"blocks\": [\n\t\t\t {\n\t\t\t \"key\": \"KEY\",\n\t\t\t \"raw\": \"value\",\n\t\t\t \"type\": \"value\",\n\t\t\t \"value\": \"value\",\n\t\t\t },\n\t\t\t ],\n\t\t\t \"obj\": {\n\t\t\t \"KEY\": \"value\",\n\t\t\t },\n\t\t\t}\n\t\t`);\n\t\texpect(parse(input4)).toMatchInlineSnapshot(`\n {\n \"blocks\": [\n {\n \"key\": \"KEY\",\n \"raw\": \"value# this is a comment\",\n \"type\": \"value\",\n \"value\": \"value\",\n },\n ],\n \"obj\": {\n \"KEY\": \"value\",\n },\n }\n `);\n\t});\n}\n","import prompts from \"prompts\";\n\nexport const promptConfirm = async ({\n\tpredicate,\n\tskip,\n\tmessage,\n}: {\n\tpredicate?: (...args: unknown[]) => Promise<boolean> | boolean;\n\tskip?: boolean;\n\tmessage: string;\n}): Promise<boolean> => {\n\tif (skip === true) {\n\t\treturn true;\n\t} else {\n\t\tconst result = predicate ? await predicate() : true;\n\t\tif (result) {\n\t\t\tconst confirmResult = await prompts({\n\t\t\t\ttype: \"confirm\",\n\t\t\t\tname: \"confirm\",\n\t\t\t\tmessage: () => {\n\t\t\t\t\treturn message;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (confirmResult.confirm === true) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nexport const promptExecute = async ({\n\tskip,\n\tmessage,\n\texecute,\n}: {\n\tskip?: boolean;\n\tmessage: string;\n\texecute: () => unknown | Promise<unknown>;\n}) => {\n\tlet shouldExecute = false;\n\tif (skip) {\n\t\tshouldExecute = true;\n\t} else {\n\t\tconst promptResponse = await prompts({\n\t\t\ttype: \"confirm\",\n\t\t\tname: \"confirm\",\n\t\t\tmessage,\n\t\t});\n\n\t\tif (promptResponse.confirm === true) {\n\t\t\tshouldExecute = true;\n\t\t}\n\t}\n\n\tif (shouldExecute) {\n\t\tawait execute();\n\t}\n};\n","import { expand } from \"dotenv-expand\";\n\nexport const resolveFromEnv = (options: {\n\tfromEnvValue?: string;\n\tenv: NodeJS.ProcessEnv;\n\tvariables: Record<string, string>;\n}) => {\n\tconst { fromEnvValue, env, variables } = options;\n\n\tif (!fromEnvValue) {\n\t\treturn \"\";\n\t}\n\n\treturn (\n\t\texpand({\n\t\t\tignoreProcessEnv: true,\n\t\t\tparsed: {\n\t\t\t\t// add standard env variables\n\t\t\t\t...(env as Record<string, string>),\n\t\t\t\t// add custom env variables, either from .env or .sec, (or empty object if none)\n\t\t\t\t...variables,\n\t\t\t\tRESOLVED: fromEnvValue || \"\",\n\t\t\t},\n\t\t}) as { parsed?: { RESOLVED?: string } }\n\t).parsed?.RESOLVED;\n};\n","import fs, { stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport prompts from \"prompts\";\n\nexport const readContentsFromFile = async (\n\tfilePath: string,\n): Promise<string> => {\n\treturn await fs.readFile(filePath, \"utf-8\");\n};\n\nexport const writeContentsToFile = async (\n\tfilePath: string,\n\tcontents: string,\n): Promise<void> => {\n\treturn await fs.writeFile(filePath, contents, \"utf-8\");\n};\n\nexport const fileExists = async (source: string): Promise<boolean> => {\n\ttry {\n\t\tawait stat(source);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport const promptOverwriteIfFileExists = async ({\n\tfilePath,\n\tskip,\n}: {\n\tfilePath: string;\n\tskip?: boolean;\n}) => {\n\tlet overwriteResponse: prompts.Answers<\"overwrite\"> | undefined;\n\n\tif ((await fileExists(filePath)) && skip !== true) {\n\t\toverwriteResponse = await prompts({\n\t\t\ttype: \"confirm\",\n\t\t\tname: \"overwrite\",\n\t\t\tmessage: () => {\n\t\t\t\treturn `Overwrite './${path.relative(process.cwd(), filePath)}' ?`;\n\t\t\t},\n\t\t});\n\t} else {\n\t\toverwriteResponse = undefined;\n\t}\n\treturn overwriteResponse;\n};\n","import chalk from \"chalk\";\nimport Table from \"cli-table\";\nexport { Table };\n\nlet _logger: Pick<Console, \"info\" | \"error\" | \"table\">;\nexport const getLogger = () => {\n\tif (!_logger) {\n\t\t_logger = console;\n\t}\n\n\treturn _logger;\n};\nexport const writeLine = (str: string) => {\n\tprocess.stdout.write(str);\n};\nexport const emphasis = (str: string): string => chalk.yellowBright(str);\nexport const strong = (str: string): string => chalk.yellow.bold(str);\n\nexport const clientLogger = {\n\tdebug(content: object) {\n\t\tconsole.log(content);\n\t},\n\tinfo(content: object) {\n\t\tconsole.log(content);\n\t},\n\twarn(content: object) {\n\t\tconsole.log(content);\n\t},\n\terror(content: object) {\n\t\tconsole.error(content);\n\t},\n};\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,189 @@
|
|
|
1
|
-
import
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import { expand } from 'dotenv-expand';
|
|
3
|
+
import fs, { stat } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
export { default as Table } from 'cli-table';
|
|
7
|
+
|
|
8
|
+
// src/lib/parse.ts
|
|
9
|
+
var LINE = /^(#.*)|(\s?\r?\n)|(?:^|^)\s*(?:export\s+)?([\w.-]*)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?(\s*)(#.*)?(?:$|$)/gm;
|
|
10
|
+
var parse = (src) => {
|
|
11
|
+
const obj = {};
|
|
12
|
+
const blocks = [];
|
|
13
|
+
let lines = src.toString();
|
|
14
|
+
lines = lines.replace(/\r\n?/gm, "\n");
|
|
15
|
+
let match;
|
|
16
|
+
while ((match = LINE.exec(lines)) != null) {
|
|
17
|
+
const key = match[3];
|
|
18
|
+
if (match?.[1]?.[0] === "#") {
|
|
19
|
+
blocks.push({ type: "comment", raw: match[1] });
|
|
20
|
+
} else if (match?.[2]) {
|
|
21
|
+
blocks.push({ type: "whitespace", raw: match[2] });
|
|
22
|
+
} else {
|
|
23
|
+
let value = match[4] || "";
|
|
24
|
+
value = value.trim();
|
|
25
|
+
const maybeQuote = value[0];
|
|
26
|
+
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
27
|
+
if (maybeQuote === '"') {
|
|
28
|
+
value = value.replace(/\\n/g, "\n");
|
|
29
|
+
value = value.replace(/\\r/g, "\r");
|
|
30
|
+
}
|
|
31
|
+
obj[key] = value;
|
|
32
|
+
blocks.push({
|
|
33
|
+
type: "value",
|
|
34
|
+
key,
|
|
35
|
+
value,
|
|
36
|
+
raw: value + (match[5] ? match[5] : "") + (match[6] ? match[6] : "")
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { blocks, obj };
|
|
41
|
+
};
|
|
42
|
+
if (import.meta.vitest) {
|
|
43
|
+
const { it, expect } = import.meta.vitest;
|
|
44
|
+
it("parse", () => {
|
|
45
|
+
const input1 = "KEY=value";
|
|
46
|
+
const input2 = 'KEY="value"';
|
|
47
|
+
const input3 = "KEY='value'";
|
|
48
|
+
const input4 = "KEY=value # this is a comment";
|
|
49
|
+
expect(parse(input1)).toMatchInlineSnapshot(`
|
|
50
|
+
{
|
|
51
|
+
"blocks": [
|
|
52
|
+
{
|
|
53
|
+
"key": "KEY",
|
|
54
|
+
"raw": "value",
|
|
55
|
+
"type": "value",
|
|
56
|
+
"value": "value",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
"obj": {
|
|
60
|
+
"KEY": "value",
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
`);
|
|
64
|
+
expect(parse(input2)).toMatchInlineSnapshot(`
|
|
65
|
+
{
|
|
66
|
+
"blocks": [
|
|
67
|
+
{
|
|
68
|
+
"key": "KEY",
|
|
69
|
+
"raw": "value",
|
|
70
|
+
"type": "value",
|
|
71
|
+
"value": "value",
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
"obj": {
|
|
75
|
+
"KEY": "value",
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
`);
|
|
79
|
+
expect(parse(input3)).toMatchInlineSnapshot(`
|
|
80
|
+
{
|
|
81
|
+
"blocks": [
|
|
82
|
+
{
|
|
83
|
+
"key": "KEY",
|
|
84
|
+
"raw": "value",
|
|
85
|
+
"type": "value",
|
|
86
|
+
"value": "value",
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
"obj": {
|
|
90
|
+
"KEY": "value",
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
`);
|
|
94
|
+
expect(parse(input4)).toMatchInlineSnapshot(`
|
|
95
|
+
{
|
|
96
|
+
"blocks": [
|
|
97
|
+
{
|
|
98
|
+
"key": "KEY",
|
|
99
|
+
"raw": "value# this is a comment",
|
|
100
|
+
"type": "value",
|
|
101
|
+
"value": "value",
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
"obj": {
|
|
105
|
+
"KEY": "value",
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
`);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
var promptExecute = async ({
|
|
112
|
+
skip,
|
|
113
|
+
message,
|
|
114
|
+
execute
|
|
115
|
+
}) => {
|
|
116
|
+
let shouldExecute = false;
|
|
117
|
+
if (skip) {
|
|
118
|
+
shouldExecute = true;
|
|
119
|
+
} else {
|
|
120
|
+
const promptResponse = await prompts({
|
|
121
|
+
type: "confirm",
|
|
122
|
+
name: "confirm",
|
|
123
|
+
message
|
|
124
|
+
});
|
|
125
|
+
if (promptResponse.confirm === true) {
|
|
126
|
+
shouldExecute = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (shouldExecute) {
|
|
130
|
+
await execute();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var resolveFromEnv = (options) => {
|
|
134
|
+
const { fromEnvValue, env, variables } = options;
|
|
135
|
+
if (!fromEnvValue) {
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
138
|
+
return expand({
|
|
139
|
+
ignoreProcessEnv: true,
|
|
140
|
+
parsed: {
|
|
141
|
+
// add standard env variables
|
|
142
|
+
...env,
|
|
143
|
+
// add custom env variables, either from .env or .sec, (or empty object if none)
|
|
144
|
+
...variables,
|
|
145
|
+
RESOLVED: fromEnvValue || ""
|
|
146
|
+
}
|
|
147
|
+
}).parsed?.RESOLVED;
|
|
148
|
+
};
|
|
149
|
+
var readContentsFromFile = async (filePath) => {
|
|
150
|
+
return await fs.readFile(filePath, "utf-8");
|
|
151
|
+
};
|
|
152
|
+
var writeContentsToFile = async (filePath, contents) => {
|
|
153
|
+
return await fs.writeFile(filePath, contents, "utf-8");
|
|
154
|
+
};
|
|
155
|
+
var fileExists = async (source) => {
|
|
156
|
+
try {
|
|
157
|
+
await stat(source);
|
|
158
|
+
return true;
|
|
159
|
+
} catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var promptOverwriteIfFileExists = async ({
|
|
164
|
+
filePath,
|
|
165
|
+
skip
|
|
166
|
+
}) => {
|
|
167
|
+
let overwriteResponse;
|
|
168
|
+
if (await fileExists(filePath) && skip !== true) {
|
|
169
|
+
overwriteResponse = await prompts({
|
|
170
|
+
type: "confirm",
|
|
171
|
+
name: "overwrite",
|
|
172
|
+
message: () => {
|
|
173
|
+
return `Overwrite './${path.relative(process.cwd(), filePath)}' ?`;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} else {
|
|
177
|
+
overwriteResponse = void 0;
|
|
178
|
+
}
|
|
179
|
+
return overwriteResponse;
|
|
180
|
+
};
|
|
181
|
+
var writeLine = (str) => {
|
|
182
|
+
process.stdout.write(str);
|
|
183
|
+
};
|
|
184
|
+
var emphasis = (str) => chalk.yellowBright(str);
|
|
185
|
+
var strong = (str) => chalk.yellow.bold(str);
|
|
186
|
+
|
|
187
|
+
export { emphasis, parse, promptExecute, promptOverwriteIfFileExists, readContentsFromFile, resolveFromEnv, strong, writeContentsToFile, writeLine };
|
|
188
|
+
//# sourceMappingURL=out.js.map
|
|
2
189
|
//# sourceMappingURL=index.mjs.map
|