@romaintaillandier1978/dotenv-never-lies 1.1.1 → 1.3.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/README.md +103 -42
- package/dist/cli/commands/assert.d.ts +3 -4
- package/dist/cli/commands/assert.d.ts.map +1 -1
- package/dist/cli/commands/explain.d.ts +2 -3
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/export.d.ts +4 -3
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +46 -0
- package/dist/cli/commands/generate.d.ts +2 -2
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/infer.d.ts +15 -0
- package/dist/cli/commands/infer.d.ts.map +1 -0
- package/dist/cli/commands/infer.js +86 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +30 -0
- package/dist/cli/commands/program.d.ts +4 -0
- package/dist/cli/commands/program.d.ts.map +1 -0
- package/dist/cli/commands/program.js +1 -0
- package/dist/cli/index.js +74 -30
- package/dist/cli/utils/infer-schema.d.ts +2 -2
- package/dist/cli/utils/infer-schema.d.ts.map +1 -1
- package/dist/cli/utils/infer-schema.js +20 -22
- package/dist/cli/utils/printer.d.ts +2 -0
- package/dist/cli/utils/printer.d.ts.map +1 -1
- package/dist/cli/utils/printer.js +104 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/infer/__tests__/port-vs-version.test.d.ts +2 -0
- package/dist/infer/__tests__/port-vs-version.test.d.ts.map +1 -0
- package/dist/infer/__tests__/port-vs-version.test.js +32 -0
- package/dist/infer/__tests__/rules/basic.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/basic.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/basic.test.js +85 -0
- package/dist/infer/__tests__/rules/boolean.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/boolean.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/boolean.test.js +34 -0
- package/dist/infer/__tests__/rules/duration.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/duration.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/duration.test.js +24 -0
- package/dist/infer/__tests__/rules/ip.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/ip.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/ip.test.js +24 -0
- package/dist/infer/__tests__/rules/json.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/json.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/json.test.js +38 -0
- package/dist/infer/__tests__/rules/list.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/list.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/list.test.js +130 -0
- package/dist/infer/__tests__/rules/port.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/port.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/port.test.js +24 -0
- package/dist/infer/__tests__/rules/url.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/url.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/url.test.js +39 -0
- package/dist/infer/__tests__/rules/version.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/version.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/version.test.js +37 -0
- package/dist/infer/generated/basic.d.ts +8 -0
- package/dist/infer/generated/basic.d.ts.map +1 -0
- package/dist/infer/generated/basic.js +24 -0
- package/dist/infer/generated/boolean.d.ts +3 -0
- package/dist/infer/generated/boolean.d.ts.map +1 -0
- package/dist/infer/generated/boolean.js +9 -0
- package/dist/infer/generated/duration.d.ts +3 -0
- package/dist/infer/generated/duration.d.ts.map +1 -0
- package/dist/infer/generated/duration.js +9 -0
- package/dist/infer/generated/ip.d.ts +3 -0
- package/dist/infer/generated/ip.d.ts.map +1 -0
- package/dist/infer/generated/ip.js +9 -0
- package/dist/infer/generated/json.d.ts +4 -0
- package/dist/infer/generated/json.d.ts.map +1 -0
- package/dist/infer/generated/json.js +10 -0
- package/dist/infer/generated/list.d.ts +8 -0
- package/dist/infer/generated/list.d.ts.map +1 -0
- package/dist/infer/generated/list.js +49 -0
- package/dist/infer/generated/port.d.ts +4 -0
- package/dist/infer/generated/port.d.ts.map +1 -0
- package/dist/infer/generated/port.js +10 -0
- package/dist/infer/generated/url.d.ts +14 -0
- package/dist/infer/generated/url.d.ts.map +1 -0
- package/dist/infer/generated/url.js +30 -0
- package/dist/infer/generated/version.d.ts +4 -0
- package/dist/infer/generated/version.d.ts.map +1 -0
- package/dist/infer/generated/version.js +10 -0
- package/dist/infer/helpers.d.ts +11 -0
- package/dist/infer/helpers.d.ts.map +1 -0
- package/dist/infer/helpers.js +41 -0
- package/dist/infer/index.d.ts +4 -0
- package/dist/infer/index.d.ts.map +1 -0
- package/dist/infer/index.js +35 -0
- package/dist/infer/rules/basic.d.ts +11 -0
- package/dist/infer/rules/basic.d.ts.map +1 -0
- package/dist/infer/rules/basic.js +90 -0
- package/dist/infer/rules/boolean.d.ts +3 -0
- package/dist/infer/rules/boolean.d.ts.map +1 -0
- package/dist/infer/rules/boolean.js +25 -0
- package/dist/infer/rules/duration.d.ts +3 -0
- package/dist/infer/rules/duration.d.ts.map +1 -0
- package/dist/infer/rules/duration.js +25 -0
- package/dist/infer/rules/ip.d.ts +3 -0
- package/dist/infer/rules/ip.d.ts.map +1 -0
- package/dist/infer/rules/ip.js +25 -0
- package/dist/infer/rules/json.d.ts +3 -0
- package/dist/infer/rules/json.d.ts.map +1 -0
- package/dist/infer/rules/json.js +59 -0
- package/dist/infer/rules/list.d.ts +12 -0
- package/dist/infer/rules/list.d.ts.map +1 -0
- package/dist/infer/rules/list.js +221 -0
- package/dist/infer/rules/port.d.ts +3 -0
- package/dist/infer/rules/port.d.ts.map +1 -0
- package/dist/infer/rules/port.js +30 -0
- package/dist/infer/rules/url.d.ts +4 -0
- package/dist/infer/rules/url.d.ts.map +1 -0
- package/dist/infer/rules/url.js +143 -0
- package/dist/infer/rules/version.d.ts +3 -0
- package/dist/infer/rules/version.d.ts.map +1 -0
- package/dist/infer/rules/version.js +26 -0
- package/dist/infer/types.d.ts +87 -0
- package/dist/infer/types.d.ts.map +1 -0
- package/dist/infer/types.js +1 -0
- package/dist/infer-rules/basic.d.ts +5 -0
- package/dist/infer-rules/basic.d.ts.map +1 -0
- package/dist/infer-rules/basic.js +48 -0
- package/dist/infer-rules/boolean.d.ts +3 -0
- package/dist/infer-rules/boolean.d.ts.map +1 -0
- package/dist/infer-rules/boolean.js +25 -0
- package/dist/infer-rules/dotted.d.ts +4 -0
- package/dist/infer-rules/dotted.d.ts.map +1 -0
- package/dist/infer-rules/dotted.js +48 -0
- package/dist/infer-rules/duration.d.ts +3 -0
- package/dist/infer-rules/duration.d.ts.map +1 -0
- package/dist/infer-rules/duration.js +25 -0
- package/dist/infer-rules/index.d.ts +50 -0
- package/dist/infer-rules/index.d.ts.map +1 -0
- package/dist/infer-rules/index.js +42 -0
- package/dist/infer-rules/json.d.ts +3 -0
- package/dist/infer-rules/json.d.ts.map +1 -0
- package/dist/infer-rules/json.js +50 -0
- package/dist/infer-rules/list.d.ts +5 -0
- package/dist/infer-rules/list.d.ts.map +1 -0
- package/dist/infer-rules/list.js +200 -0
- package/dist/infer-rules/path.d.ts +5 -0
- package/dist/infer-rules/path.d.ts.map +1 -0
- package/dist/infer-rules/path.js +78 -0
- package/dist/infer-rules/port.d.ts +3 -0
- package/dist/infer-rules/port.d.ts.map +1 -0
- package/dist/infer-rules/port.js +26 -0
- package/dist/infer-rules/simple.d.ts +3 -0
- package/dist/infer-rules/simple.d.ts.map +1 -0
- package/dist/infer-rules/simple.js +37 -0
- package/dist/infer-rules/url.d.ts +4 -0
- package/dist/infer-rules/url.d.ts.map +1 -0
- package/dist/infer-rules/url.js +149 -0
- package/dist/llm-kit/context.json.d.ts +2 -0
- package/dist/llm-kit/context.json.d.ts.map +1 -0
- package/dist/llm-kit/context.json.js +22 -0
- package/dist/sample/DNLTest.d.ts +2 -0
- package/dist/sample/DNLTest.d.ts.map +1 -0
- package/dist/sample/DNLTest.js +4 -0
- package/dist/sample/debug.d.ts +2 -0
- package/dist/sample/debug.d.ts.map +1 -0
- package/dist/sample/debug.js +5 -0
- package/dist/sample/env.dnl.d.ts +426 -0
- package/dist/sample/env.dnl.d.ts.map +1 -0
- package/dist/sample/env.dnl.js +429 -0
- package/dist/schemas/bool.d.ts +9 -0
- package/dist/schemas/bool.d.ts.map +1 -0
- package/dist/schemas/bool.js +22 -0
- package/dist/schemas/boolean.d.ts +9 -0
- package/dist/schemas/boolean.d.ts.map +1 -0
- package/dist/schemas/boolean.js +23 -0
- package/dist/schemas/dotted.d.ts +21 -0
- package/dist/schemas/dotted.d.ts.map +1 -0
- package/dist/schemas/dotted.js +45 -0
- package/dist/schemas/duration.d.ts +11 -0
- package/dist/schemas/duration.d.ts.map +1 -0
- package/dist/schemas/duration.js +44 -0
- package/dist/schemas/index.d.ts +9 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +8 -0
- package/dist/schemas/ip-and-version.d.ts +12 -0
- package/dist/schemas/ip-and-version.d.ts.map +1 -0
- package/dist/schemas/ip-and-version.js +35 -0
- package/dist/schemas/ip.d.ts +11 -0
- package/dist/schemas/ip.d.ts.map +1 -0
- package/dist/schemas/ip.js +33 -0
- package/dist/schemas/json.d.ts +15 -0
- package/dist/schemas/json.d.ts.map +1 -0
- package/dist/schemas/json.js +34 -0
- package/dist/schemas/list.d.ts +89 -0
- package/dist/schemas/list.d.ts.map +1 -0
- package/dist/schemas/list.js +139 -0
- package/dist/schemas/path.d.ts +23 -0
- package/dist/schemas/path.d.ts.map +1 -0
- package/dist/schemas/path.js +33 -0
- package/dist/schemas/port.d.ts +8 -0
- package/dist/schemas/port.d.ts.map +1 -0
- package/dist/schemas/port.js +9 -0
- package/dist/schemas/urls.d.ts +15 -0
- package/dist/schemas/urls.d.ts.map +1 -0
- package/dist/schemas/urls.js +54 -0
- package/package.json +11 -6
- package/dist/DnlTest.d.ts +0 -2
- package/dist/DnlTest.d.ts.map +0 -1
- package/dist/DnlTest.js +0 -12
- package/dist/cli/utils/exitCodes.d.ts +0 -8
- package/dist/cli/utils/exitCodes.d.ts.map +0 -1
- package/dist/cli/utils/exitCodes.js +0 -8
- package/dist/romaintaillandier1978-dotenv-never-lies-0.3.0.tgz +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { program, CommanderError } from "commander";
|
|
3
3
|
import { assertCommand } from "./commands/assert.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { initCommand } from "./commands/init.js";
|
|
5
|
+
import { inferCommand } from "./commands/infer.js";
|
|
6
6
|
import { explainCommand, printHuman } from "./commands/explain.js";
|
|
7
7
|
import { exportCommand } from "./commands/export.js";
|
|
8
8
|
import { toFile } from "./utils/toFile.js";
|
|
@@ -56,7 +56,7 @@ program
|
|
|
56
56
|
dnl generate --schema my-dnl.ts --out .env
|
|
57
57
|
|
|
58
58
|
# Create an env.dnl.ts schema from an existing .env
|
|
59
|
-
dnl
|
|
59
|
+
dnl infer --source .env
|
|
60
60
|
|
|
61
61
|
# Display known variables and their description
|
|
62
62
|
dnl explain
|
|
@@ -71,7 +71,10 @@ program
|
|
|
71
71
|
.command("assert")
|
|
72
72
|
.description("Verifies the runtime environment and exits the process if the schema is not satisfied.")
|
|
73
73
|
.option("-s, --source <source>", "Variables source (default: process.env)")
|
|
74
|
-
.action(
|
|
74
|
+
.action(async (opts) => {
|
|
75
|
+
const globalOpts = program.opts();
|
|
76
|
+
await assertCommand({ ...opts, schema: globalOpts.schema });
|
|
77
|
+
})
|
|
75
78
|
.addHelpText("after", `\nExamples:
|
|
76
79
|
|
|
77
80
|
# Validate environment variables from process.env
|
|
@@ -102,6 +105,7 @@ const exportHelp = {
|
|
|
102
105
|
json: "Key/value JSON object",
|
|
103
106
|
ts: "Typed TypeScript object",
|
|
104
107
|
js: "JavaScript object",
|
|
108
|
+
types: "TypeScript declaration file (.d.ts) for your environment variables",
|
|
105
109
|
};
|
|
106
110
|
program
|
|
107
111
|
.command("export")
|
|
@@ -117,7 +121,8 @@ program
|
|
|
117
121
|
.option("--k8s-name <name>", "Name for the k8s resource. Default: env-secret for k8s-secret, env-config for k8s-configmap")
|
|
118
122
|
.option("--github-org <org>", "GitHub organization name")
|
|
119
123
|
.action(async (format, opts) => {
|
|
120
|
-
const
|
|
124
|
+
const globalOpts = program.opts();
|
|
125
|
+
const { content, warnings, out } = await exportCommand({ ...opts, format, schema: globalOpts.schema });
|
|
121
126
|
if (out) {
|
|
122
127
|
await toFile(content, out, opts.force ?? false);
|
|
123
128
|
}
|
|
@@ -225,49 +230,84 @@ program
|
|
|
225
230
|
# Export variables as a typed TypeScript object, or js
|
|
226
231
|
dnl export ts --out env.generated.ts --serialize-typed
|
|
227
232
|
dnl export js --out env.generated.js --serialize-typed
|
|
233
|
+
`)
|
|
234
|
+
.addHelpText("after", `\nSpecific case of export types:
|
|
235
|
+
|
|
236
|
+
This command generates a TypeScript declaration file (.d.ts) describing the static contract of your environment variables.
|
|
237
|
+
|
|
238
|
+
The generated types are intentionally conservative. Zod transforms are NOT reflected in the exported types.
|
|
239
|
+
|
|
240
|
+
If a variable uses a Zod transform:
|
|
241
|
+
* a CLI warning is emitted
|
|
242
|
+
* the generated type is annotated with @dnl-transform
|
|
243
|
+
* the runtime value returned by assert() may differ from the declared type
|
|
244
|
+
|
|
245
|
+
The --source option is NOT applicable to this format. Only the schema is used.
|
|
246
|
+
|
|
247
|
+
# Example:
|
|
248
|
+
dnl export types --out src/types/env.dnl.d.ts
|
|
228
249
|
`);
|
|
229
250
|
// #endregion export
|
|
230
|
-
// #region
|
|
251
|
+
// #region init
|
|
231
252
|
program
|
|
232
|
-
.command("
|
|
233
|
-
.description("
|
|
253
|
+
.command("init")
|
|
254
|
+
.description("Initialize an environment file from a DNL schema.\n" +
|
|
255
|
+
"This command does NOT read any existing environment variables.\n" +
|
|
234
256
|
"Useful to bootstrap a project or facilitate onboarding of a new developer.\n" +
|
|
235
257
|
"Only default values defined in the schema are written.")
|
|
236
258
|
.option("-o, --out <file>", "Output file (default: .env)")
|
|
237
259
|
.option("-f, --force", "Overwrite existing file")
|
|
238
260
|
.action(async (opts) => {
|
|
239
|
-
const
|
|
261
|
+
const globalOpts = program.opts();
|
|
262
|
+
const { content, out } = await initCommand({ ...opts, schema: globalOpts.schema });
|
|
240
263
|
await toFile(content, out, opts.force ?? false);
|
|
241
264
|
})
|
|
242
265
|
.addHelpText("after", `\nExamples:
|
|
243
266
|
|
|
244
|
-
#
|
|
245
|
-
dnl
|
|
267
|
+
# Initialize a .env file from the default DNL schema (env.dnl.ts)
|
|
268
|
+
dnl init
|
|
246
269
|
|
|
247
|
-
#
|
|
248
|
-
dnl
|
|
270
|
+
# Initialize a .env file from a specified DNL schema
|
|
271
|
+
dnl init --schema my-dnl.ts
|
|
249
272
|
|
|
250
|
-
#
|
|
251
|
-
dnl
|
|
273
|
+
# Initialize a .env.local file from the DNL schema
|
|
274
|
+
dnl init --out .env.local
|
|
252
275
|
|
|
253
|
-
#
|
|
254
|
-
dnl
|
|
276
|
+
# Initialize a .env file from a DNL schema and overwrite the existing file
|
|
277
|
+
dnl init --out .env --force
|
|
255
278
|
`);
|
|
256
|
-
// #endregion
|
|
257
|
-
// #region
|
|
279
|
+
// #endregion init
|
|
280
|
+
// #region infer
|
|
258
281
|
program
|
|
259
|
-
.command("
|
|
282
|
+
.command("infer")
|
|
260
283
|
.description("Generates a dotenv-never-lies schema from a .env file.\n" +
|
|
261
284
|
"Useful to migrate an existing project to dotenv-never-lies.\n" +
|
|
262
285
|
"The generated schema is a starting point and must be refined manually.\n" +
|
|
263
|
-
"Keys in the .env file that are not valid identifiers are escaped to JSON strings. (e.g. MY-KEY -> 'MY-KEY')"
|
|
286
|
+
"Keys in the .env file that are not valid identifiers are escaped to JSON strings. (e.g. MY-KEY -> 'MY-KEY')\n" +
|
|
287
|
+
"By default, the command will try to guess sensitive variables (e.g. SECRET, KEY, TOKEN, PASSWORD) as secrets.\n" +
|
|
288
|
+
"This detection is intentionally aggressive and may flag variables that are not secrets.\n" +
|
|
289
|
+
"This is a deliberate design choice to avoid missing sensitive values.\n" +
|
|
290
|
+
"Use the --dont-guess-secret option to disable this behavior.\n" +
|
|
291
|
+
"\n" +
|
|
292
|
+
"Documentation: https://github.com/rtaillandier/dotenv-never-lies/blob/main/docs/commands/infer.md")
|
|
264
293
|
.option("-s, --source <source>", "Source .env file", ".env")
|
|
265
294
|
.option("-o, --out <file>", "Output DNL file", "env.dnl.ts")
|
|
266
295
|
.option("-f, --force", "Overwrite existing file")
|
|
267
|
-
.option("--
|
|
296
|
+
.option("--verbose", "Verbose mode")
|
|
297
|
+
.option("--dont-guess-secret", "Do not try to guess sensitive variables (heuristic)")
|
|
268
298
|
.action(async (opts) => {
|
|
269
|
-
const { content, out, warnings } = await
|
|
270
|
-
|
|
299
|
+
const { content, out, warnings, verbose } = await inferCommand(opts);
|
|
300
|
+
if (opts.verbose) {
|
|
301
|
+
for (const v of verbose ?? []) {
|
|
302
|
+
console.log(v);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (out) {
|
|
306
|
+
await toFile(content, out, opts.force ?? false);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
console.log(content);
|
|
310
|
+
}
|
|
271
311
|
for (const warning of warnings) {
|
|
272
312
|
console.error(`${warning}`);
|
|
273
313
|
}
|
|
@@ -275,18 +315,21 @@ program
|
|
|
275
315
|
.addHelpText("after", `\nExamples:
|
|
276
316
|
|
|
277
317
|
# Generate an env.dnl.ts schema from a .env file, try to guess sensitive variables
|
|
278
|
-
dnl
|
|
318
|
+
dnl infer --guess-secret
|
|
279
319
|
|
|
280
320
|
# Generate an env.dnl.ts schema from a .env.local file
|
|
281
|
-
dnl
|
|
321
|
+
dnl infer --source .env.local
|
|
282
322
|
|
|
283
323
|
# Generate a my-dnl.ts schema from a .env file
|
|
284
|
-
dnl
|
|
324
|
+
dnl infer --out my-dnl.ts
|
|
285
325
|
|
|
286
326
|
# Generate an env.dnl.ts schema from a .env file and overwrite the existing file
|
|
287
|
-
dnl
|
|
327
|
+
dnl infer --force
|
|
328
|
+
|
|
329
|
+
# Full documentation:
|
|
330
|
+
# https://github.com/romaintaillandier1978/dotenv-never-lies/blob/main/docs/commands/infer.md
|
|
288
331
|
`);
|
|
289
|
-
// #endregion
|
|
332
|
+
// #endregion infer
|
|
290
333
|
// #region explain
|
|
291
334
|
program
|
|
292
335
|
.command("explain")
|
|
@@ -294,7 +337,8 @@ program
|
|
|
294
337
|
.argument("[keys...]", "Keys to explain (0..N). Without argument, all keys.")
|
|
295
338
|
.option("-f, --format <format>", 'Output format ("human" | "json")', "human")
|
|
296
339
|
.action(async (keys, opts) => {
|
|
297
|
-
const
|
|
340
|
+
const globalOpts = program.opts();
|
|
341
|
+
const { format, result } = await explainCommand({ keys: keys ?? [], schema: globalOpts.schema, format: opts.format });
|
|
298
342
|
if (format === "human") {
|
|
299
343
|
printHuman(result);
|
|
300
344
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const
|
|
1
|
+
import { Import } from "../../infer/types.js";
|
|
2
|
+
export declare const infer: (name: string, rawValue: string, imports: Array<Import>, verbose: Array<string>, warnings: Array<string>) => string;
|
|
3
3
|
//# sourceMappingURL=infer-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infer-schema.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/infer-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"infer-schema.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/infer-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,KAAK,CAAC,MAAM,CAAC,EAAE,SAAS,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,KAAK,CAAC,MAAM,CAAC,KAAG,MAsB/H,CAAC"}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import { RULES } from "../../infer/index.js";
|
|
2
|
+
export const infer = (name, rawValue, imports, verbose, warnings) => {
|
|
3
|
+
for (const pass of RULES) {
|
|
4
|
+
const result = pass.tryInfer({ name, rawValue });
|
|
5
|
+
if (!result)
|
|
6
|
+
continue;
|
|
7
|
+
if (result.confidence >= pass.threshold) {
|
|
8
|
+
verbose.push(` Infer ${name} : `);
|
|
9
|
+
const importedNames = result.generated.imports.map((entry) => entry.name);
|
|
10
|
+
verbose.push(` [${importedNames.join(", ")}] confidence: ${result.confidence} / threshold: ${pass.threshold}`);
|
|
11
|
+
imports.push(...result.generated.imports);
|
|
12
|
+
if (result.reasons) {
|
|
13
|
+
verbose.push(...result.reasons.map((reason) => ` ${reason}`));
|
|
14
|
+
}
|
|
15
|
+
verbose.push(` -> selected schema: ${result.generated.code}`);
|
|
16
|
+
if (result.warnings) {
|
|
17
|
+
warnings.push(...result.warnings);
|
|
18
|
+
}
|
|
19
|
+
return result.generated.code;
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
return "z.string()";
|
|
20
23
|
};
|
|
21
|
-
const secretMarkers = ["SECRET", "KEY", "TOKEN", "PASSWORD", "PASS", "AUTH"];
|
|
22
|
-
export const guessSecret = (value) => {
|
|
23
|
-
const parts = value.toUpperCase().split(/[_\-]/);
|
|
24
|
-
return secretMarkers.some((marker) => parts.includes(marker));
|
|
25
|
-
};
|
|
@@ -11,6 +11,8 @@ export type Explanation = {
|
|
|
11
11
|
};
|
|
12
12
|
export declare const toExplanation: (key: string, value: EnvVarDefinition<any>) => Explanation;
|
|
13
13
|
export declare function printZodType(def: z.core.$ZodTypeDef): string;
|
|
14
|
+
export declare function printZodTypeDts(def: z.core.$ZodTypeDef): string;
|
|
14
15
|
export declare function getDefaultEnvValue(def: z.core.$ZodTypeDef): string | undefined;
|
|
15
16
|
export declare function isRequired(def: z.core.$ZodTypeDef): boolean;
|
|
17
|
+
export declare function isTransform(def: z.core.$ZodTypeDef): boolean;
|
|
16
18
|
//# sourceMappingURL=printer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/printer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AACF,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,EAAE,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAG,WAWzE,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,CAqE5D;AAuBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,GAAG,SAAS,CAwB9E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,OAAO,CAyB3D"}
|
|
1
|
+
{"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/printer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AACF,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,EAAE,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAG,WAWzE,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,CAqE5D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,CA6E/D;AAuBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,GAAG,SAAS,CAwB9E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,OAAO,CAyB3D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,OAAO,CAkC5D"}
|
|
@@ -20,7 +20,7 @@ export function printZodType(def) {
|
|
|
20
20
|
case "enum":
|
|
21
21
|
if ("entries" in def) {
|
|
22
22
|
return Object.keys(def.entries)
|
|
23
|
-
.map((k) => k)
|
|
23
|
+
.map((k) => `"${k}"`)
|
|
24
24
|
.join(" | ");
|
|
25
25
|
}
|
|
26
26
|
return "unknown";
|
|
@@ -74,6 +74,78 @@ export function printZodType(def) {
|
|
|
74
74
|
return "unknown";
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
export function printZodTypeDts(def) {
|
|
78
|
+
switch (def.type) {
|
|
79
|
+
case "string":
|
|
80
|
+
case "number":
|
|
81
|
+
case "boolean":
|
|
82
|
+
case "transform":
|
|
83
|
+
return def.type;
|
|
84
|
+
case "enum":
|
|
85
|
+
if ("entries" in def) {
|
|
86
|
+
return Object.keys(def.entries)
|
|
87
|
+
.map((k) => `"${k}"`)
|
|
88
|
+
.join(" | ");
|
|
89
|
+
}
|
|
90
|
+
return "unknown";
|
|
91
|
+
case "literal":
|
|
92
|
+
if ("values" in def) {
|
|
93
|
+
return JSON.stringify(def.values[0]);
|
|
94
|
+
}
|
|
95
|
+
return "unknown";
|
|
96
|
+
case "array":
|
|
97
|
+
if ("element" in def) {
|
|
98
|
+
return printZodTypeDts(def.element) + "[]";
|
|
99
|
+
}
|
|
100
|
+
return "[]";
|
|
101
|
+
case "optional":
|
|
102
|
+
if ("innerType" in def) {
|
|
103
|
+
return printZodTypeDts(def.innerType) + " | undefined";
|
|
104
|
+
}
|
|
105
|
+
return "unknown | undefined";
|
|
106
|
+
case "nullable":
|
|
107
|
+
if ("innerType" in def) {
|
|
108
|
+
return printZodTypeDts(def.innerType) + " | null";
|
|
109
|
+
}
|
|
110
|
+
return "unknown | null";
|
|
111
|
+
case "default":
|
|
112
|
+
//TODO : ignore les valeurs par défaut falsy (0, false, "") dans printZodType, donc dnl explain omet des defaults valides.
|
|
113
|
+
if ("innerType" in def) {
|
|
114
|
+
const result = printZodTypeDts(def.innerType);
|
|
115
|
+
const defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : (def.defaultValue ?? undefined);
|
|
116
|
+
// const defaultValue = (def as any).defaultValue;
|
|
117
|
+
if (defaultValue !== undefined) {
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
return "unknown | null";
|
|
123
|
+
// z.union
|
|
124
|
+
case "union":
|
|
125
|
+
if ("options" in def) {
|
|
126
|
+
return def.options.map(printZodTypeDts).join(" | ");
|
|
127
|
+
}
|
|
128
|
+
return "unknown";
|
|
129
|
+
// z.transform
|
|
130
|
+
case "pipe": {
|
|
131
|
+
if ("in" in def) {
|
|
132
|
+
return printZodTypeDts(def.in);
|
|
133
|
+
}
|
|
134
|
+
return "string"; // fallback défensif
|
|
135
|
+
}
|
|
136
|
+
case "transform": {
|
|
137
|
+
if (def.schema?.def) {
|
|
138
|
+
return printZodTypeDts(def.schema.def);
|
|
139
|
+
}
|
|
140
|
+
if (def.in) {
|
|
141
|
+
return printZodTypeDts(def.in);
|
|
142
|
+
}
|
|
143
|
+
return "string";
|
|
144
|
+
}
|
|
145
|
+
default:
|
|
146
|
+
return "unknown";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
77
149
|
function stringifyEnvValue(value) {
|
|
78
150
|
if (value === undefined || value === null) {
|
|
79
151
|
return undefined;
|
|
@@ -136,3 +208,34 @@ export function isRequired(def) {
|
|
|
136
208
|
return true;
|
|
137
209
|
}
|
|
138
210
|
}
|
|
211
|
+
export function isTransform(def) {
|
|
212
|
+
switch (def.type) {
|
|
213
|
+
// Direct transform wrappers: if we see them anywhere in the tree, it's a transform.
|
|
214
|
+
case "pipe":
|
|
215
|
+
case "transform":
|
|
216
|
+
return true;
|
|
217
|
+
// Transparent wrappers: keep walking.
|
|
218
|
+
case "optional":
|
|
219
|
+
case "nullable":
|
|
220
|
+
case "default":
|
|
221
|
+
if ("innerType" in def) {
|
|
222
|
+
return isTransform(def.innerType);
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
// Arrays: check element.
|
|
226
|
+
case "array":
|
|
227
|
+
if ("element" in def) {
|
|
228
|
+
return isTransform(def.element);
|
|
229
|
+
}
|
|
230
|
+
return false;
|
|
231
|
+
// Unions: any option being a transform means transform.
|
|
232
|
+
case "union":
|
|
233
|
+
if ("options" in def) {
|
|
234
|
+
return def.options.some((opt) => isTransform(opt));
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
237
|
+
// Other types: no transform.
|
|
238
|
+
default:
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IAE7D;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IACV;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CAKvB;AAID;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,aAAa,IAAI;KAClD,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;CAC1C,CAAC;AACF;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,aAAa,IAAI;KAC3C,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CACnD,CAAC;AAEF,KAAK,OAAO,GAAG,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,KAAK,OAAO,CAAC;AACzE,KAAK,QAAQ,CAAC,CAAC,SAAS,aAAa,IAAI,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEvG;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,aAAa,IAAI;IACvD;;OAEG;IACH,GAAG,EAAE,CAAC,CAAC;IACP;;OAEG;IACH,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7B;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C;;;;;;;;OAQG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;OASG;IACH,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,aAAa,EAAE,KAAK,CAAC,KAAG,mBAAmB,CAAC,CAAC,CAuB7E,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,SAa1C,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AASjC,cAAc,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AASjC,cAAc,WAAW,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAE,CAAC;AACf,eAAe,GAAG,CAAC;AAEnB,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-vs-version.test.d.ts","sourceRoot":"","sources":["../../../src/infer/__tests__/port-vs-version.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { portRule } from "../rules/port.js";
|
|
3
|
+
import { versionRule } from "../rules/version.js";
|
|
4
|
+
import { versionGenSchemaNoName } from "../generated/version.js";
|
|
5
|
+
describe("Inference rules – port vs version", () => {
|
|
6
|
+
it("portRule should NOT match API_VERSION=2.0", () => {
|
|
7
|
+
const result = portRule.tryInfer({
|
|
8
|
+
name: "API_VERSION",
|
|
9
|
+
rawValue: "2.0",
|
|
10
|
+
});
|
|
11
|
+
// rule does not apply → null
|
|
12
|
+
expect(result).toBeNull();
|
|
13
|
+
});
|
|
14
|
+
it("versionRule should not match API_VERSION=2.0", () => {
|
|
15
|
+
const result = versionRule.tryInfer({
|
|
16
|
+
name: "API_VERSION",
|
|
17
|
+
rawValue: "2.0",
|
|
18
|
+
});
|
|
19
|
+
// rule does not recognizes a version pattern
|
|
20
|
+
expect(result).toBeNull();
|
|
21
|
+
});
|
|
22
|
+
it("versionRule should not match API_VERSION=2.0.0", () => {
|
|
23
|
+
const result = versionRule.tryInfer({
|
|
24
|
+
name: "API_VERSION",
|
|
25
|
+
rawValue: "2.0.0",
|
|
26
|
+
});
|
|
27
|
+
// rule recognizes a version pattern
|
|
28
|
+
expect(result).not.toBeNull();
|
|
29
|
+
expect(result?.generated.code).toContain(versionGenSchemaNoName.imports[0].name);
|
|
30
|
+
expect(result.confidence).toBeGreaterThanOrEqual(versionRule.threshold);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic.test.d.ts","sourceRoot":"","sources":["../../../../src/infer/__tests__/rules/basic.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { numberRule, emailRule, stringRule } from "../../rules/basic.js";
|
|
3
|
+
import { zEmailGenSchema, zNumberGenSchema, zStringGenSchema } from "../../generated/basic.js";
|
|
4
|
+
describe("Inference rules – basic", () => {
|
|
5
|
+
it("numberRule should match a valid number", () => {
|
|
6
|
+
const input = {
|
|
7
|
+
name: "NUMBER",
|
|
8
|
+
rawValue: "123",
|
|
9
|
+
};
|
|
10
|
+
const result = numberRule.tryInfer(input);
|
|
11
|
+
expect(result).not.toBeNull();
|
|
12
|
+
expect(result?.generated.code).toBe(zNumberGenSchema.code);
|
|
13
|
+
expect(result.confidence).toBeGreaterThanOrEqual(numberRule.threshold);
|
|
14
|
+
});
|
|
15
|
+
it("numberRule should match a valid number wrapped in quotes", () => {
|
|
16
|
+
const input = {
|
|
17
|
+
name: "NUMBER",
|
|
18
|
+
rawValue: '"123"',
|
|
19
|
+
};
|
|
20
|
+
const result = numberRule.tryInfer(input);
|
|
21
|
+
expect(result).not.toBeNull();
|
|
22
|
+
expect(result?.generated.code).toBe(zNumberGenSchema.code);
|
|
23
|
+
expect(result.confidence).toBeGreaterThanOrEqual(numberRule.threshold);
|
|
24
|
+
});
|
|
25
|
+
it("numberRule should match float values", () => {
|
|
26
|
+
const input = {
|
|
27
|
+
name: "RATE",
|
|
28
|
+
rawValue: "-12.5",
|
|
29
|
+
};
|
|
30
|
+
const result = numberRule.tryInfer(input);
|
|
31
|
+
expect(result).not.toBeNull();
|
|
32
|
+
expect(result?.generated.code).toBe(zNumberGenSchema.code);
|
|
33
|
+
expect(result.confidence).toBeGreaterThanOrEqual(numberRule.threshold);
|
|
34
|
+
});
|
|
35
|
+
it("numberRule should match integers outside port range", () => {
|
|
36
|
+
const input = {
|
|
37
|
+
name: "BIG_NUMBER",
|
|
38
|
+
rawValue: "+7e6",
|
|
39
|
+
};
|
|
40
|
+
const result = numberRule.tryInfer(input);
|
|
41
|
+
expect(result).not.toBeNull();
|
|
42
|
+
expect(result?.generated.code).toBe(zNumberGenSchema.code);
|
|
43
|
+
expect(result.confidence).toBeGreaterThanOrEqual(numberRule.threshold);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("Inference rules – email", () => {
|
|
47
|
+
it("emailRule should match a valid email-like value", () => {
|
|
48
|
+
const input = {
|
|
49
|
+
name: "CONTACT_EMAIL",
|
|
50
|
+
rawValue: "dev@example.com",
|
|
51
|
+
};
|
|
52
|
+
const result = emailRule.tryInfer(input);
|
|
53
|
+
expect(result).not.toBeNull();
|
|
54
|
+
expect(result?.generated.code).toBe(zEmailGenSchema.code);
|
|
55
|
+
expect(result.confidence).toBeGreaterThanOrEqual(emailRule.threshold);
|
|
56
|
+
});
|
|
57
|
+
it("emailRule should ignore non-email values", () => {
|
|
58
|
+
const input = {
|
|
59
|
+
name: "NOT_EMAIL",
|
|
60
|
+
rawValue: "dev@example",
|
|
61
|
+
};
|
|
62
|
+
const result = emailRule.tryInfer(input);
|
|
63
|
+
expect(result).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
it("emailRule should ignore non-email values (database URL)", () => {
|
|
66
|
+
const input = {
|
|
67
|
+
name: "DATABASE_URL",
|
|
68
|
+
rawValue: "postgres://user:pass@localhost:5432/app",
|
|
69
|
+
};
|
|
70
|
+
const result = emailRule.tryInfer(input);
|
|
71
|
+
expect(result).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("Inference rules – string", () => {
|
|
75
|
+
it("stringRule should always fallback to string", () => {
|
|
76
|
+
const input = {
|
|
77
|
+
name: "ANY_VALUE",
|
|
78
|
+
rawValue: "whatever",
|
|
79
|
+
};
|
|
80
|
+
const result = stringRule.tryInfer(input);
|
|
81
|
+
expect(result).not.toBeNull();
|
|
82
|
+
expect(result?.generated.code).toBe(zStringGenSchema.code);
|
|
83
|
+
expect(result.confidence).toBeGreaterThanOrEqual(stringRule.threshold);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boolean.test.d.ts","sourceRoot":"","sources":["../../../../src/infer/__tests__/rules/boolean.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { booleanRule } from "../../rules/boolean.js";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
describe("Inference rules – boolean", () => {
|
|
4
|
+
it("booleanRule should match strict boolean values", () => {
|
|
5
|
+
const trueFalseValues = ["true", "false"];
|
|
6
|
+
for (const rawValue of trueFalseValues) {
|
|
7
|
+
const result = booleanRule.tryInfer({
|
|
8
|
+
name: "IS_ENABLED",
|
|
9
|
+
rawValue,
|
|
10
|
+
});
|
|
11
|
+
expect(result).not.toBeNull();
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
it("booleanRule should match 0 or 1 values", () => {
|
|
15
|
+
const zeroOneValues = ["0", "1"];
|
|
16
|
+
for (const rawValue of zeroOneValues) {
|
|
17
|
+
const result = booleanRule.tryInfer({
|
|
18
|
+
name: "IS_ENABLED",
|
|
19
|
+
rawValue,
|
|
20
|
+
});
|
|
21
|
+
expect(result).not.toBeNull();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
it("booleanRule should match yes,no,y,n values", () => {
|
|
25
|
+
const yesNoValues = ["yes", "no", "y", "n"];
|
|
26
|
+
for (const rawValue of yesNoValues) {
|
|
27
|
+
const result = booleanRule.tryInfer({
|
|
28
|
+
name: "IS_ENABLED",
|
|
29
|
+
rawValue,
|
|
30
|
+
});
|
|
31
|
+
expect(result).not.toBeNull();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.test.d.ts","sourceRoot":"","sources":["../../../../src/infer/__tests__/rules/duration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { durationRule } from "../../rules/duration.js";
|
|
3
|
+
describe("Inference rules – duration", () => {
|
|
4
|
+
it("durationRule should match a valid duration", () => {
|
|
5
|
+
const validDurations = ["5s", "10m", "2h", "3d", "4w", "5M", "6y"];
|
|
6
|
+
for (const rawValue of validDurations) {
|
|
7
|
+
const result = durationRule.tryInfer({
|
|
8
|
+
name: "REQUEST_TIMEOUT",
|
|
9
|
+
rawValue,
|
|
10
|
+
});
|
|
11
|
+
expect(result).not.toBeNull();
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
it("durationRule should ignore invalid durations", () => {
|
|
15
|
+
const invalidDurations = ["5", "-55.5h"];
|
|
16
|
+
for (const rawValue of invalidDurations) {
|
|
17
|
+
const result = durationRule.tryInfer({
|
|
18
|
+
name: "REQUEST_TIMEOUT",
|
|
19
|
+
rawValue,
|
|
20
|
+
});
|
|
21
|
+
expect(result).toBeNull();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip.test.d.ts","sourceRoot":"","sources":["../../../../src/infer/__tests__/rules/ip.test.ts"],"names":[],"mappings":""}
|