env-lane 0.1.0
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/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/cli.js +294 -0
- package/dist/index.cjs +24 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bill Toshiaki Stark
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# env-lane
|
|
2
|
+
|
|
3
|
+
CLI for workspace-aware dotenv injection and optional development vault helpers.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pnpm add -D env-lane
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
env-lane packages
|
|
11
|
+
env-lane files api --build production
|
|
12
|
+
env-lane print api --build production --format json
|
|
13
|
+
env-lane run api --build production -- pnpm start
|
|
14
|
+
env-lane check api --build production --require-override
|
|
15
|
+
env-lane sort env-lane.config.ts api production
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The package also re-exports `@env-lane/core` APIs for convenience.
|
|
19
|
+
|
|
20
|
+
Vault commands are optional and require installing `@env-lane/vault` alongside `env-lane`.
|
|
21
|
+
|
|
22
|
+
See the full documentation at https://github.com/billstark001/env-lane#readme.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import {
|
|
5
|
+
checkDotenvSelector,
|
|
6
|
+
getLogger,
|
|
7
|
+
listEnvFiles,
|
|
8
|
+
listWorkspacePackages,
|
|
9
|
+
loadEnvLaneConfig,
|
|
10
|
+
redactValue,
|
|
11
|
+
resolveInjectedEnv,
|
|
12
|
+
resolveTargetPackage,
|
|
13
|
+
runWithInjectedEnv,
|
|
14
|
+
setLogger,
|
|
15
|
+
sortEnvFile,
|
|
16
|
+
sortEnvFilesFromConfig
|
|
17
|
+
} from "@env-lane/core";
|
|
18
|
+
import { Command } from "commander";
|
|
19
|
+
import { createConsola } from "consola";
|
|
20
|
+
var consola = createConsola();
|
|
21
|
+
setLogger({
|
|
22
|
+
log: (msg, ...args) => consola.log(msg, ...args),
|
|
23
|
+
info: (msg, ...args) => consola.info(msg, ...args),
|
|
24
|
+
warn: (msg, ...args) => consola.warn(msg, ...args),
|
|
25
|
+
error: (msg, ...args) => consola.error(msg, ...args),
|
|
26
|
+
success: (msg, ...args) => consola.success(msg, ...args),
|
|
27
|
+
debug: (msg, ...args) => consola.debug(msg, ...args),
|
|
28
|
+
write: (msg) => process.stdout.write(msg)
|
|
29
|
+
});
|
|
30
|
+
var program = new Command();
|
|
31
|
+
program.name("env-lane").description("Workspace-aware dotenv injection and development vault tooling.").version("0.1.0").option("--format <format>", "output format (text, json, dotenv)").option("--json", "use json output format (shorthand for --format json)");
|
|
32
|
+
program.enablePositionalOptions();
|
|
33
|
+
function addCommonOptions(command) {
|
|
34
|
+
return command.option("-c, --config <file>", "env-lane config file").option("-b, --build <name>", "build selector value").option("--cwd <dir>", "working directory").option("--format <format>", "output format (text, json, dotenv)").option("--json", "use json output format (shorthand for --format json)");
|
|
35
|
+
}
|
|
36
|
+
async function resolveOutputFormat(opts, defaultFormat = "text") {
|
|
37
|
+
let format;
|
|
38
|
+
if (opts.json) {
|
|
39
|
+
format = "json";
|
|
40
|
+
} else if (opts.format) {
|
|
41
|
+
format = opts.format;
|
|
42
|
+
} else {
|
|
43
|
+
const config = await loadEnvLaneConfig({ configFile: opts.config, cwd: opts.cwd });
|
|
44
|
+
format = config.output.format ?? defaultFormat;
|
|
45
|
+
}
|
|
46
|
+
if (format === "json") {
|
|
47
|
+
consola.level = 2;
|
|
48
|
+
}
|
|
49
|
+
return format;
|
|
50
|
+
}
|
|
51
|
+
async function loadVaultModule() {
|
|
52
|
+
try {
|
|
53
|
+
return await import("@env-lane/vault");
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ERR_MODULE_NOT_FOUND" && error instanceof Error && error.message.includes("@env-lane/vault")) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"Vault commands require the optional @env-lane/vault package. Install it with: pnpm add -D @env-lane/vault"
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
addCommonOptions(program.command("packages")).description("List discovered workspace packages. Falls back to root in single-package projects.").action(async (opts) => {
|
|
64
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
65
|
+
const format = await resolveOutputFormat(allOpts, "text");
|
|
66
|
+
const packages = await listWorkspacePackages({ cwd: allOpts.cwd, configFile: allOpts.config });
|
|
67
|
+
const logger = getLogger();
|
|
68
|
+
if (format === "json") {
|
|
69
|
+
logger.log(JSON.stringify(packages, null, 2));
|
|
70
|
+
} else {
|
|
71
|
+
for (const pkg of packages)
|
|
72
|
+
logger.log(`${pkg.name ?? "<unnamed>"} ${pkg.relativeDir} ${pkg.aliases.join(",")}`);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
addCommonOptions(program.command("resolve-target <target>")).description("Resolve a target alias/name/path to a package.").action(async (target, opts) => {
|
|
76
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
77
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
78
|
+
const resolved = await resolveTargetPackage(target, {
|
|
79
|
+
cwd: allOpts.cwd,
|
|
80
|
+
configFile: allOpts.config
|
|
81
|
+
});
|
|
82
|
+
if (format === "json") {
|
|
83
|
+
getLogger().log(JSON.stringify(resolved, null, 2));
|
|
84
|
+
} else {
|
|
85
|
+
getLogger().log(`${resolved.name ?? "<unnamed>"} ${resolved.dir}`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
addCommonOptions(program.command("files [target]")).alias("env-files").description("List dotenv files in injection order.").option("--require-override", "fail if selected override file is missing").action(async (target, opts) => {
|
|
89
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
90
|
+
const format = await resolveOutputFormat(allOpts, "text");
|
|
91
|
+
if (target === "all") {
|
|
92
|
+
const packages = await listWorkspacePackages({ cwd: allOpts.cwd, configFile: allOpts.config });
|
|
93
|
+
const result = await Promise.all(
|
|
94
|
+
packages.map(async (pkg) => ({
|
|
95
|
+
target: pkg,
|
|
96
|
+
files: await listEnvFiles({
|
|
97
|
+
cwd: allOpts.cwd,
|
|
98
|
+
configFile: allOpts.config,
|
|
99
|
+
target: pkg.relativeDir,
|
|
100
|
+
build: allOpts.build,
|
|
101
|
+
requireOverride: allOpts.requireOverride
|
|
102
|
+
})
|
|
103
|
+
}))
|
|
104
|
+
);
|
|
105
|
+
if (format === "json") {
|
|
106
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
107
|
+
} else {
|
|
108
|
+
for (const entry of result) {
|
|
109
|
+
getLogger().log(`# ${entry.target.name ?? entry.target.relativeDir}`);
|
|
110
|
+
for (const file of entry.files)
|
|
111
|
+
getLogger().log(
|
|
112
|
+
`${file.exists ? "loaded " : "missing"} ${file.kind.padEnd(8)} ${file.relativePath}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const files = await listEnvFiles({
|
|
119
|
+
cwd: allOpts.cwd,
|
|
120
|
+
configFile: allOpts.config,
|
|
121
|
+
target,
|
|
122
|
+
build: allOpts.build,
|
|
123
|
+
requireOverride: allOpts.requireOverride
|
|
124
|
+
});
|
|
125
|
+
if (format === "json") {
|
|
126
|
+
getLogger().log(JSON.stringify(files, null, 2));
|
|
127
|
+
} else {
|
|
128
|
+
for (const file of files)
|
|
129
|
+
getLogger().log(
|
|
130
|
+
`${file.exists ? "loaded " : "missing"} ${file.kind.padEnd(8)} ${file.relativePath}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
addCommonOptions(program.command("print <target>")).alias("env-json").description("Print final injected environment for a target.").option("--show-secrets", "print secret-like values without redaction").option(
|
|
135
|
+
"--include-shell",
|
|
136
|
+
"print all shell environment variables, not only dotenv keys and the selector"
|
|
137
|
+
).option("--no-process-env", "do not merge process.env").action(async (target, opts) => {
|
|
138
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
139
|
+
const format = await resolveOutputFormat(allOpts, "dotenv");
|
|
140
|
+
const resolved = await resolveInjectedEnv({
|
|
141
|
+
cwd: allOpts.cwd,
|
|
142
|
+
configFile: allOpts.config,
|
|
143
|
+
target,
|
|
144
|
+
build: allOpts.build,
|
|
145
|
+
includeProcessEnv: allOpts.processEnv
|
|
146
|
+
});
|
|
147
|
+
const keys = Object.keys(resolved.values).filter(
|
|
148
|
+
(key) => allOpts.includeShell || resolved.sources[key]?.source !== "process" || resolved.sources[key]?.shellOverride
|
|
149
|
+
).sort();
|
|
150
|
+
if (format === "json") {
|
|
151
|
+
const payload = Object.fromEntries(
|
|
152
|
+
keys.map((key) => [
|
|
153
|
+
key,
|
|
154
|
+
{
|
|
155
|
+
value: redactValue(key, resolved.values[key], allOpts.showSecrets),
|
|
156
|
+
source: resolved.sources[key]
|
|
157
|
+
}
|
|
158
|
+
])
|
|
159
|
+
);
|
|
160
|
+
getLogger().log(JSON.stringify(payload, null, 2));
|
|
161
|
+
} else {
|
|
162
|
+
for (const key of keys)
|
|
163
|
+
getLogger().log(`${key}=${redactValue(key, resolved.values[key], allOpts.showSecrets)}`);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
addCommonOptions(
|
|
167
|
+
program.command("run <target>").argument("<command...>", "command and arguments to run").allowUnknownOption(true).passThroughOptions()
|
|
168
|
+
).description("Run a command with injected dotenv environment.").option("--run-cwd <target|root|path>", "command working directory", "target").option("--quiet", "suppress run summary").action(async (target, command, opts) => {
|
|
169
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
170
|
+
const format = await resolveOutputFormat(allOpts, "text");
|
|
171
|
+
const code = await runWithInjectedEnv({
|
|
172
|
+
cwd: allOpts.cwd,
|
|
173
|
+
configFile: allOpts.config,
|
|
174
|
+
target,
|
|
175
|
+
build: allOpts.build,
|
|
176
|
+
command,
|
|
177
|
+
runCwd: allOpts.runCwd,
|
|
178
|
+
quiet: allOpts.quiet || format === "json"
|
|
179
|
+
});
|
|
180
|
+
process.exit(code);
|
|
181
|
+
});
|
|
182
|
+
addCommonOptions(program.command("check [target]")).description("Check that the selector key is not stored in dotenv files.").option("--require-override", "fail if selected override file is missing").action(async (target, opts) => {
|
|
183
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
184
|
+
const format = await resolveOutputFormat(allOpts, "text");
|
|
185
|
+
const result = await checkDotenvSelector({
|
|
186
|
+
cwd: allOpts.cwd,
|
|
187
|
+
configFile: allOpts.config,
|
|
188
|
+
target,
|
|
189
|
+
build: allOpts.build,
|
|
190
|
+
requireOverride: allOpts.requireOverride
|
|
191
|
+
});
|
|
192
|
+
if (format === "json") {
|
|
193
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
194
|
+
if (!result.ok) process.exit(1);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (!result.ok) {
|
|
198
|
+
if (result.violations.length) {
|
|
199
|
+
getLogger().error(
|
|
200
|
+
`${result.selectorKey} must not be stored in dotenv files:
|
|
201
|
+
${result.violations.map((v) => ` ${v.relativeFile}${v.line ? `:${v.line}` : ""}`).join("\n")}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
if (result.missingRequired.length) {
|
|
205
|
+
getLogger().error(
|
|
206
|
+
`Missing required env file(s):
|
|
207
|
+
${result.missingRequired.map((file) => ` ${file.target}: ${file.relativeFile}`).join("\n")}`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
getLogger().success(`[env-lane] OK: ${result.selectorKey} is absent from dotenv files.`);
|
|
213
|
+
});
|
|
214
|
+
var vault = program.command("vault").description("Optional unsafe development vault helpers. Requires @env-lane/vault.");
|
|
215
|
+
addCommonOptions(vault.command("encrypt <config> <keyFile>")).action(
|
|
216
|
+
async (config, keyFile, opts) => {
|
|
217
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
218
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
219
|
+
const { encryptEnvFiles } = await loadVaultModule();
|
|
220
|
+
const result = await encryptEnvFiles(config, keyFile);
|
|
221
|
+
if (format === "json") {
|
|
222
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
223
|
+
} else {
|
|
224
|
+
getLogger().log(`Encrypted records to ${result.storePath}`);
|
|
225
|
+
getLogger().log(` Set: ${result.setRecordsWritten}`);
|
|
226
|
+
getLogger().log(` Delete: ${result.deleteRecordsWritten}`);
|
|
227
|
+
getLogger().log(` Skipped unchanged: ${result.skippedUnchanged}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
addCommonOptions(vault.command("plan <config> <keyFile>")).description("Print the vault restore plan without writing files.").action(async (config, keyFile, opts) => {
|
|
232
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
233
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
234
|
+
const { buildRestorePlan } = await loadVaultModule();
|
|
235
|
+
const result = await buildRestorePlan(config, keyFile);
|
|
236
|
+
if (format === "json") {
|
|
237
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
238
|
+
} else {
|
|
239
|
+
getLogger().log(`Restore plan for ${result.storePath}:`);
|
|
240
|
+
for (const file of result.files) {
|
|
241
|
+
const changes = file.entries.filter((e) => e.action !== "identical");
|
|
242
|
+
if (changes.length > 0) {
|
|
243
|
+
getLogger().log(`# ${file.filePath}`);
|
|
244
|
+
for (const e of changes) getLogger().log(` ${e.action.padEnd(10)} ${e.key}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
getLogger().log(`Summary: ${result.summary.filesWithChanges} files to change.`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
addCommonOptions(vault.command("decrypt <config> <keyFile>")).option("--dry-run", "show planned restore without writing files").option("-y, --yes", "apply restore without interactive confirmation").action(async (config, keyFile, opts) => {
|
|
251
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
252
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
253
|
+
const { decryptEnvFiles } = await loadVaultModule();
|
|
254
|
+
const result = await decryptEnvFiles(config, keyFile, {
|
|
255
|
+
dryRun: allOpts.dryRun,
|
|
256
|
+
autoApprove: allOpts.yes
|
|
257
|
+
});
|
|
258
|
+
if (format === "json") {
|
|
259
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
260
|
+
} else {
|
|
261
|
+
getLogger().log(`Decrypted ${result.filesWritten} files from ${result.storePath}`);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
addCommonOptions(program.command("sort-file <envFile> <templateFile>")).description("Sort one env file using a template env file.").action(async (envFile, templateFile, opts) => {
|
|
265
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
266
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
267
|
+
const result = await sortEnvFile(envFile, templateFile);
|
|
268
|
+
if (format === "json") {
|
|
269
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
270
|
+
} else {
|
|
271
|
+
getLogger().log(`${result.applied ? "Sorted" : "No changes for"} ${envFile}`);
|
|
272
|
+
if (result.applied) {
|
|
273
|
+
getLogger().log(` Moved: ${result.movedCount}`);
|
|
274
|
+
getLogger().log(` Inserted commented: ${result.insertedCommentedCount}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
addCommonOptions(program.command("sort <config> [key] [envSuffix]")).description("Sort env files using an env-lane config sort section.").action(async (config, key = "all", envSuffix = "all", opts) => {
|
|
279
|
+
const allOpts = { ...program.opts(), ...opts };
|
|
280
|
+
const format = await resolveOutputFormat(allOpts, "json");
|
|
281
|
+
const result = await sortEnvFilesFromConfig(config, key, envSuffix);
|
|
282
|
+
if (format === "json") {
|
|
283
|
+
getLogger().log(JSON.stringify(result, null, 2));
|
|
284
|
+
} else {
|
|
285
|
+
getLogger().log(`Sort applied: ${result.applied}`);
|
|
286
|
+
for (const r of result.results) {
|
|
287
|
+
getLogger().log(`${r.applied ? "SORTED " : "SKIPPED"} ${r.filePath}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
program.parseAsync().catch((error) => {
|
|
292
|
+
getLogger().error(error instanceof Error ? error.message : String(error));
|
|
293
|
+
process.exit(1);
|
|
294
|
+
});
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
+
|
|
17
|
+
// src/index.ts
|
|
18
|
+
var index_exports = {};
|
|
19
|
+
module.exports = __toCommonJS(index_exports);
|
|
20
|
+
__reExport(index_exports, require("@env-lane/core"), module.exports);
|
|
21
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
22
|
+
0 && (module.exports = {
|
|
23
|
+
...require("@env-lane/core")
|
|
24
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@env-lane/core';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@env-lane/core';
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "env-lane",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "CLI for env-lane dotenv injection and optional development vault helpers.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "billstark001",
|
|
8
|
+
"homepage": "https://github.com/billstark001/env-lane#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/billstark001/env-lane/issues"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/billstark001/env-lane.git",
|
|
15
|
+
"directory": "packages/cli"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"dotenv",
|
|
19
|
+
"env",
|
|
20
|
+
"environment",
|
|
21
|
+
"cli",
|
|
22
|
+
"workspace",
|
|
23
|
+
"pnpm"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"main": "./dist/index.cjs",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"bin": {
|
|
32
|
+
"env-lane": "./dist/cli.js"
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"require": "./dist/index.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"provenance": true
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"commander": "^14.0.3",
|
|
52
|
+
"consola": "^3.4.2",
|
|
53
|
+
"@env-lane/core": "0.1.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@env-lane/vault": "0.1.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@env-lane/vault": "^0.1.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"@env-lane/vault": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean && tsup src/cli.ts --format esm --clean false",
|
|
68
|
+
"dev": "tsx src/cli.ts",
|
|
69
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
70
|
+
"lint": "biome check ."
|
|
71
|
+
}
|
|
72
|
+
}
|