@hubble-ventures/infisicml 1.2.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +103 -1
  2. package/README.md +123 -118
  3. package/dist/aliases.d.ts +11 -5
  4. package/dist/aliases.d.ts.map +1 -1
  5. package/dist/aliases.js +20 -12
  6. package/dist/aliases.js.map +1 -1
  7. package/dist/ci-skip.d.ts +32 -15
  8. package/dist/ci-skip.d.ts.map +1 -1
  9. package/dist/ci-skip.js +48 -39
  10. package/dist/ci-skip.js.map +1 -1
  11. package/dist/commands/export-gha.d.ts +16 -0
  12. package/dist/commands/export-gha.d.ts.map +1 -1
  13. package/dist/commands/export-gha.js +52 -43
  14. package/dist/commands/export-gha.js.map +1 -1
  15. package/dist/commands/list.d.ts.map +1 -1
  16. package/dist/commands/list.js +17 -25
  17. package/dist/commands/list.js.map +1 -1
  18. package/dist/commands/paths.d.ts.map +1 -1
  19. package/dist/commands/paths.js +15 -14
  20. package/dist/commands/paths.js.map +1 -1
  21. package/dist/commands/pull.d.ts.map +1 -1
  22. package/dist/commands/pull.js +12 -9
  23. package/dist/commands/pull.js.map +1 -1
  24. package/dist/commands/run.d.ts.map +1 -1
  25. package/dist/commands/run.js +10 -7
  26. package/dist/commands/run.js.map +1 -1
  27. package/dist/commands/validate.d.ts.map +1 -1
  28. package/dist/commands/validate.js +3 -13
  29. package/dist/commands/validate.js.map +1 -1
  30. package/dist/config.d.ts +4 -3
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js.map +1 -1
  33. package/dist/github-env.js +1 -1
  34. package/dist/github-env.js.map +1 -1
  35. package/dist/hooks.d.ts +2 -2
  36. package/dist/hooks.js +2 -2
  37. package/dist/include.d.ts +6 -43
  38. package/dist/include.d.ts.map +1 -1
  39. package/dist/include.js +11 -67
  40. package/dist/include.js.map +1 -1
  41. package/dist/index.d.ts +5 -4
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +5 -4
  44. package/dist/index.js.map +1 -1
  45. package/dist/manifest.d.ts +59 -35
  46. package/dist/manifest.d.ts.map +1 -1
  47. package/dist/manifest.js +95 -86
  48. package/dist/manifest.js.map +1 -1
  49. package/dist/pull.d.ts.map +1 -1
  50. package/dist/pull.js +11 -16
  51. package/dist/pull.js.map +1 -1
  52. package/dist/registry.d.ts +28 -5
  53. package/dist/registry.d.ts.map +1 -1
  54. package/dist/registry.js +38 -13
  55. package/dist/registry.js.map +1 -1
  56. package/dist/tree.d.ts +49 -0
  57. package/dist/tree.d.ts.map +1 -0
  58. package/dist/tree.js +190 -0
  59. package/dist/tree.js.map +1 -0
  60. package/package.json +5 -2
  61. package/schema/secrets.schema.json +49 -43
package/dist/manifest.js CHANGED
@@ -1,39 +1,27 @@
1
- import { resolve, sep } from "node:path";
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join, resolve, sep } from "node:path";
3
+ import { parse as parseYaml } from "yaml";
2
4
  import { z } from "zod";
3
- const pathPattern = /^[a-z0-9_/-]+$/;
4
- const pathsSchema = z
5
- .array(z.string().regex(pathPattern))
6
- .min(1, "paths must be a non-empty array");
7
- const envVarNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
8
- const aliasSourceSchema = z
9
- .string()
10
- .regex(envVarNamePattern, "alias source must be a valid env var name");
11
- const aliasTargetSchema = z
12
- .string()
13
- .regex(envVarNamePattern, "alias target must be a valid env var name");
14
- // Key-level allowlist. When present, only these env var names are emitted from
15
- // whatever the folders yielded (after aliases). `.min(1)` because an empty
16
- // allowlist is almost certainly a mistake — omit the field to emit every key.
17
- const includeSchema = z
18
- .array(z.string().regex(envVarNamePattern, "include entry must be a valid env var name"))
19
- .min(1, "include must be a non-empty array");
5
+ import { compileTree, treeSchema, } from "./tree.js";
20
6
  // How secrets are read from the vault. `folder` (default) fetches whole folders
21
- // and filters locally. `keys` fetches only the exact keys `include` resolves to,
22
- // so the vault never transmits the rest — wire-level least privilege. `keys`
23
- // requires an `include` allowlist (enforced by resolveFetchKeys / validate,
24
- // since the requirement depends on the resolved profile).
7
+ // and selects the declared keys locally. `keys` fetches only the exact keys the
8
+ // tree declares, so the vault never transmits the rest — wire-level least
9
+ // privilege. Because the tree always names every key, `keys` needs no separate
10
+ // allowlist (unlike v1, where it required `include`).
25
11
  const fetchModeSchema = z.enum(["folder", "keys"]);
26
12
  export const secretsManifestSchema = z.object({
27
13
  $schema: z.string().optional(),
28
- paths: pathsSchema,
14
+ // The folder tree: an array of `{ folder: [ ...contents ] }` objects naming
15
+ // which Infisical folders to pull and, per folder, exactly which keys to emit
16
+ // (bare strings) and how to alias them (`{ SOURCE: "TARGET" }`). Subfolders
17
+ // nest as `{ name: [ ... ] }`. See tree.ts for the entry grammar.
18
+ secrets: treeSchema,
29
19
  profiles: z
30
20
  .record(z.string(), z.object({
31
- paths: pathsSchema,
32
- // Replaces the root `include` for this profile when set; if omitted,
33
- // the root `include` applies (same replace-not-merge as `paths`).
34
- include: includeSchema.optional(),
35
- // Overrides the root `fetch` for this profile when set (same
36
- // replace-not-merge as `paths` / `include`).
21
+ // Replaces the root `secrets` for this profile when running with
22
+ // --profile (same replace-not-merge as v1 `paths`).
23
+ secrets: treeSchema,
24
+ // Overrides the root `fetch` for this profile when set.
37
25
  fetch: fetchModeSchema.optional(),
38
26
  }))
39
27
  .optional(),
@@ -47,23 +35,9 @@ export const secretsManifestSchema = z.object({
47
35
  .string()
48
36
  .regex(/^[^/\\]+$/)
49
37
  .optional(),
50
- // Map a pulled secret to the extra env var name(s) a build/runtime expects.
51
- // The vault names a secret once (e.g. /clerk exposes the publishable key as
52
- // CLERK_PUBLISHABLE_KEY), but build tools inline it by a tool-specific,
53
- // convention-prefixed name — Vite reads VITE_*, Next reads NEXT_PUBLIC_*.
54
- // Declaring the mapping here means every consumer (CI export-gha, local pull)
55
- // emits the right name instead of each workflow re-deriving it.
56
- aliases: z
57
- .record(aliasSourceSchema, z.union([aliasTargetSchema, z.array(aliasTargetSchema).min(1)]))
58
- .optional(),
59
- // Emit only these keys from whatever the folders yielded (default-deny key
60
- // selection). Applied after `aliases`, to the final set of names — so a client
61
- // can pull a shared vendor folder but emit only its public key. Absent = emit
62
- // all (backward compatible). A per-profile `include` replaces this one.
63
- include: includeSchema.optional(),
64
- // Read strategy: `folder` (default) pulls whole folders and filters locally;
65
- // `keys` pulls only the keys `include` resolves to (least privilege at the
66
- // wire). A per-profile `fetch` replaces this one.
38
+ // Read strategy: `folder` (default) pulls whole folders and selects the
39
+ // declared keys locally; `keys` pulls only the declared keys (least privilege
40
+ // at the wire). A per-profile `fetch` replaces this one.
67
41
  fetch: fetchModeSchema.optional(),
68
42
  environments: z
69
43
  .record(z.string(), z.object({
@@ -74,34 +48,91 @@ export const secretsManifestSchema = z.object({
74
48
  export function loadManifestJson(raw) {
75
49
  return secretsManifestSchema.parse(raw);
76
50
  }
77
- /** Profile paths replace default paths when a profile is set. */
78
- export function resolvePaths(manifest, profile) {
79
- if (profile) {
80
- const profileConfig = manifest.profiles?.[profile];
81
- if (!profileConfig) {
82
- throw new Error(`Unknown profile '${profile}' in secrets.json`);
83
- }
84
- return profileConfig.paths;
51
+ // Manifest filenames in preference order. YAML is the primary, recommended
52
+ // format; JSON stays fully supported for anyone who prefers it (or generates
53
+ // manifests programmatically). The first file that exists in a package
54
+ // directory wins, so `secrets.yaml` shadows a stray `secrets.json`.
55
+ export const MANIFEST_FILENAMES = [
56
+ "secrets.yaml",
57
+ "secrets.yml",
58
+ "secrets.json",
59
+ ];
60
+ /** A generic name for the manifest, for messages that shouldn't hardcode an extension. */
61
+ export const MANIFEST_LABEL = "secrets manifest";
62
+ /**
63
+ * Locate the manifest file in `dir`, preferring YAML over JSON
64
+ * ({@link MANIFEST_FILENAMES}). Returns `null` when no manifest exists.
65
+ *
66
+ * A directory with more than one manifest file is a hard error: picking a winner
67
+ * by preference order would let a stale or experimental `secrets.yaml` left next
68
+ * to the intended `secrets.json` (or vice versa) silently change which secret
69
+ * tree is pulled — and non-interactive lanes (the GitHub Action's `export-gha`)
70
+ * would write it into `GITHUB_ENV` and still succeed. Refuse instead of guessing;
71
+ * the operator removes the extra file to resolve.
72
+ */
73
+ /**
74
+ * Cheap presence check: does `dir` hold at least one manifest file? Used to
75
+ * enumerate package directories without parsing or resolving ambiguity, so
76
+ * discovery never throws on a manifest a command won't actually load.
77
+ */
78
+ export function hasManifestFile(dir) {
79
+ return MANIFEST_FILENAMES.some((name) => existsSync(join(dir, name)));
80
+ }
81
+ export function findManifestFile(dir) {
82
+ const present = MANIFEST_FILENAMES.filter((name) => existsSync(join(dir, name)));
83
+ if (present.length === 0)
84
+ return null;
85
+ if (present.length > 1) {
86
+ throw new Error(`Ambiguous secrets manifest in ${dir}: found ${present.join(", ")}. ` +
87
+ `Keep exactly one — remove the extra file(s) so it's unambiguous which secret tree is used.`);
85
88
  }
86
- return manifest.paths;
89
+ const [filename] = present;
90
+ return {
91
+ path: join(dir, filename),
92
+ filename,
93
+ format: filename.endsWith(".json") ? "json" : "yaml",
94
+ };
95
+ }
96
+ /**
97
+ * Parse a manifest file's contents into the raw object, dispatching on format.
98
+ * YAML is a superset of JSON, but we parse each with its own reader so error
99
+ * messages point at the right syntax. Does not validate against the schema —
100
+ * call {@link loadManifestJson} for that.
101
+ */
102
+ export function parseManifestFile(file) {
103
+ const raw = readFileSync(file.path, "utf8");
104
+ return file.format === "yaml" ? parseYaml(raw) : JSON.parse(raw);
105
+ }
106
+ /**
107
+ * Find, read, parse, and schema-validate the manifest in `dir`. Returns the
108
+ * validated manifest plus the file it came from, or `null` when no manifest
109
+ * file exists.
110
+ */
111
+ export function loadManifestFromDir(dir) {
112
+ const file = findManifestFile(dir);
113
+ if (!file)
114
+ return null;
115
+ return { manifest: loadManifestJson(parseManifestFile(file)), file };
87
116
  }
88
117
  /**
89
- * Resolve the effective key allowlist. A profile's `include` replaces the root
90
- * `include` when the profile defines it; otherwise the root `include` applies.
91
- * Returns `undefined` when no allowlist is in effect (emit all keys).
118
+ * Compile the effective folder tree into an ordered {@link CompiledFolder} list.
119
+ * A profile's `tree` replaces the root `tree` when a profile is set (same
120
+ * replace-not-merge as v1 `paths`). Throws on an unknown profile name.
92
121
  */
93
- export function resolveInclude(manifest, profile) {
122
+ export function resolveCompiledFolders(manifest, profile) {
94
123
  if (profile) {
95
- const profileInclude = manifest.profiles?.[profile]?.include;
96
- if (profileInclude !== undefined)
97
- return profileInclude;
124
+ const profileConfig = manifest.profiles?.[profile];
125
+ if (!profileConfig) {
126
+ throw new Error(`Unknown profile '${profile}' in ${MANIFEST_LABEL}`);
127
+ }
128
+ return compileTree(profileConfig.secrets);
98
129
  }
99
- return manifest.include;
130
+ return compileTree(manifest.secrets);
100
131
  }
101
132
  /**
102
133
  * Resolve the effective fetch mode. A profile's `fetch` replaces the root
103
134
  * `fetch` when the profile defines it; otherwise the root `fetch` applies.
104
- * Defaults to `"folder"` (whole-folder read + local filter) when unset.
135
+ * Defaults to `"folder"` (whole-folder read + local select) when unset.
105
136
  */
106
137
  export function resolveFetchMode(manifest, profile) {
107
138
  if (profile) {
@@ -111,28 +142,6 @@ export function resolveFetchMode(manifest, profile) {
111
142
  }
112
143
  return manifest.fetch ?? "folder";
113
144
  }
114
- /**
115
- * Cross-field rule: `fetch: "keys"` requires an `include` allowlist, because
116
- * key mode fetches exactly the keys `include` names. The check spans the root
117
- * and every profile (a profile's `fetch`/`include` each replace the root's), so
118
- * every runnable combination is covered. Returns human-readable issue strings
119
- * (empty when consistent) for `validate` to surface. Zod can't express this —
120
- * the requirement depends on the resolved profile.
121
- */
122
- export function checkFetchIncludeConsistency(manifest) {
123
- const issues = [];
124
- const check = (profile, label) => {
125
- if (resolveFetchMode(manifest, profile) === "keys" &&
126
- resolveInclude(manifest, profile) === undefined) {
127
- issues.push(`fetch: "keys" requires an include allowlist (${label})`);
128
- }
129
- };
130
- check(undefined, "root");
131
- for (const name of Object.keys(manifest.profiles ?? {})) {
132
- check(name, `profile "${name}"`);
133
- }
134
- return issues;
135
- }
136
145
  export function normalizeFolderPath(folder) {
137
146
  return `/${folder.replace(/^\/+/, "")}`;
138
147
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;AAEF,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,EAAE,GACb,IAAI,CAgBN;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAkErB"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;AAEF,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,EAAE,GACb,IAAI,CAgBN;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAgErB"}
package/dist/pull.js CHANGED
@@ -1,10 +1,8 @@
1
1
  import { existsSync, writeFileSync } from "node:fs";
2
2
  import { relative } from "node:path";
3
- import { applyAliases } from "./aliases.js";
4
- import { fetchManifestSecrets, keysForCiStub, shouldSkipInfisicalPull, } from "./ci-skip.js";
3
+ import { fetchCompiledFolders, keysForCiStub, materializeSecrets, shouldSkipInfisicalPull, } from "./ci-skip.js";
5
4
  import { serializeDotenv } from "./dotenv.js";
6
- import { selectEmittedSecrets } from "./include.js";
7
- import { normalizeFolderPath, resolveFetchMode, resolveInclude, resolvePaths, resolveSecretsOutputPath, } from "./manifest.js";
5
+ import { normalizeFolderPath, resolveCompiledFolders, resolveFetchMode, resolveSecretsOutputPath, } from "./manifest.js";
8
6
  import { resolveOptionalKeys } from "./optional-keys.js";
9
7
  export function writeInjectedSecretsStub(outputPath, manifest, keys) {
10
8
  const fromEnv = {};
@@ -37,25 +35,22 @@ export async function pullManifest(options) {
37
35
  console.log(`⏭️ ${manifest.id}: skipped Infisical pull (injected env → ${rel})`);
38
36
  return "skipped";
39
37
  }
40
- const paths = resolvePaths(manifest.config, profile);
38
+ const folders = resolveCompiledFolders(manifest.config, profile);
41
39
  const fetchMode = resolveFetchMode(manifest.config, profile);
42
- const aliased = applyAliases(await fetchManifestSecrets(provider, envName, paths, manifest.config, profile), manifest.config);
43
- // Default-deny key selection: emit only the allowlisted keys when `include`
44
- // is set (after aliases). Absent = emit all.
45
- const include = resolveInclude(manifest.config, profile);
46
- const merged = selectEmittedSecrets(aliased, include, resolveOptionalKeys(manifest.config, envName));
47
- // filter(Boolean) drops the optional Profile/Include lines when absent. It
48
- // would also drop a trailing "" sentinel, so append the trailing newline
49
- // explicitly — otherwise the first secret gets glued onto the "# Generated"
50
- // line.
40
+ // Per-folder fetch per-folder alias + missing-key enforcement → merge, so a
41
+ // key declared in two folders keeps each folder's value/provenance.
42
+ const folderSecrets = await fetchCompiledFolders(provider, envName, folders, fetchMode);
43
+ const merged = materializeSecrets(folderSecrets, resolveOptionalKeys(manifest.config, envName));
44
+ // filter(Boolean) drops the optional Profile line when absent. It would also
45
+ // drop a trailing "" sentinel, so append the trailing newline explicitly —
46
+ // otherwise the first secret gets glued onto the "# Generated" line.
51
47
  const header = `${[
52
48
  "# Pulled from Infisical — do not edit. Refresh: infisicml pull",
53
49
  `# Package: ${manifest.id}`,
54
50
  `# Environment: ${envName}`,
55
51
  profile ? `# Profile: ${profile}` : "",
56
- `# Paths: ${paths.map((p) => normalizeFolderPath(p)).join(", ")}`,
52
+ `# Paths: ${folders.map((f) => normalizeFolderPath(f.path)).join(", ")}`,
57
53
  fetchMode === "keys" ? "# Fetch: keys (per-key least-privilege read)" : "",
58
- include ? `# Include: ${include.join(", ")}` : "",
59
54
  `# Generated: ${new Date().toISOString()}`,
60
55
  ]
61
56
  .filter(Boolean)
package/dist/pull.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,37 @@
1
1
  import type { ResolvedConfig } from "./config.js";
2
- import { type SecretsManifest } from "./manifest.js";
3
- export type PackageManifest = {
2
+ import { type ManifestFile, type SecretsManifest } from "./manifest.js";
3
+ /** A discovered package: its id and directory, before its manifest is loaded. */
4
+ export type PackageRef = {
4
5
  id: string;
5
6
  dir: string;
7
+ };
8
+ export type PackageManifest = PackageRef & {
6
9
  config: SecretsManifest;
10
+ /** The manifest file this package was loaded from (YAML or JSON). */
11
+ file: ManifestFile;
7
12
  };
8
13
  /**
9
- * Discover every `secrets.json` in the repo, driven entirely by
10
- * `config.discovery` — no repo-specific directory constants. Explicit
11
- * `packages` win over `roots`-discovered entries at the same directory.
14
+ * Enumerate every package directory that holds a secrets manifest, driven
15
+ * entirely by `config.discovery` — no repo-specific directory constants.
16
+ * Explicit `packages` win over `roots`-discovered entries at the same directory.
17
+ *
18
+ * This is a cheap presence scan: it does NOT parse, validate, or resolve
19
+ * manifest ambiguity, so a stale or malformed manifest in one package never
20
+ * blocks discovery of the others. Resolution happens in {@link loadPackage},
21
+ * per package, only for the packages a command actually uses.
22
+ */
23
+ export declare function discoverPackages(config: ResolvedConfig): PackageRef[];
24
+ /**
25
+ * Resolve, parse, and schema-validate one package's manifest. Throws if the
26
+ * directory is ambiguous (more than one manifest file) or the manifest is
27
+ * invalid — scoped to this package, so an unrelated broken sibling never blocks
28
+ * a command that doesn't load it.
29
+ */
30
+ export declare function loadPackage(ref: PackageRef): PackageManifest;
31
+ /**
32
+ * Discover and load every package's manifest. Loads all — to load only a
33
+ * targeted subset (so an unrelated ambiguous/broken package can't abort the
34
+ * run), use {@link discoverPackages} + {@link loadPackage} instead.
12
35
  */
13
36
  export declare function discoverManifests(config: ResolvedConfig): PackageManifest[];
14
37
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,EAAE,CA4B3E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,iFAAiF;AACjF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,MAAM,EAAE,eAAe,CAAC;IACxB,qEAAqE;IACrE,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,EAAE,CAwBrE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,eAAe,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,EAAE,CAE3E"}
package/dist/registry.js CHANGED
@@ -1,20 +1,23 @@
1
- import { existsSync, readdirSync, readFileSync } from "node:fs";
1
+ import { existsSync, readdirSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { loadManifestJson } from "./manifest.js";
3
+ import { hasManifestFile, loadManifestFromDir, } from "./manifest.js";
4
4
  /**
5
- * Discover every `secrets.json` in the repo, driven entirely by
6
- * `config.discovery` — no repo-specific directory constants. Explicit
7
- * `packages` win over `roots`-discovered entries at the same directory.
5
+ * Enumerate every package directory that holds a secrets manifest, driven
6
+ * entirely by `config.discovery` — no repo-specific directory constants.
7
+ * Explicit `packages` win over `roots`-discovered entries at the same directory.
8
+ *
9
+ * This is a cheap presence scan: it does NOT parse, validate, or resolve
10
+ * manifest ambiguity, so a stale or malformed manifest in one package never
11
+ * blocks discovery of the others. Resolution happens in {@link loadPackage},
12
+ * per package, only for the packages a command actually uses.
8
13
  */
9
- export function discoverManifests(config) {
14
+ export function discoverPackages(config) {
10
15
  const { repoRoot } = config;
11
16
  const byDir = new Map();
12
- const scanDir = (dir, id) => {
13
- const manifestPath = join(dir, "secrets.json");
14
- if (!existsSync(manifestPath))
17
+ const consider = (dir, id) => {
18
+ if (!hasManifestFile(dir))
15
19
  return;
16
- const parsed = loadManifestJson(JSON.parse(readFileSync(manifestPath, "utf8")));
17
- byDir.set(resolve(dir), { dir, id, config: parsed });
20
+ byDir.set(resolve(dir), { id, dir });
18
21
  };
19
22
  for (const root of config.discovery.roots ?? []) {
20
23
  const rootAbs = join(repoRoot, root);
@@ -23,13 +26,35 @@ export function discoverManifests(config) {
23
26
  for (const entry of readdirSync(rootAbs, { withFileTypes: true })) {
24
27
  if (!entry.isDirectory())
25
28
  continue;
26
- scanDir(join(rootAbs, entry.name), entry.name);
29
+ consider(join(rootAbs, entry.name), entry.name);
27
30
  }
28
31
  }
29
32
  // Explicit packages last so a custom id/dir overrides a roots-discovered one.
30
33
  for (const { id, dir } of config.discovery.packages ?? []) {
31
- scanDir(join(repoRoot, dir), id);
34
+ consider(join(repoRoot, dir), id);
32
35
  }
33
36
  return [...byDir.values()].sort((a, b) => a.id.localeCompare(b.id));
34
37
  }
38
+ /**
39
+ * Resolve, parse, and schema-validate one package's manifest. Throws if the
40
+ * directory is ambiguous (more than one manifest file) or the manifest is
41
+ * invalid — scoped to this package, so an unrelated broken sibling never blocks
42
+ * a command that doesn't load it.
43
+ */
44
+ export function loadPackage(ref) {
45
+ const loaded = loadManifestFromDir(ref.dir);
46
+ if (!loaded) {
47
+ // hasManifestFile was true at discovery; the file vanished in between.
48
+ throw new Error(`No secrets manifest in ${ref.dir}`);
49
+ }
50
+ return { id: ref.id, dir: ref.dir, config: loaded.manifest, file: loaded.file };
51
+ }
52
+ /**
53
+ * Discover and load every package's manifest. Loads all — to load only a
54
+ * targeted subset (so an unrelated ambiguous/broken package can't abort the
55
+ * run), use {@link discoverPackages} + {@link loadPackage} instead.
56
+ */
57
+ export function discoverManifests(config) {
58
+ return discoverPackages(config).map(loadPackage);
59
+ }
35
60
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAwB,MAAM,eAAe,CAAC;AAQvE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEjD,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAU,EAAE,EAAE;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO;QACtC,MAAM,MAAM,GAAG,gBAAgB,CAC7B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAC/C,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QACnC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YACnC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EACL,eAAe,EACf,mBAAmB,GAGpB,MAAM,eAAe,CAAC;AAcvB;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE5C,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAU,EAAE,EAAE;QAC3C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC;YAAE,OAAO;QAClC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QACnC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YACnC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QAC1D,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAe;IACzC,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,uEAAuE;QACvE,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AAClF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC"}
package/dist/tree.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * One entry in a folder's contents array. Either:
4
+ * - a **string** — a plain key emitted as-is, or
5
+ * - an **object** whose entries are, per key, discriminated by value type:
6
+ * - `SOURCE: "TARGET"` (string value) — an alias (the canonical vault key
7
+ * `SOURCE` is emitted and copied to `TARGET`). Multiple targets? Repeat the
8
+ * entry, one target each.
9
+ * - `name: [ ... ]` (array value) — a subfolder (its own contents array).
10
+ */
11
+ export type FolderEntry = string | {
12
+ [key: string]: string | FolderArray;
13
+ };
14
+ /** A folder's contents: a non-empty array of {@link FolderEntry}. */
15
+ export type FolderArray = FolderEntry[];
16
+ /**
17
+ * The manifest's `secrets`: a non-empty array of single-folder objects
18
+ * (`{ folderName: contentsArray }`) — the top level of the tree.
19
+ */
20
+ export type SecretsTree = Array<{
21
+ [folder: string]: FolderArray;
22
+ }>;
23
+ /** A single emitted key resolved from a folder (canonical name + aliases). */
24
+ export type CompiledKey = {
25
+ key: string;
26
+ aliases: string[];
27
+ };
28
+ /** A folder path plus the exact keys to emit from it (provenance-aware). */
29
+ export type CompiledFolder = {
30
+ path: string;
31
+ keys: CompiledKey[];
32
+ };
33
+ /**
34
+ * Schema for the manifest's `secrets`: a non-empty array of folder objects, each
35
+ * validated recursively. Cast to the precise {@link SecretsTree} type — the base
36
+ * `z.array` infers `unknown[]`, but every element is structurally a folder
37
+ * object once {@link validateFolderObject} passes.
38
+ */
39
+ export declare const treeSchema: z.ZodType<SecretsTree>;
40
+ /**
41
+ * Flatten a validated tree into an ordered list of {@link CompiledFolder}.
42
+ * String entries carry no aliases; each `SOURCE: "TARGET"` entry carries its
43
+ * single target (repeat the entry for several targets). A folder's own keys are
44
+ * emitted before recursing into its subfolders, so declaration order is
45
+ * preserved (last folder wins on a genuine cross-folder name collision at merge
46
+ * time).
47
+ */
48
+ export declare function compileTree(secrets: SecretsTree): CompiledFolder[];
49
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAA;CAAE,CAAC;AAE3E,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG,WAAW,EAAE,CAAC;AAExC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,CAAC,CAAC;AAEnE,8EAA8E;AAC9E,MAAM,MAAM,WAAW,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE7D,4EAA4E;AAC5E,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAkJnE;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAUJ,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AAE1C;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,EAAE,CAQlE"}