envprism 0.1.0-dev.10-1179a3d → 0.1.0-dev.11-c6859e8

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.
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env bun
2
2
  import { defineCommand, runMain } from "citty";
3
3
  import consola from "consola";
4
- import { resolve } from "pathe";
5
- import { d as discoverEnvFiles, r as resolveBase, b as buildMatrix, c as computeDiff, f as formatDiffText } from "../chunks/matrix-nBq_GY2v.mjs";
4
+ import { resolve, join } from "pathe";
5
+ import { l as loadEnvprismConfig, e as discoverEnvFiles, r as resolveBase, b as buildMatrix, c as computeDiff, g as formatDiffText } from "../chunks/matrix-CQv-scUc.mjs";
6
+ import { writeFile } from "node:fs/promises";
6
7
  const diffCommand = defineCommand({
7
8
  meta: {
8
9
  name: "diff",
@@ -25,16 +26,30 @@ const diffCommand = defineCommand({
25
26
  check: {
26
27
  type: "boolean",
27
28
  description: "Suppress output and exit 1 when any file drifts from the base."
29
+ },
30
+ config: {
31
+ type: "string",
32
+ description: "Path to an envprism.config file (default: walk up from cwd)."
28
33
  }
29
34
  },
30
35
  async run({ args }) {
31
- const inputs = collectPaths$1(args.paths);
32
- const files = await discoverEnvFiles(inputs.map((p) => resolve(p)));
36
+ const { config } = await loadEnvprismConfig({ configFile: args.config });
37
+ const inputs = collectPaths$1(args.paths, config.discovery.paths);
38
+ const files = await discoverEnvFiles(
39
+ inputs.map((p) => resolve(p)),
40
+ {
41
+ skipSuffixes: config.discovery.skipSuffixes,
42
+ exampleFirst: config.discovery.exampleFirst
43
+ }
44
+ );
33
45
  if (files.length === 0) {
34
46
  if (!args.check) consola.warn("No .env* files found.");
35
47
  process.exit(args.check ? 0 : 1);
36
48
  }
37
- const base = resolveBase(files, args.base);
49
+ const base = resolveBase(files, args.base, {
50
+ exampleName: config.base.exampleName,
51
+ priority: config.base.priority
52
+ });
38
53
  if (!base) {
39
54
  consola.error("Could not resolve a base file.");
40
55
  process.exit(1);
@@ -42,35 +57,125 @@ const diffCommand = defineCommand({
42
57
  const matrix = buildMatrix(files, base);
43
58
  const report = computeDiff(matrix);
44
59
  if (args.check) {
45
- process.exit(report.inSync ? 0 : 1);
60
+ process.exit(report.inSync ? 0 : config.diff.checkExitCode);
46
61
  }
47
- if (args.json) {
62
+ const json = args.json ?? config.diff.json;
63
+ if (json) {
48
64
  process.stdout.write(JSON.stringify(report, null, 2) + "\n");
49
65
  return;
50
66
  }
51
67
  process.stdout.write(formatDiffText(report));
52
68
  }
53
69
  });
54
- function collectPaths$1(arg) {
70
+ function collectPaths$1(arg, fallback) {
55
71
  if (Array.isArray(arg)) return arg.map(String);
56
72
  if (typeof arg === "string" && arg.length > 0) return [arg];
57
- return ["."];
73
+ return fallback;
58
74
  }
75
+ const TEMPLATE = `/**
76
+ * envprism configuration.
77
+ *
78
+ * For type-safe authoring, install envprism and switch to:
79
+ * import { defineEnvprismConfig } from 'envprism/config';
80
+ * export default defineEnvprismConfig({ ... });
81
+ *
82
+ * @type {import('envprism/config').EnvprismUserConfig}
83
+ */
84
+ export default {
85
+ discovery: {
86
+ // paths: ['.'],
87
+ // skipSuffixesExtra: ['.tmp'],
88
+ // exampleFirst: true
89
+ },
90
+ base: {
91
+ exampleName: '.env.example'
92
+ // priority: ['.env.shared']
93
+ },
94
+ heuristics: {
95
+ // secretTokensExtra: ['JWT'],
96
+ // placeholdersExtra: ['set[_-]?me'],
97
+ grouping: 'auto'
98
+ },
99
+ diff: {
100
+ json: false,
101
+ checkExitCode: 1
102
+ },
103
+ tui: {
104
+ theme: {
105
+ // fgBase: '#82aaff'
106
+ },
107
+ layout: {
108
+ keyColWidth: 22,
109
+ valueColMin: 18,
110
+ sidebarWidth: 30,
111
+ rowGap: 0,
112
+ cellPadX: 1
113
+ },
114
+ undoLimit: 50,
115
+ maskSecrets: true
116
+ }
117
+ };
118
+ `;
119
+ const initCommand = defineCommand({
120
+ meta: {
121
+ name: "init",
122
+ description: "Scaffold an envprism.config.ts with documented defaults."
123
+ },
124
+ args: {
125
+ out: {
126
+ type: "positional",
127
+ required: false,
128
+ description: "Directory to write envprism.config.ts into (default: cwd)."
129
+ },
130
+ force: {
131
+ type: "boolean",
132
+ description: "Overwrite an existing config file."
133
+ }
134
+ },
135
+ async run({ args }) {
136
+ const dir = resolve(typeof args.out === "string" ? args.out : ".");
137
+ const target = join(dir, "envprism.config.ts");
138
+ try {
139
+ await writeFile(target, TEMPLATE, {
140
+ encoding: "utf8",
141
+ flag: args.force ? "w" : "wx"
142
+ });
143
+ } catch (err) {
144
+ if (err.code === "EEXIST") {
145
+ consola.error(`${target} already exists. Use --force to overwrite.`);
146
+ process.exitCode = 1;
147
+ return;
148
+ }
149
+ throw err;
150
+ }
151
+ consola.success(`Wrote ${target}`);
152
+ }
153
+ });
59
154
  async function runTui(args) {
60
- const inputs = collectPaths(args.paths);
61
- const files = await discoverEnvFiles(inputs.map((p) => resolve(p)));
155
+ const { config } = await loadEnvprismConfig({ configFile: args.config });
156
+ const inputs = collectPaths(args.paths, config.discovery.paths);
157
+ const files = await discoverEnvFiles(
158
+ inputs.map((p) => resolve(p)),
159
+ {
160
+ skipSuffixes: config.discovery.skipSuffixes,
161
+ exampleFirst: config.discovery.exampleFirst
162
+ }
163
+ );
62
164
  if (files.length === 0) {
63
165
  consola.warn("No .env* files found.");
64
166
  process.exit(1);
65
167
  }
66
- const base = resolveBase(files, args.base);
168
+ const base = resolveBase(files, args.base, {
169
+ exampleName: config.base.exampleName,
170
+ priority: config.base.priority
171
+ });
67
172
  if (!base) {
68
173
  consola.error("Could not resolve a base file.");
69
174
  process.exit(1);
70
175
  }
71
176
  const matrix = buildMatrix(files, base);
72
- const { runMatrixTui } = await import("../chunks/app-CgJxxbhr.mjs");
73
- await runMatrixTui(matrix);
177
+ const { runMatrixTui } = await import("../chunks/app-BtsPqDdo.mjs");
178
+ await runMatrixTui(matrix, config);
74
179
  }
75
180
  const tuiCommand = defineCommand({
76
181
  meta: {
@@ -86,18 +191,22 @@ const tuiCommand = defineCommand({
86
191
  base: {
87
192
  type: "string",
88
193
  description: "Base file to diff against (defaults to .env.example)."
194
+ },
195
+ config: {
196
+ type: "string",
197
+ description: "Path to an envprism.config file (default: walk up from cwd)."
89
198
  }
90
199
  },
91
200
  async run({ args }) {
92
- await runTui({ paths: args.paths, base: args.base });
201
+ await runTui({ paths: args.paths, base: args.base, config: args.config });
93
202
  }
94
203
  });
95
- function collectPaths(arg) {
204
+ function collectPaths(arg, fallback) {
96
205
  if (Array.isArray(arg)) return arg.map(String);
97
206
  if (typeof arg === "string" && arg.length > 0) return [arg];
98
- return ["."];
207
+ return fallback;
99
208
  }
100
- const SUBCOMMANDS = /* @__PURE__ */ new Set(["tui", "diff"]);
209
+ const SUBCOMMANDS = /* @__PURE__ */ new Set(["tui", "diff", "init"]);
101
210
  const rootCommand = defineCommand({
102
211
  meta: {
103
212
  name: "envprism",
@@ -105,7 +214,8 @@ const rootCommand = defineCommand({
105
214
  },
106
215
  subCommands: {
107
216
  tui: tuiCommand,
108
- diff: diffCommand
217
+ diff: diffCommand,
218
+ init: initCommand
109
219
  },
110
220
  // citty 0.1.6 invokes the root `run` after a matched subcommand returns,
111
221
  // so guard against double-execution by bailing when the first positional
@@ -1 +1 @@
1
- {"version":3,"file":"envprism.mjs","sources":["../../src/commands/diff.ts","../../src/commands/tui.ts","../../src/cli.ts","../../src/bin/envprism.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { resolve } from 'pathe';\nimport { resolveBase } from '@/core/base.ts';\nimport { computeDiff, formatDiffText } from '@/core/diff.ts';\nimport { discoverEnvFiles } from '@/core/discover.ts';\nimport { buildMatrix } from '@/core/matrix.ts';\n\nexport const diffCommand = defineCommand({\n meta: {\n name: 'diff',\n description: 'Print the drift between .env* files compared to a base.'\n },\n args: {\n paths: {\n type: 'positional',\n required: false,\n description: 'Directory or files to scan (defaults to cwd).'\n },\n base: {\n type: 'string',\n description: 'Base file to diff against (defaults to .env.example).'\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of a text table.'\n },\n check: {\n type: 'boolean',\n description:\n 'Suppress output and exit 1 when any file drifts from the base.'\n }\n },\n async run({ args }) {\n const inputs = collectPaths(args.paths);\n const files = await discoverEnvFiles(inputs.map((p) => resolve(p)));\n\n if (files.length === 0) {\n if (!args.check) consola.warn('No .env* files found.');\n process.exit(args.check ? 0 : 1);\n }\n\n const base = resolveBase(files, args.base);\n if (!base) {\n consola.error('Could not resolve a base file.');\n process.exit(1);\n }\n\n const matrix = buildMatrix(files, base);\n const report = computeDiff(matrix);\n\n if (args.check) {\n process.exit(report.inSync ? 0 : 1);\n }\n\n if (args.json) {\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n return;\n }\n\n process.stdout.write(formatDiffText(report));\n }\n});\n\nfunction collectPaths(arg: unknown): string[] {\n if (Array.isArray(arg)) return arg.map(String);\n if (typeof arg === 'string' && arg.length > 0) return [arg];\n return ['.'];\n}\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { resolve } from 'pathe';\nimport { resolveBase } from '@/core/base.ts';\nimport { discoverEnvFiles } from '@/core/discover.ts';\nimport { buildMatrix } from '@/core/matrix.ts';\n\ninterface TuiInvocation {\n paths?: string | string[];\n base?: string;\n}\n\n/**\n * Resolve the matrix and boot the TUI. Shared between the explicit `tui`\n * subcommand and the default-no-subcommand path in `rootCommand`.\n */\nexport async function runTui(args: TuiInvocation): Promise<void> {\n const inputs = collectPaths(args.paths);\n const files = await discoverEnvFiles(inputs.map((p) => resolve(p)));\n\n if (files.length === 0) {\n consola.warn('No .env* files found.');\n process.exit(1);\n }\n\n const base = resolveBase(files, args.base);\n if (!base) {\n consola.error('Could not resolve a base file.');\n process.exit(1);\n }\n\n const matrix = buildMatrix(files, base);\n\n // Dynamic import keeps @opentui/core out of the bundle path used by the\n // `diff` subcommand, so users running diff on Node never hit Bun-only code.\n const { runMatrixTui } = await import('../tui/app.ts');\n await runMatrixTui(matrix);\n}\n\nexport const tuiCommand = defineCommand({\n meta: {\n name: 'tui',\n description: 'Open the interactive matrix view (default command).'\n },\n args: {\n paths: {\n type: 'positional',\n required: false,\n description: 'Directory or files to scan (defaults to cwd).'\n },\n base: {\n type: 'string',\n description: 'Base file to diff against (defaults to .env.example).'\n }\n },\n async run({ args }) {\n await runTui({ paths: args.paths, base: args.base });\n }\n});\n\nfunction collectPaths(arg: unknown): string[] {\n if (Array.isArray(arg)) return arg.map(String);\n if (typeof arg === 'string' && arg.length > 0) return [arg];\n return ['.'];\n}\n","import { defineCommand } from 'citty';\nimport { diffCommand } from '@/commands/diff.ts';\nimport { runTui, tuiCommand } from '@/commands/tui.ts';\n\nconst SUBCOMMANDS = new Set(['tui', 'diff']);\n\nexport const rootCommand = defineCommand({\n meta: {\n name: 'envprism',\n description:\n 'TUI-based env file manager — refract one set of variables into many environment views.'\n },\n subCommands: {\n tui: tuiCommand,\n diff: diffCommand\n },\n // citty 0.1.6 invokes the root `run` after a matched subcommand returns,\n // so guard against double-execution by bailing when the first positional\n // arg names a known subcommand. With no args at all we launch the TUI in\n // the cwd, which is the documented default.\n async run({ rawArgs }) {\n const firstPositional = rawArgs.find((a) => !a.startsWith('-'));\n if (firstPositional && SUBCOMMANDS.has(firstPositional)) return;\n await runTui({});\n }\n});\n","import { runMain } from 'citty';\nimport { rootCommand } from '@/cli.ts';\n\nrunMain(rootCommand);\n"],"names":["collectPaths"],"mappings":"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"}
1
+ {"version":3,"file":"envprism.mjs","sources":["../../src/commands/diff.ts","../../src/commands/init.ts","../../src/commands/tui.ts","../../src/cli.ts","../../src/bin/envprism.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { resolve } from 'pathe';\nimport { loadEnvprismConfig } from '@/config/load.ts';\nimport { resolveBase } from '@/core/base.ts';\nimport { computeDiff, formatDiffText } from '@/core/diff.ts';\nimport { discoverEnvFiles } from '@/core/discover.ts';\nimport { buildMatrix } from '@/core/matrix.ts';\n\nexport const diffCommand = defineCommand({\n meta: {\n name: 'diff',\n description: 'Print the drift between .env* files compared to a base.'\n },\n args: {\n paths: {\n type: 'positional',\n required: false,\n description: 'Directory or files to scan (defaults to cwd).'\n },\n base: {\n type: 'string',\n description: 'Base file to diff against (defaults to .env.example).'\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON instead of a text table.'\n },\n check: {\n type: 'boolean',\n description:\n 'Suppress output and exit 1 when any file drifts from the base.'\n },\n config: {\n type: 'string',\n description:\n 'Path to an envprism.config file (default: walk up from cwd).'\n }\n },\n async run({ args }) {\n const { config } = await loadEnvprismConfig({ configFile: args.config });\n const inputs = collectPaths(args.paths, config.discovery.paths);\n const files = await discoverEnvFiles(\n inputs.map((p) => resolve(p)),\n {\n skipSuffixes: config.discovery.skipSuffixes,\n exampleFirst: config.discovery.exampleFirst\n }\n );\n\n if (files.length === 0) {\n if (!args.check) consola.warn('No .env* files found.');\n process.exit(args.check ? 0 : 1);\n }\n\n const base = resolveBase(files, args.base, {\n exampleName: config.base.exampleName,\n priority: config.base.priority\n });\n if (!base) {\n consola.error('Could not resolve a base file.');\n process.exit(1);\n }\n\n const matrix = buildMatrix(files, base);\n const report = computeDiff(matrix);\n\n if (args.check) {\n process.exit(report.inSync ? 0 : config.diff.checkExitCode);\n }\n\n const json = args.json ?? config.diff.json;\n if (json) {\n process.stdout.write(JSON.stringify(report, null, 2) + '\\n');\n return;\n }\n\n process.stdout.write(formatDiffText(report));\n }\n});\n\nfunction collectPaths(arg: unknown, fallback: string[]): string[] {\n if (Array.isArray(arg)) return arg.map(String);\n if (typeof arg === 'string' && arg.length > 0) return [arg];\n return fallback;\n}\n","import { writeFile } from 'node:fs/promises';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { join, resolve } from 'pathe';\n\nconst TEMPLATE = `/**\n * envprism configuration.\n *\n * For type-safe authoring, install envprism and switch to:\n * import { defineEnvprismConfig } from 'envprism/config';\n * export default defineEnvprismConfig({ ... });\n *\n * @type {import('envprism/config').EnvprismUserConfig}\n */\nexport default {\n discovery: {\n // paths: ['.'],\n // skipSuffixesExtra: ['.tmp'],\n // exampleFirst: true\n },\n base: {\n exampleName: '.env.example'\n // priority: ['.env.shared']\n },\n heuristics: {\n // secretTokensExtra: ['JWT'],\n // placeholdersExtra: ['set[_-]?me'],\n grouping: 'auto'\n },\n diff: {\n json: false,\n checkExitCode: 1\n },\n tui: {\n theme: {\n // fgBase: '#82aaff'\n },\n layout: {\n keyColWidth: 22,\n valueColMin: 18,\n sidebarWidth: 30,\n rowGap: 0,\n cellPadX: 1\n },\n undoLimit: 50,\n maskSecrets: true\n }\n};\n`;\n\nexport const initCommand = defineCommand({\n meta: {\n name: 'init',\n description: 'Scaffold an envprism.config.ts with documented defaults.'\n },\n args: {\n out: {\n type: 'positional',\n required: false,\n description: 'Directory to write envprism.config.ts into (default: cwd).'\n },\n force: {\n type: 'boolean',\n description: 'Overwrite an existing config file.'\n }\n },\n async run({ args }) {\n const dir = resolve(typeof args.out === 'string' ? args.out : '.');\n const target = join(dir, 'envprism.config.ts');\n try {\n await writeFile(target, TEMPLATE, {\n encoding: 'utf8',\n flag: args.force ? 'w' : 'wx'\n });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST') {\n consola.error(`${target} already exists. Use --force to overwrite.`);\n process.exitCode = 1;\n return;\n }\n throw err;\n }\n consola.success(`Wrote ${target}`);\n }\n});\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { resolve } from 'pathe';\nimport { loadEnvprismConfig } from '@/config/load.ts';\nimport { resolveBase } from '@/core/base.ts';\nimport { discoverEnvFiles } from '@/core/discover.ts';\nimport { buildMatrix } from '@/core/matrix.ts';\n\ninterface TuiInvocation {\n paths?: string | string[];\n base?: string;\n config?: string;\n}\n\n/**\n * Resolve the matrix and boot the TUI. Shared between the explicit `tui`\n * subcommand and the default-no-subcommand path in `rootCommand`.\n */\nexport async function runTui(args: TuiInvocation): Promise<void> {\n const { config } = await loadEnvprismConfig({ configFile: args.config });\n const inputs = collectPaths(args.paths, config.discovery.paths);\n const files = await discoverEnvFiles(\n inputs.map((p) => resolve(p)),\n {\n skipSuffixes: config.discovery.skipSuffixes,\n exampleFirst: config.discovery.exampleFirst\n }\n );\n\n if (files.length === 0) {\n consola.warn('No .env* files found.');\n process.exit(1);\n }\n\n const base = resolveBase(files, args.base, {\n exampleName: config.base.exampleName,\n priority: config.base.priority\n });\n if (!base) {\n consola.error('Could not resolve a base file.');\n process.exit(1);\n }\n\n const matrix = buildMatrix(files, base);\n\n // Dynamic import keeps @opentui/core out of the bundle path used by the\n // `diff` subcommand, so users running diff on Node never hit Bun-only code.\n const { runMatrixTui } = await import('../tui/app.ts');\n await runMatrixTui(matrix, config);\n}\n\nexport const tuiCommand = defineCommand({\n meta: {\n name: 'tui',\n description: 'Open the interactive matrix view (default command).'\n },\n args: {\n paths: {\n type: 'positional',\n required: false,\n description: 'Directory or files to scan (defaults to cwd).'\n },\n base: {\n type: 'string',\n description: 'Base file to diff against (defaults to .env.example).'\n },\n config: {\n type: 'string',\n description:\n 'Path to an envprism.config file (default: walk up from cwd).'\n }\n },\n async run({ args }) {\n await runTui({ paths: args.paths, base: args.base, config: args.config });\n }\n});\n\nfunction collectPaths(arg: unknown, fallback: string[]): string[] {\n if (Array.isArray(arg)) return arg.map(String);\n if (typeof arg === 'string' && arg.length > 0) return [arg];\n return fallback;\n}\n","import { defineCommand } from 'citty';\nimport { diffCommand } from '@/commands/diff.ts';\nimport { initCommand } from '@/commands/init.ts';\nimport { runTui, tuiCommand } from '@/commands/tui.ts';\n\nconst SUBCOMMANDS = new Set(['tui', 'diff', 'init']);\n\nexport const rootCommand = defineCommand({\n meta: {\n name: 'envprism',\n description:\n 'TUI-based env file manager — refract one set of variables into many environment views.'\n },\n subCommands: {\n tui: tuiCommand,\n diff: diffCommand,\n init: initCommand\n },\n // citty 0.1.6 invokes the root `run` after a matched subcommand returns,\n // so guard against double-execution by bailing when the first positional\n // arg names a known subcommand. With no args at all we launch the TUI in\n // the cwd, which is the documented default.\n async run({ rawArgs }) {\n const firstPositional = rawArgs.find((a) => !a.startsWith('-'));\n if (firstPositional && SUBCOMMANDS.has(firstPositional)) return;\n await runTui({});\n }\n});\n","import { runMain } from 'citty';\nimport { rootCommand } from '@/cli.ts';\n\nrunMain(rootCommand);\n"],"names":["collectPaths"],"mappings":"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"}