configenvy 0.1.7 → 0.2.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/dist/index.js +62 -8
- package/package.json +2 -2
- package/src/index.ts +78 -8
package/dist/index.js
CHANGED
|
@@ -91,7 +91,7 @@ var presetConfigs = {
|
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
var availablePresetNames = Object.keys(presetConfigs).sort();
|
|
94
|
-
var availablePresetList = availablePresetNames.join(", ");
|
|
94
|
+
var availablePresetList = ["auto", ...availablePresetNames].join(", ");
|
|
95
95
|
var require2 = createRequire(import.meta.url);
|
|
96
96
|
var cliPackage = require2("../package.json");
|
|
97
97
|
var cliVersion = cliPackage.version;
|
|
@@ -124,10 +124,11 @@ async function runDoctor(projectPath, options, dependencies = defaultDependencie
|
|
|
124
124
|
async function runInit(projectPath, options = {}, dependencies = defaultDependencies) {
|
|
125
125
|
const rootDir = dependencies.resolvePath(projectPath);
|
|
126
126
|
const result = await dependencies.scanProject({ rootDir });
|
|
127
|
-
const preset = resolvePreset(options.preset, dependencies);
|
|
128
|
-
if (options.preset && !preset) return;
|
|
127
|
+
const preset = await resolvePreset(rootDir, options.preset, dependencies);
|
|
128
|
+
if (options.preset && !preset.config && options.preset !== "auto") return;
|
|
129
|
+
if (preset.message) dependencies.log(preset.message);
|
|
129
130
|
const existingEnvExample = options.envExample && options.force ? await readOptionalText(dependencies.resolvePath(rootDir, ".env.example"), dependencies) : void 0;
|
|
130
|
-
const files = buildInitFiles(rootDir, result, Boolean(options.envExample), dependencies.resolvePath, existingEnvExample, preset);
|
|
131
|
+
const files = buildInitFiles(rootDir, result, Boolean(options.envExample), dependencies.resolvePath, existingEnvExample, preset.config);
|
|
131
132
|
if (options.dryRun) {
|
|
132
133
|
for (const file of files) {
|
|
133
134
|
dependencies.log(`Would write ${file.path}`);
|
|
@@ -177,14 +178,67 @@ function buildInitFiles(rootDir, result, includeEnvExample, resolvePath = resolv
|
|
|
177
178
|
}
|
|
178
179
|
return files;
|
|
179
180
|
}
|
|
180
|
-
function resolvePreset(name, dependencies) {
|
|
181
|
-
if (!name) return
|
|
181
|
+
async function resolvePreset(rootDir, name, dependencies) {
|
|
182
|
+
if (!name) return {};
|
|
183
|
+
if (name === "auto") {
|
|
184
|
+
return detectPreset(rootDir, dependencies);
|
|
185
|
+
}
|
|
182
186
|
if (name in presetConfigs) {
|
|
183
|
-
return presetConfigs[name];
|
|
187
|
+
return { config: presetConfigs[name] };
|
|
184
188
|
}
|
|
185
189
|
dependencies.error(`Unknown preset "${name}". Available presets: ${availablePresetList}.`);
|
|
186
190
|
dependencies.exit(1);
|
|
187
|
-
return
|
|
191
|
+
return {};
|
|
192
|
+
}
|
|
193
|
+
async function detectPreset(rootDir, dependencies) {
|
|
194
|
+
const packageJson = await readPackageJson(rootDir, dependencies);
|
|
195
|
+
const packages = new Set(Object.keys({
|
|
196
|
+
...packageJson?.dependencies,
|
|
197
|
+
...packageJson?.devDependencies
|
|
198
|
+
}));
|
|
199
|
+
const packageDetections = [
|
|
200
|
+
["nextjs", "next", 'dependency "next"'],
|
|
201
|
+
["astro", "astro", 'dependency "astro"'],
|
|
202
|
+
["nuxt", "nuxt", 'dependency "nuxt"'],
|
|
203
|
+
["sveltekit", "@sveltejs/kit", 'dependency "@sveltejs/kit"'],
|
|
204
|
+
["vite", "vite", 'dependency "vite"']
|
|
205
|
+
];
|
|
206
|
+
for (const [presetName, packageName, reason] of packageDetections) {
|
|
207
|
+
if (packages.has(packageName)) {
|
|
208
|
+
return detectedPreset(presetName, reason);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const configDetections = [
|
|
212
|
+
["nextjs", ["next.config.js", "next.config.mjs", "next.config.ts"]],
|
|
213
|
+
["astro", ["astro.config.js", "astro.config.mjs", "astro.config.ts"]],
|
|
214
|
+
["nuxt", ["nuxt.config.js", "nuxt.config.mjs", "nuxt.config.ts"]],
|
|
215
|
+
["sveltekit", ["svelte.config.js", "svelte.config.ts"]],
|
|
216
|
+
["vite", ["vite.config.js", "vite.config.mjs", "vite.config.ts"]]
|
|
217
|
+
];
|
|
218
|
+
for (const [presetName, files] of configDetections) {
|
|
219
|
+
for (const file of files) {
|
|
220
|
+
if (await readOptionalText(dependencies.resolvePath(rootDir, file), dependencies) !== void 0) {
|
|
221
|
+
return detectedPreset(presetName, `found ${file}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { message: "No framework preset detected. Using the base config." };
|
|
226
|
+
}
|
|
227
|
+
function detectedPreset(name, reason) {
|
|
228
|
+
return {
|
|
229
|
+
config: presetConfigs[name],
|
|
230
|
+
message: `Detected preset: ${name}
|
|
231
|
+
Reason: ${reason}`
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
async function readPackageJson(rootDir, dependencies) {
|
|
235
|
+
const content = await readOptionalText(dependencies.resolvePath(rootDir, "package.json"), dependencies);
|
|
236
|
+
if (content === void 0) return void 0;
|
|
237
|
+
try {
|
|
238
|
+
return JSON.parse(content);
|
|
239
|
+
} catch {
|
|
240
|
+
return void 0;
|
|
241
|
+
}
|
|
188
242
|
}
|
|
189
243
|
function mergeUnique(base, extra) {
|
|
190
244
|
return [.../* @__PURE__ */ new Set([...base, ...extra])].sort();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "configenvy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Find missing, unused, undocumented, and risky environment variables before setup breaks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"build": "tsup src/index.ts --format esm --dts --clean"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@configenvy/core": "0.
|
|
38
|
+
"@configenvy/core": "0.2.0",
|
|
39
39
|
"commander": "^12.1.0"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
package/src/index.ts
CHANGED
|
@@ -171,13 +171,18 @@ const presetConfigs = {
|
|
|
171
171
|
} satisfies Record<string, Partial<StarterConfig>>;
|
|
172
172
|
|
|
173
173
|
const availablePresetNames = Object.keys(presetConfigs).sort();
|
|
174
|
-
const availablePresetList = availablePresetNames.join(", ");
|
|
174
|
+
const availablePresetList = ["auto", ...availablePresetNames].join(", ");
|
|
175
175
|
|
|
176
176
|
type InitFile = {
|
|
177
177
|
content: string;
|
|
178
178
|
path: string;
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
type PresetResolution = {
|
|
182
|
+
config?: Partial<StarterConfig>;
|
|
183
|
+
message?: string;
|
|
184
|
+
};
|
|
185
|
+
|
|
181
186
|
const require = createRequire(import.meta.url);
|
|
182
187
|
const cliPackage = require("../package.json") as { version: string };
|
|
183
188
|
export const cliVersion = cliPackage.version;
|
|
@@ -224,12 +229,13 @@ export async function runInit(
|
|
|
224
229
|
): Promise<void> {
|
|
225
230
|
const rootDir = dependencies.resolvePath(projectPath);
|
|
226
231
|
const result = await dependencies.scanProject({ rootDir });
|
|
227
|
-
const preset = resolvePreset(options.preset, dependencies);
|
|
228
|
-
if (options.preset && !preset) return;
|
|
232
|
+
const preset = await resolvePreset(rootDir, options.preset, dependencies);
|
|
233
|
+
if (options.preset && !preset.config && options.preset !== "auto") return;
|
|
234
|
+
if (preset.message) dependencies.log(preset.message);
|
|
229
235
|
const existingEnvExample = options.envExample && options.force
|
|
230
236
|
? await readOptionalText(dependencies.resolvePath(rootDir, ".env.example"), dependencies)
|
|
231
237
|
: undefined;
|
|
232
|
-
const files = buildInitFiles(rootDir, result, Boolean(options.envExample), dependencies.resolvePath, existingEnvExample, preset);
|
|
238
|
+
const files = buildInitFiles(rootDir, result, Boolean(options.envExample), dependencies.resolvePath, existingEnvExample, preset.config);
|
|
233
239
|
|
|
234
240
|
if (options.dryRun) {
|
|
235
241
|
for (const file of files) {
|
|
@@ -293,14 +299,78 @@ export function buildInitFiles(
|
|
|
293
299
|
return files;
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
function resolvePreset(name: string | undefined, dependencies: CliDependencies):
|
|
297
|
-
if (!name) return
|
|
302
|
+
async function resolvePreset(rootDir: string, name: string | undefined, dependencies: CliDependencies): Promise<PresetResolution> {
|
|
303
|
+
if (!name) return {};
|
|
304
|
+
if (name === "auto") {
|
|
305
|
+
return detectPreset(rootDir, dependencies);
|
|
306
|
+
}
|
|
298
307
|
if (name in presetConfigs) {
|
|
299
|
-
return presetConfigs[name as PresetName];
|
|
308
|
+
return { config: presetConfigs[name as PresetName] };
|
|
300
309
|
}
|
|
301
310
|
dependencies.error(`Unknown preset "${name}". Available presets: ${availablePresetList}.`);
|
|
302
311
|
dependencies.exit(1);
|
|
303
|
-
return
|
|
312
|
+
return {};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function detectPreset(rootDir: string, dependencies: CliDependencies): Promise<PresetResolution> {
|
|
316
|
+
const packageJson = await readPackageJson(rootDir, dependencies);
|
|
317
|
+
const packages = new Set(Object.keys({
|
|
318
|
+
...packageJson?.dependencies,
|
|
319
|
+
...packageJson?.devDependencies
|
|
320
|
+
}));
|
|
321
|
+
|
|
322
|
+
const packageDetections: Array<[PresetName, string, string]> = [
|
|
323
|
+
["nextjs", "next", "dependency \"next\""],
|
|
324
|
+
["astro", "astro", "dependency \"astro\""],
|
|
325
|
+
["nuxt", "nuxt", "dependency \"nuxt\""],
|
|
326
|
+
["sveltekit", "@sveltejs/kit", "dependency \"@sveltejs/kit\""],
|
|
327
|
+
["vite", "vite", "dependency \"vite\""]
|
|
328
|
+
];
|
|
329
|
+
for (const [presetName, packageName, reason] of packageDetections) {
|
|
330
|
+
if (packages.has(packageName)) {
|
|
331
|
+
return detectedPreset(presetName, reason);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const configDetections: Array<[PresetName, string[]]> = [
|
|
336
|
+
["nextjs", ["next.config.js", "next.config.mjs", "next.config.ts"]],
|
|
337
|
+
["astro", ["astro.config.js", "astro.config.mjs", "astro.config.ts"]],
|
|
338
|
+
["nuxt", ["nuxt.config.js", "nuxt.config.mjs", "nuxt.config.ts"]],
|
|
339
|
+
["sveltekit", ["svelte.config.js", "svelte.config.ts"]],
|
|
340
|
+
["vite", ["vite.config.js", "vite.config.mjs", "vite.config.ts"]]
|
|
341
|
+
];
|
|
342
|
+
for (const [presetName, files] of configDetections) {
|
|
343
|
+
for (const file of files) {
|
|
344
|
+
if (await readOptionalText(dependencies.resolvePath(rootDir, file), dependencies) !== undefined) {
|
|
345
|
+
return detectedPreset(presetName, `found ${file}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return { message: "No framework preset detected. Using the base config." };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function detectedPreset(name: PresetName, reason: string): PresetResolution {
|
|
354
|
+
return {
|
|
355
|
+
config: presetConfigs[name],
|
|
356
|
+
message: `Detected preset: ${name}\nReason: ${reason}`
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function readPackageJson(rootDir: string, dependencies: CliDependencies): Promise<{
|
|
361
|
+
dependencies?: Record<string, string>;
|
|
362
|
+
devDependencies?: Record<string, string>;
|
|
363
|
+
} | undefined> {
|
|
364
|
+
const content = await readOptionalText(dependencies.resolvePath(rootDir, "package.json"), dependencies);
|
|
365
|
+
if (content === undefined) return undefined;
|
|
366
|
+
try {
|
|
367
|
+
return JSON.parse(content) as {
|
|
368
|
+
dependencies?: Record<string, string>;
|
|
369
|
+
devDependencies?: Record<string, string>;
|
|
370
|
+
};
|
|
371
|
+
} catch {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
304
374
|
}
|
|
305
375
|
|
|
306
376
|
function mergeUnique(base: string[], extra: readonly string[]): string[] {
|