varlock 0.3.0 → 0.4.1

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.
Files changed (65) hide show
  1. package/README.md +23 -10
  2. package/dist/chunk-3U2C5ACW.js +48 -0
  3. package/dist/chunk-3U2C5ACW.js.map +1 -0
  4. package/dist/{chunk-MXZI2FC6.js → chunk-6SS4YD2I.js} +5 -5
  5. package/dist/{chunk-MXZI2FC6.js.map → chunk-6SS4YD2I.js.map} +1 -1
  6. package/dist/{chunk-26ICEAKS.js → chunk-AHEBZW37.js} +9 -8
  7. package/dist/chunk-AHEBZW37.js.map +1 -0
  8. package/dist/{chunk-IG5PPVD7.js → chunk-BGPQX6XO.js} +6 -6
  9. package/dist/{chunk-IG5PPVD7.js.map → chunk-BGPQX6XO.js.map} +1 -1
  10. package/dist/{chunk-MHIFZAPA.js → chunk-CBWJHW3M.js} +7 -7
  11. package/dist/{chunk-MHIFZAPA.js.map → chunk-CBWJHW3M.js.map} +1 -1
  12. package/dist/{chunk-JDMZWNQA.js → chunk-HS2NN4VF.js} +7 -7
  13. package/dist/chunk-HS2NN4VF.js.map +1 -0
  14. package/dist/chunk-I4RYFNPM.js +22 -0
  15. package/dist/chunk-I4RYFNPM.js.map +1 -0
  16. package/dist/{chunk-GEJNYKR4.js → chunk-MBYYRBL6.js} +3 -3
  17. package/dist/{chunk-GEJNYKR4.js.map → chunk-MBYYRBL6.js.map} +1 -1
  18. package/dist/{chunk-VQ5I7WMP.js → chunk-NWY5IIPW.js} +3 -3
  19. package/dist/{chunk-VQ5I7WMP.js.map → chunk-NWY5IIPW.js.map} +1 -1
  20. package/dist/{chunk-WDC5CEKD.js → chunk-ONSMSCMG.js} +5 -5
  21. package/dist/{chunk-WDC5CEKD.js.map → chunk-ONSMSCMG.js.map} +1 -1
  22. package/dist/{chunk-TLXFVH7P.js → chunk-P7WVEZYA.js} +4 -4
  23. package/dist/{chunk-TLXFVH7P.js.map → chunk-P7WVEZYA.js.map} +1 -1
  24. package/dist/{chunk-WZW7QS6M.js → chunk-PCRIVT4T.js} +342 -32
  25. package/dist/chunk-PCRIVT4T.js.map +1 -0
  26. package/dist/{chunk-KKPD7AYU.js → chunk-PIOJV2A7.js} +4 -4
  27. package/dist/{chunk-KKPD7AYU.js.map → chunk-PIOJV2A7.js.map} +1 -1
  28. package/dist/{chunk-LZ52O5WU.js → chunk-RQDMJMKL.js} +14 -23
  29. package/dist/chunk-RQDMJMKL.js.map +1 -0
  30. package/dist/cli/cli-executable.js +33 -25
  31. package/dist/cli/cli-executable.js.map +1 -1
  32. package/dist/config-item-K7KWEJD2.js +5 -0
  33. package/dist/{config-item-2AL7WF23.js.map → config-item-K7KWEJD2.js.map} +1 -1
  34. package/dist/{env-graph-C8s2oqOJ.d.ts → env-graph-COORmJlH.d.ts} +59 -0
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.js +6 -4
  37. package/dist/index.js.map +1 -1
  38. package/dist/init.command-SZPMB525.js +12 -0
  39. package/dist/{init.command-J4HZL3PB.js.map → init.command-SZPMB525.js.map} +1 -1
  40. package/dist/load.command-XSOTCSGA.js +11 -0
  41. package/dist/{load.command-6DAP7LEX.js.map → load.command-XSOTCSGA.js.map} +1 -1
  42. package/dist/plugin-lib.d.ts +2 -2
  43. package/dist/printenv.command-4HWCHHCY.js +12 -0
  44. package/dist/{printenv.command-7B7SZ2EF.js.map → printenv.command-4HWCHHCY.js.map} +1 -1
  45. package/dist/run.command-DIN6XVLO.js +12 -0
  46. package/dist/{run.command-HVV6XXDR.js.map → run.command-DIN6XVLO.js.map} +1 -1
  47. package/dist/runtime/env.d.ts +1 -1
  48. package/dist/scan.command-4J64EB4Z.js +13 -0
  49. package/dist/{scan.command-Q33VJOPD.js.map → scan.command-4J64EB4Z.js.map} +1 -1
  50. package/dist/telemetry.command-44NGPRGQ.js +11 -0
  51. package/dist/{telemetry.command-HOJDUCKG.js.map → telemetry.command-44NGPRGQ.js.map} +1 -1
  52. package/dist/typegen.command-7BE3K6PU.js +12 -0
  53. package/dist/typegen.command-7BE3K6PU.js.map +1 -0
  54. package/package.json +13 -12
  55. package/dist/chunk-26ICEAKS.js.map +0 -1
  56. package/dist/chunk-JDMZWNQA.js.map +0 -1
  57. package/dist/chunk-LZ52O5WU.js.map +0 -1
  58. package/dist/chunk-WZW7QS6M.js.map +0 -1
  59. package/dist/config-item-2AL7WF23.js +0 -5
  60. package/dist/init.command-J4HZL3PB.js +0 -12
  61. package/dist/load.command-6DAP7LEX.js +0 -11
  62. package/dist/printenv.command-7B7SZ2EF.js +0 -12
  63. package/dist/run.command-HVV6XXDR.js +0 -12
  64. package/dist/scan.command-Q33VJOPD.js +0 -13
  65. package/dist/telemetry.command-HOJDUCKG.js +0 -11
package/README.md CHANGED
@@ -2,9 +2,18 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/varlock.svg)](https://www.npmjs.com/package/varlock) [![npm downloads](https://img.shields.io/npm/dm/varlock.svg)](https://www.npmjs.com/package/varlock) [![GitHub stars](https://img.shields.io/github/stars/dmno-dev/varlock.svg?style=social&label=Star)](https://github.com/dmno-dev/varlock) [![license](https://img.shields.io/npm/l/varlock.svg)](https://github.com/dmno-dev/varlock/blob/main/LICENSE)
4
4
 
5
- > See https://varlock.dev for docs and examples.
5
+ > AI-safe .env files: Schemas for agents, Secrets for humans.
6
6
 
7
- _A sample `.env.schema`_:
7
+ - 🤖 AI-safe config — agents read your schema, never your secrets
8
+ - 🔍 proactive leak scanning via `varlock scan` + git hooks
9
+ - 🔏 runtime protection — log redaction and leak prevention
10
+ - 🛡️ validation, coercion, type safety w/ IntelliSense
11
+ - 🌐 flexible multi-environment management — auto .env.* loading and explicit import
12
+ - 🔌 6 secret manager plugins (1Password, Infisical, AWS, Azure, GCP, Bitwarden)
13
+
14
+ See https://varlock.dev for full docs and examples.
15
+
16
+ _A sample `.env.schema`_:
8
17
  ```bash
9
18
  # @currentEnv=$APP_ENV
10
19
  # ---
@@ -14,11 +23,11 @@ APP_ENV=development #sets default value
14
23
 
15
24
  # API port
16
25
  # @type=port @example=3000
17
- API_PORT=
26
+ API_PORT=
18
27
 
19
28
  # API url including expansion of another env var
20
29
  # @required @type=url
21
- API_URL=localhost:${API_PORT}
30
+ API_URL=localhost:${API_PORT}
22
31
 
23
32
  # API key with validation, securely fetched from 1Password
24
33
  # @required @sensitive @type=string(startsWith=sk-)
@@ -31,7 +40,7 @@ SOME_SERVICE_API_URL=https://api.someservice.com
31
40
 
32
41
  ## Installation
33
42
 
34
- You can get started with varlock by installing the CLI:
43
+ You can get started with varlock by installing the CLI:
35
44
 
36
45
  ```bash
37
46
  # Install as a dependency in a js project
@@ -44,28 +53,32 @@ brew install dmno-dev/tap/varlock
44
53
  curl -sSfL https://varlock.dev/install.sh | sh -s
45
54
  ```
46
55
 
47
- See the full installation [docs](https://varlock.dev/getting-started/installation/).
56
+ See the full installation [docs](https://varlock.dev/getting-started/installation/).
48
57
 
49
58
  ## Workflow
50
59
 
51
- Validate your `.env.schema` with:
60
+ Validate your `.env.schema` with:
52
61
 
53
62
  ```bash
54
63
  varlock load
55
64
  ```
56
65
 
57
- If you need to pass resolved env vars into another process, you can run:
66
+ If you need to pass resolved env vars into another process, you can run:
58
67
 
59
68
  ```bash
60
69
  varlock run -- node script.js
61
70
  ```
62
71
 
63
- Or you can integrate more deeply with one of our [integrations](https://varlock.dev/integrations/javascript/) to get log redaction and leak prevention.
72
+ Or you can integrate more deeply with one of our [integrations](https://varlock.dev/integrations/javascript/) to get log redaction and leak prevention.
73
+
74
+ ## AI-Safe Config
75
+
76
+ Your `.env.schema` gives AI agents full context on your config — variable names, types, validation rules, descriptions — without ever exposing secret values. Combined with `varlock scan` to catch leaked secrets in AI-generated code, varlock is purpose-built for the AI era. Learn more in the [AI-safe config guide](https://varlock.dev/guides/ai-tools/).
64
77
 
65
78
  ## @env-spec
66
79
 
67
80
  Varlock is built on top of @env-spec, a new DSL for attaching a schema and additional functionality to .env files using JSDoc style comments. The @env-spec package contains a parser and info about the spec itself.
68
81
 
69
- - @env-spec [docs](https://varlock.dev/env-spec/overview/)
82
+ - @env-spec [docs](https://varlock.dev/env-spec/overview/)
70
83
  - @env-spec [RFC](https://github.com/dmno-dev/varlock/discussions/17)
71
84
 
@@ -0,0 +1,48 @@
1
+ import { CliExitError } from './chunk-PIOJV2A7.js';
2
+ import { define } from './chunk-4A54P4EM.js';
3
+ import { checkForSchemaErrors, checkForNoEnvFiles } from './chunk-P7WVEZYA.js';
4
+ import { loadVarlockEnvGraph } from './chunk-MBYYRBL6.js';
5
+ import { __name } from './chunk-6PEHRAEP.js';
6
+
7
+ // src/cli/commands/typegen.command.ts
8
+ var commandSpec = define({
9
+ name: "typegen",
10
+ description: "Generate TypeScript types from your env schema",
11
+ args: {
12
+ path: {
13
+ type: "string",
14
+ short: "p",
15
+ description: "Path to a specific .env file or directory to use as the entry point"
16
+ }
17
+ },
18
+ examples: `
19
+ Generates TypeScript type definitions from your .env schema files.
20
+ Uses only non-environment-specific schema info, so output is deterministic
21
+ regardless of which environment is active.
22
+
23
+ This is useful when you have \`@generateTypes(lang=ts, path=env.d.ts, auto=false)\`
24
+ in your schema to disable automatic type generation during \`varlock load\` or \`varlock run\`.
25
+
26
+ Examples:
27
+ varlock typegen # Generate types using default schema
28
+ varlock typegen --path .env.prod # Generate types from a specific .env file
29
+ `.trim()
30
+ });
31
+ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
32
+ const envGraph = await loadVarlockEnvGraph({
33
+ entryFilePath: ctx.values.path
34
+ });
35
+ checkForSchemaErrors(envGraph);
36
+ checkForNoEnvFiles(envGraph);
37
+ const generatedCount = await envGraph.generateTypesIfNeeded({ ignoreAutoFalse: true });
38
+ if (generatedCount === 0) {
39
+ throw new CliExitError("No @generateTypes decorator found in your schema", {
40
+ suggestion: "Add `@generateTypes(lang=ts, path=env.d.ts)` to your .env.schema file."
41
+ });
42
+ }
43
+ console.log("\u2705 Types generated successfully");
44
+ }, "commandFn");
45
+
46
+ export { commandFn, commandSpec };
47
+ //# sourceMappingURL=chunk-3U2C5ACW.js.map
48
+ //# sourceMappingURL=chunk-3U2C5ACW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/typegen.command.ts"],"names":[],"mappings":";;;;;;;AAOO,IAAM,cAAc,MAAA,CAAO;AAAA,EAChC,IAAA,EAAM,SAAA;AAAA,EACN,WAAA,EAAa,gDAAA;AAAA,EACb,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,QAAA;AAAA,MACN,KAAA,EAAO,GAAA;AAAA,MACP,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,QAAA,EAAU;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA,CAWV,IAAA;AACF,CAAC;AAGM,IAAM,SAAA,iCAA6D,GAAA,KAAQ;AAChF,EAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB;AAAA,IACzC,aAAA,EAAe,IAAI,MAAA,CAAO;AAAA,GAC3B,CAAA;AACD,EAAA,oBAAA,CAAqB,QAAQ,CAAA;AAC7B,EAAA,kBAAA,CAAmB,QAAQ,CAAA;AAG3B,EAAA,MAAM,iBAAiB,MAAM,QAAA,CAAS,sBAAsB,EAAE,eAAA,EAAiB,MAAM,CAAA;AAErF,EAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,aAAa,kDAAA,EAAoD;AAAA,MACzE,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,OAAA,CAAQ,IAAI,qCAAgC,CAAA;AAC9C,CAAA,EAjBmE,WAAA","file":"chunk-3U2C5ACW.js","sourcesContent":["import { define } from 'gunshi';\n\nimport { loadVarlockEnvGraph } from '../../lib/load-graph';\nimport { checkForNoEnvFiles, checkForSchemaErrors } from '../helpers/error-checks';\nimport { CliExitError } from '../helpers/exit-error';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\n\nexport const commandSpec = define({\n name: 'typegen',\n description: 'Generate TypeScript types from your env schema',\n args: {\n path: {\n type: 'string',\n short: 'p',\n description: 'Path to a specific .env file or directory to use as the entry point',\n },\n },\n examples: `\nGenerates TypeScript type definitions from your .env schema files.\nUses only non-environment-specific schema info, so output is deterministic\nregardless of which environment is active.\n\nThis is useful when you have \\`@generateTypes(lang=ts, path=env.d.ts, auto=false)\\`\nin your schema to disable automatic type generation during \\`varlock load\\` or \\`varlock run\\`.\n\nExamples:\n varlock typegen # Generate types using default schema\n varlock typegen --path .env.prod # Generate types from a specific .env file\n`.trim(),\n});\n\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n const envGraph = await loadVarlockEnvGraph({\n entryFilePath: ctx.values.path as string | undefined,\n });\n checkForSchemaErrors(envGraph);\n checkForNoEnvFiles(envGraph);\n\n // Force type generation even if auto=false is set\n const generatedCount = await envGraph.generateTypesIfNeeded({ ignoreAutoFalse: true });\n\n if (generatedCount === 0) {\n throw new CliExitError('No @generateTypes decorator found in your schema', {\n suggestion: 'Add `@generateTypes(lang=ts, path=env.d.ts)` to your .env.schema file.',\n });\n }\n\n console.log('✅ Types generated successfully');\n};\n"]}
@@ -1,6 +1,6 @@
1
- import { CliExitError } from './chunk-KKPD7AYU.js';
2
- import { ansis_default } from './chunk-VQ5I7WMP.js';
3
- import { pathExistsSync } from './chunk-WZW7QS6M.js';
1
+ import { CliExitError } from './chunk-PIOJV2A7.js';
2
+ import { ansis_default } from './chunk-NWY5IIPW.js';
3
+ import { pathExistsSync } from './chunk-PCRIVT4T.js';
4
4
  import { createDebug } from './chunk-QZ6HBRJC.js';
5
5
  import { __name } from './chunk-6PEHRAEP.js';
6
6
  import path from 'path';
@@ -152,5 +152,5 @@ var logLines = /* @__PURE__ */ __name((lines) => {
152
152
  }, "logLines");
153
153
 
154
154
  export { detectJsPackageManager, fmt, installJsDependency, logLines };
155
- //# sourceMappingURL=chunk-MXZI2FC6.js.map
156
- //# sourceMappingURL=chunk-MXZI2FC6.js.map
155
+ //# sourceMappingURL=chunk-6SS4YD2I.js.map
156
+ //# sourceMappingURL=chunk-6SS4YD2I.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-MXZI2FC6.js","sourcesContent":["import path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { pathExistsSync } from '@env-spec/utils/fs-utils';\nimport { createDebug } from '../../lib/debug';\n\nimport { CliExitError } from './exit-error';\nimport { execSync } from 'node:child_process';\n\nconst debug = createDebug('varlock:js-package-manager-utils');\n\nexport type JsPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno';\n\nexport type JsPackageManagerMeta = {\n name: JsPackageManager;\n lockfiles: Array<string>;\n add: string;\n exec: string;\n dlx: string;\n};\n\nexport const JS_PACKAGE_MANAGERS: Record<JsPackageManager, JsPackageManagerMeta> = Object.freeze({\n npm: {\n name: 'npm',\n lockfiles: ['package-lock.json'],\n add: 'npm install', // add also works\n exec: 'npm exec --',\n dlx: 'npx',\n },\n pnpm: {\n name: 'pnpm',\n lockfiles: ['pnpm-lock.yaml'],\n add: 'pnpm add',\n exec: 'pnpm exec',\n dlx: 'pnpm dlx',\n },\n yarn: {\n name: 'yarn',\n lockfiles: ['yarn.lock'],\n add: 'yarn add',\n exec: 'yarn exec --',\n dlx: 'yarn dlx',\n },\n bun: {\n name: 'bun',\n lockfiles: ['bun.lock', 'bun.lockb'],\n add: 'bun add',\n exec: 'bun run',\n dlx: 'bunx',\n },\n deno: { //! deno not fully supported yet\n name: 'deno',\n lockfiles: ['deno.lock'],\n add: 'deno add',\n // TODO: don't think these are quite right...\n exec: 'deno run',\n dlx: 'deno run',\n },\n});\n\n/**\n * detect js package manager\n *\n * currently go up the folder tree looking for lockfiles (ex: package-lock.json, pnpm-lock.yaml)\n * if nothing found, we'll look at process.env.npm_config_user_agent\n * */\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n workspaceRootPath?: string,\n exitIfNotFound?: boolean,\n}) {\n debug('Detecting js package manager');\n let cwd = opts?.cwd || process.cwd();\n let multipleLockfilesDetected: Array<JsPackageManager> | undefined;\n do {\n debug(`> scanning ${cwd}`);\n const scanDir = cwd;\n let pm: JsPackageManager;\n let detectedPm: JsPackageManager | undefined;\n for (pm in JS_PACKAGE_MANAGERS) {\n const foundLockfile = JS_PACKAGE_MANAGERS[pm].lockfiles.find(\n (lockfile) => pathExistsSync(path.join(scanDir, lockfile)),\n );\n\n if (foundLockfile) {\n // if we find 2 lockfiles at the same level, store them and continue\n // this can happen in monorepos or when switching package managers\n if (detectedPm) {\n debug(`> found multiple lockfiles: ${foundLockfile} and ${JS_PACKAGE_MANAGERS[detectedPm].lockfiles[0]}`);\n multipleLockfilesDetected = [detectedPm, pm];\n break;\n }\n debug(`> found ${foundLockfile}`);\n detectedPm = pm;\n }\n }\n if (detectedPm && !multipleLockfilesDetected) return JS_PACKAGE_MANAGERS[detectedPm];\n if (multipleLockfilesDetected) break;\n\n // will break when we reach the root\n const parentDir = path.dirname(cwd);\n if (parentDir === cwd) break;\n cwd = parentDir;\n\n if (opts?.workspaceRootPath) {\n if (opts.workspaceRootPath === cwd) {\n debug('> found workspace root');\n break;\n }\n } else {\n // if we don't have a workspace root path, we'll break if we hit the git repo root\n if (pathExistsSync(path.join(cwd, '.git'))) {\n debug('> found git root');\n break;\n }\n }\n } while (cwd);\n\n // if we did not find a lockfile, we'll look at env vars for other hints\n if (process.env.npm_config_user_agent) {\n const pmFromAgent = process.env.npm_config_user_agent.split('/')[0];\n if (Object.keys(JS_PACKAGE_MANAGERS).includes(pmFromAgent)) {\n debug(`> found ${pmFromAgent} using npm_config_user_agent`);\n return JS_PACKAGE_MANAGERS[pmFromAgent as JsPackageManager];\n }\n }\n\n // if we found multiple lockfiles and env var detection failed, return the first detected one\n // we choose the first one because the order is deterministic (based on the order in JS_PACKAGE_MANAGERS)\n // and this provides a reasonable fallback when we can't determine the active package manager\n if (multipleLockfilesDetected) {\n debug(`> using ${multipleLockfilesDetected[0]} from multiple detected lockfiles`);\n return JS_PACKAGE_MANAGERS[multipleLockfilesDetected[0]];\n }\n\n if (opts?.exitIfNotFound) {\n // show some hopefully useful error messaging if we hit the root folder without finding anything\n throw new CliExitError('Unable to find detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n}\n\n\n\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n\n","import ansis from 'ansis';\nimport { detectJsPackageManager, JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
1
+ {"version":3,"sources":["../src/cli/helpers/js-package-manager-utils.ts","../src/cli/helpers/pretty-format.ts"],"names":[],"mappings":"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","file":"chunk-6SS4YD2I.js","sourcesContent":["import path from 'node:path';\nimport fs, { existsSync } from 'node:fs';\nimport { pathExistsSync } from '@env-spec/utils/fs-utils';\nimport { createDebug } from '../../lib/debug';\n\nimport { CliExitError } from './exit-error';\nimport { execSync } from 'node:child_process';\n\nconst debug = createDebug('varlock:js-package-manager-utils');\n\nexport type JsPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno';\n\nexport type JsPackageManagerMeta = {\n name: JsPackageManager;\n lockfiles: Array<string>;\n add: string;\n exec: string;\n dlx: string;\n};\n\nexport const JS_PACKAGE_MANAGERS: Record<JsPackageManager, JsPackageManagerMeta> = Object.freeze({\n npm: {\n name: 'npm',\n lockfiles: ['package-lock.json'],\n add: 'npm install', // add also works\n exec: 'npm exec --',\n dlx: 'npx',\n },\n pnpm: {\n name: 'pnpm',\n lockfiles: ['pnpm-lock.yaml'],\n add: 'pnpm add',\n exec: 'pnpm exec',\n dlx: 'pnpm dlx',\n },\n yarn: {\n name: 'yarn',\n lockfiles: ['yarn.lock'],\n add: 'yarn add',\n exec: 'yarn exec --',\n dlx: 'yarn dlx',\n },\n bun: {\n name: 'bun',\n lockfiles: ['bun.lock', 'bun.lockb'],\n add: 'bun add',\n exec: 'bun run',\n dlx: 'bunx',\n },\n deno: { //! deno not fully supported yet\n name: 'deno',\n lockfiles: ['deno.lock'],\n add: 'deno add',\n // TODO: don't think these are quite right...\n exec: 'deno run',\n dlx: 'deno run',\n },\n});\n\n/**\n * detect js package manager\n *\n * currently go up the folder tree looking for lockfiles (ex: package-lock.json, pnpm-lock.yaml)\n * if nothing found, we'll look at process.env.npm_config_user_agent\n * */\nexport function detectJsPackageManager(opts?: {\n cwd?: string,\n workspaceRootPath?: string,\n exitIfNotFound?: boolean,\n}) {\n debug('Detecting js package manager');\n let cwd = opts?.cwd || process.cwd();\n let multipleLockfilesDetected: Array<JsPackageManager> | undefined;\n do {\n debug(`> scanning ${cwd}`);\n const scanDir = cwd;\n let pm: JsPackageManager;\n let detectedPm: JsPackageManager | undefined;\n for (pm in JS_PACKAGE_MANAGERS) {\n const foundLockfile = JS_PACKAGE_MANAGERS[pm].lockfiles.find(\n (lockfile) => pathExistsSync(path.join(scanDir, lockfile)),\n );\n\n if (foundLockfile) {\n // if we find 2 lockfiles at the same level, store them and continue\n // this can happen in monorepos or when switching package managers\n if (detectedPm) {\n debug(`> found multiple lockfiles: ${foundLockfile} and ${JS_PACKAGE_MANAGERS[detectedPm].lockfiles[0]}`);\n multipleLockfilesDetected = [detectedPm, pm];\n break;\n }\n debug(`> found ${foundLockfile}`);\n detectedPm = pm;\n }\n }\n if (detectedPm && !multipleLockfilesDetected) return JS_PACKAGE_MANAGERS[detectedPm];\n if (multipleLockfilesDetected) break;\n\n // will break when we reach the root\n const parentDir = path.dirname(cwd);\n if (parentDir === cwd) break;\n cwd = parentDir;\n\n if (opts?.workspaceRootPath) {\n if (opts.workspaceRootPath === cwd) {\n debug('> found workspace root');\n break;\n }\n } else {\n // if we don't have a workspace root path, we'll break if we hit the git repo root\n if (pathExistsSync(path.join(cwd, '.git'))) {\n debug('> found git root');\n break;\n }\n }\n } while (cwd);\n\n // if we did not find a lockfile, we'll look at env vars for other hints\n if (process.env.npm_config_user_agent) {\n const pmFromAgent = process.env.npm_config_user_agent.split('/')[0];\n if (Object.keys(JS_PACKAGE_MANAGERS).includes(pmFromAgent)) {\n debug(`> found ${pmFromAgent} using npm_config_user_agent`);\n return JS_PACKAGE_MANAGERS[pmFromAgent as JsPackageManager];\n }\n }\n\n // if we found multiple lockfiles and env var detection failed, return the first detected one\n // we choose the first one because the order is deterministic (based on the order in JS_PACKAGE_MANAGERS)\n // and this provides a reasonable fallback when we can't determine the active package manager\n if (multipleLockfilesDetected) {\n debug(`> using ${multipleLockfilesDetected[0]} from multiple detected lockfiles`);\n return JS_PACKAGE_MANAGERS[multipleLockfilesDetected[0]];\n }\n\n if (opts?.exitIfNotFound) {\n // show some hopefully useful error messaging if we hit the root folder without finding anything\n throw new CliExitError('Unable to find detect your JavaScript package manager!', {\n suggestion: 'We look for lock files (ex: package-lock.json) so you may just need to run a dependency install (ie `npm install`)',\n forceExit: true,\n });\n }\n}\n\n\n\n\nexport function installJsDependency(opts: {\n packageName: string,\n packageManager: JsPackageManager,\n packagePath?: string,\n isMonoRepoRoot?: boolean,\n}) {\n const packageJsonPath = path.join(opts.packagePath || process.cwd(), 'package.json');\n\n // for now, we'll just bail if we dont see a package.json\n if (!existsSync(packageJsonPath)) return false;\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n // bail if already installed\n if (packageJson.dependencies?.varlock) return false;\n\n // TODO: might want to check first if it's already installed?\n execSync([\n // move to the correct directory if needed\n opts.packagePath && `cd ${opts.packagePath} &&`,\n // `add` works in all of them\n `${opts.packageManager} add ${opts.packageName}`,\n // tells pnpm to either install in the workspace root explicitly\n // or to not check if we are the in the root\n opts.packageManager === 'pnpm' && (opts.isMonoRepoRoot ? '-w' : '--ignore-workspace-root-check'),\n ].filter(Boolean).join(' '));\n\n return true;\n}\n\n","import ansis from 'ansis';\nimport { detectJsPackageManager, JsPackageManagerMeta } from './js-package-manager-utils';\n\n\nexport const fmt = {\n decorator: (s: string) => ansis.magenta(s),\n filePath: (s: string) => `📂 ${ansis.cyan.italic(s)}`,\n fileName: (s: string) => `${ansis.cyan.italic(s)}`,\n command: (s: string, opts?: { jsPackageManager?: JsPackageManagerMeta | true }) => {\n let jsPackageManager: JsPackageManagerMeta | undefined;\n if (opts?.jsPackageManager === true) {\n jsPackageManager = detectJsPackageManager();\n } else if (opts?.jsPackageManager) {\n jsPackageManager = opts.jsPackageManager;\n }\n if (jsPackageManager) {\n s = `${jsPackageManager.exec} ${s}`;\n }\n return ansis.green.italic(s);\n },\n packageName: (s: string) => ansis.green.italic(s),\n};\n\nexport const logLines = (lines: Array<string | false | undefined>) => {\n for (const line of lines) {\n // skip false, null, undefined, but not empty strings\n if (!line && line !== '') continue;\n console.log(line);\n }\n};\n"]}
@@ -1,9 +1,9 @@
1
- import { fmt } from './chunk-MXZI2FC6.js';
2
- import { CliExitError } from './chunk-KKPD7AYU.js';
1
+ import { fmt } from './chunk-6SS4YD2I.js';
2
+ import { CliExitError } from './chunk-PIOJV2A7.js';
3
3
  import { define } from './chunk-4A54P4EM.js';
4
- import { gracefulExit } from './chunk-VQ5I7WMP.js';
4
+ import { gracefulExit } from './chunk-NWY5IIPW.js';
5
+ import { getUserVarlockDir } from './chunk-PCRIVT4T.js';
5
6
  import { __name } from './chunk-6PEHRAEP.js';
6
- import { homedir } from 'os';
7
7
  import { join } from 'path';
8
8
  import { mkdir, readFile, writeFile } from 'fs/promises';
9
9
  import { existsSync } from 'fs';
@@ -19,7 +19,8 @@ var commandSpec = define({
19
19
  },
20
20
  examples: `
21
21
  Opts in/out of anonymous usage analytics. This command creates/updates a configuration
22
- file at ~/.varlock/config.json saving your preference.
22
+ file at $XDG_CONFIG_HOME/varlock/config.json (or ~/.config/varlock/config.json) saving
23
+ your preference.
23
24
 
24
25
  Examples:
25
26
  varlock telemetry disable # Opt out of telemetry
@@ -35,7 +36,7 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
35
36
  forceExit: true
36
37
  });
37
38
  }
38
- const configDir = join(homedir(), ".varlock");
39
+ const configDir = getUserVarlockDir();
39
40
  const configPath = join(configDir, "config.json");
40
41
  try {
41
42
  if (!existsSync(configDir)) {
@@ -62,5 +63,5 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
62
63
  }, "commandFn");
63
64
 
64
65
  export { commandFn, commandSpec };
65
- //# sourceMappingURL=chunk-26ICEAKS.js.map
66
- //# sourceMappingURL=chunk-26ICEAKS.js.map
66
+ //# sourceMappingURL=chunk-AHEBZW37.js.map
67
+ //# sourceMappingURL=chunk-AHEBZW37.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/telemetry.command.ts"],"names":[],"mappings":";;;;;;;;;;AAWO,IAAM,cAAc,MAAA,CAAO;AAAA,EAChC,IAAA,EAAM,WAAA;AAAA,EACN,WAAA,EAAa,0CAAA;AAAA,EACb,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,YAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,QAAA,EAAU;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,EAAA,CAAA,CAWR,IAAA;AACJ,CAAC;AAEM,IAAM,SAAA,iCAA6D,GAAA,KAAQ;AAEhF,EAAA,IAAI,CAAC,CAAC,QAAA,EAAU,SAAS,EAAE,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,EAAG;AACpD,IAAA,MAAM,IAAI,aAAa,8CAAA,EAAgD;AAAA,MACrE,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,SAAA,EAAW,aAAa,CAAA;AAEhD,EAAA,IAAI;AAEF,IAAA,IAAI,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AAC1B,MAAA,MAAM,KAAA,CAAM,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IAC5C;AAGA,IAAA,IAAI,SAA8B,EAAC;AACnC,IAAA,IAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,MAAA,MAAM,aAAA,GAAgB,MAAM,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AACxD,MAAA,MAAA,GAAS,IAAA,CAAK,MAAM,aAAa,CAAA;AAAA,IACnC;AAGA,IAAA,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,KAAS,SAAA,SAAkB,iBAAA,GAAoB,IAAA;AAAA,gBAClD,MAAA,CAAO,iBAAA;AACnB,IAAA,MAAM,UAAU,UAAA,EAAY,IAAA,CAAK,UAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAE3D,IAAA,IAAI,GAAA,CAAI,OAAO,IAAA,EAAM;AACnB,MAAA,OAAA,CAAQ,IAAI,uDAAkD,CAAA;AAAA,IAChE,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAI,wDAAmD,CAAA;AAAA,IACjE;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,aAAA,EAAe,GAAA,CAAI,QAAA,CAAS,UAAU,CAAC,CAAA;AAAA,EACrD,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,mCAAmC,KAAK,CAAA;AACtD,IAAA,OAAO,aAAa,CAAC,CAAA;AAAA,EACvB;AACF,CAAA,EAvCmE,WAAA","file":"chunk-AHEBZW37.js","sourcesContent":["import { join } from 'node:path';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { define } from 'gunshi';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { gracefulExit } from 'exit-hook';\nimport { fmt } from '../helpers/pretty-format';\nimport { CliExitError } from '../helpers/exit-error';\nimport { getUserVarlockDir } from '../../lib/user-config-dir';\n\n\nexport const commandSpec = define({\n name: 'telemetry',\n description: 'Enable/disable anonymous usage analytics',\n args: {\n mode: {\n type: 'positional',\n description: '\"enable\" or \"disable\"',\n },\n },\n examples: `\nOpts in/out of anonymous usage analytics. This command creates/updates a configuration\nfile at $XDG_CONFIG_HOME/varlock/config.json (or ~/.config/varlock/config.json) saving\nyour preference.\n\nExamples:\n varlock telemetry disable # Opt out of telemetry\n varlock telemetry enable # Opt in to telemetry\n\n💡 Tip: You can also temporarily opt out by setting VARLOCK_TELEMETRY_DISABLED=1\nFor more information, visit https://varlock.dev/guides/telemetry/\n `.trim(),\n});\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n // TODO: remove this when gunshi supports types/validation for positional args\n if (!['enable', 'disable'].includes(ctx.values.mode)) {\n throw new CliExitError('additional arg must be \"enable\" or \"disable\"', {\n forceExit: true,\n });\n }\n\n const configDir = getUserVarlockDir();\n const configPath = join(configDir, 'config.json');\n\n try {\n // Create .varlock directory if it doesn't exist\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n // Read existing config if it exists\n let config: Record<string, any> = {};\n if (existsSync(configPath)) {\n const configContent = await readFile(configPath, 'utf-8');\n config = JSON.parse(configContent);\n }\n\n // update config `telemetryDisabled` setting\n if (ctx.values.mode === 'disable') config.telemetryDisabled = true;\n else delete config.telemetryDisabled;\n await writeFile(configPath, JSON.stringify(config, null, 2));\n\n if (ctx.values.mode) {\n console.log('✅ Successfully enabled anonymous usage analytics');\n } else {\n console.log('✅ Successfully disabled anonymous usage analytics');\n }\n console.log('> saved in:', fmt.filePath(configPath));\n } catch (error) {\n console.error('Failed to opt out of analytics:', error);\n return gracefulExit(1);\n }\n};\n"]}
@@ -1,8 +1,8 @@
1
1
  import { spawnAsync } from './chunk-Y3ITSQA4.js';
2
- import { detectJsPackageManager, logLines, fmt, installJsDependency } from './chunk-MXZI2FC6.js';
2
+ import { detectJsPackageManager, logLines, fmt, installJsDependency } from './chunk-6SS4YD2I.js';
3
3
  import { define } from './chunk-4A54P4EM.js';
4
- import { gracefulExit, ansis_default } from './chunk-VQ5I7WMP.js';
5
- import { envSpecUpdater, ParsedEnvSpecStaticValue, tryCatch, parseEnvSpecDotEnvFile, pathExists } from './chunk-WZW7QS6M.js';
4
+ import { gracefulExit, ansis_default } from './chunk-NWY5IIPW.js';
5
+ import { envSpecUpdater, ParsedEnvSpecStaticValue, tryCatch, parseEnvSpecDotEnvFile, pathExists } from './chunk-PCRIVT4T.js';
6
6
  import { __commonJS, __toESM, __name } from './chunk-6PEHRAEP.js';
7
7
  import path2, { dirname } from 'path';
8
8
  import fs3 from 'fs/promises';
@@ -1397,7 +1397,7 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
1397
1397
  `We've done our best to get you started, but you must review and make sure it is correct!`,
1398
1398
  "",
1399
1399
  `\u{1F449} Some helpful pointers to get you started:`,
1400
- `- add a description to each item when the name is not self explanitory - it will come through in generated types`,
1400
+ `- add a description to each item when the name is not self explanatory - it will come through in generated types`,
1401
1401
  `- use ${fmt.decorator("@required")} (or ${fmt.decorator("@optional")}) to tag items that should fail validation when empty`,
1402
1402
  `- use ${fmt.decorator("@sensitive")} to tag items that contain sensitive secrets, and must be handled accordingly`,
1403
1403
  `- use ${fmt.decorator("@type")} to set an item's data type (if not a basic string), which affects validation and coercion logic`,
@@ -1504,5 +1504,5 @@ ${bunfigContents}`);
1504
1504
  }, "commandFn");
1505
1505
 
1506
1506
  export { commandFn, commandSpec };
1507
- //# sourceMappingURL=chunk-IG5PPVD7.js.map
1508
- //# sourceMappingURL=chunk-IG5PPVD7.js.map
1507
+ //# sourceMappingURL=chunk-BGPQX6XO.js.map
1508
+ //# sourceMappingURL=chunk-BGPQX6XO.js.map