@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.
- package/CHANGELOG.md +103 -1
- package/README.md +123 -118
- package/dist/aliases.d.ts +11 -5
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +20 -12
- package/dist/aliases.js.map +1 -1
- package/dist/ci-skip.d.ts +32 -15
- package/dist/ci-skip.d.ts.map +1 -1
- package/dist/ci-skip.js +48 -39
- package/dist/ci-skip.js.map +1 -1
- package/dist/commands/export-gha.d.ts +16 -0
- package/dist/commands/export-gha.d.ts.map +1 -1
- package/dist/commands/export-gha.js +52 -43
- package/dist/commands/export-gha.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +17 -25
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/paths.d.ts.map +1 -1
- package/dist/commands/paths.js +15 -14
- package/dist/commands/paths.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +12 -9
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +10 -7
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +3 -13
- package/dist/commands/validate.js.map +1 -1
- package/dist/config.d.ts +4 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/github-env.js +1 -1
- package/dist/github-env.js.map +1 -1
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +2 -2
- package/dist/include.d.ts +6 -43
- package/dist/include.d.ts.map +1 -1
- package/dist/include.js +11 -67
- package/dist/include.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +59 -35
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +95 -86
- package/dist/manifest.js.map +1 -1
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +11 -16
- package/dist/pull.js.map +1 -1
- package/dist/registry.d.ts +28 -5
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +38 -13
- package/dist/registry.js.map +1 -1
- package/dist/tree.d.ts +49 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +190 -0
- package/dist/tree.js.map +1 -0
- package/package.json +5 -2
- package/schema/secrets.schema.json +49 -43
package/dist/manifest.js
CHANGED
|
@@ -1,39 +1,27 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
|
22
|
-
// so the vault never transmits the rest — wire-level least
|
|
23
|
-
//
|
|
24
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
90
|
-
* `
|
|
91
|
-
*
|
|
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
|
|
122
|
+
export function resolveCompiledFolders(manifest, profile) {
|
|
94
123
|
if (profile) {
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
|
|
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.
|
|
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
|
|
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
|
}
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/pull.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"
|
|
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 {
|
|
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 {
|
|
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
|
|
38
|
+
const folders = resolveCompiledFolders(manifest.config, profile);
|
|
41
39
|
const fetchMode = resolveFetchMode(manifest.config, profile);
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
//
|
|
48
|
-
//
|
|
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: ${
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
import type { ResolvedConfig } from "./config.js";
|
|
2
|
-
import { type SecretsManifest } from "./manifest.js";
|
|
3
|
-
|
|
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
|
-
*
|
|
10
|
-
* `config.discovery` — no repo-specific directory constants.
|
|
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
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { hasManifestFile, loadManifestFromDir, } from "./manifest.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* `config.discovery` — no repo-specific directory constants.
|
|
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
|
|
14
|
+
export function discoverPackages(config) {
|
|
10
15
|
const { repoRoot } = config;
|
|
11
16
|
const byDir = new Map();
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
if (!existsSync(manifestPath))
|
|
17
|
+
const consider = (dir, id) => {
|
|
18
|
+
if (!hasManifestFile(dir))
|
|
15
19
|
return;
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,
|
|
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"}
|