@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/tree.js ADDED
@@ -0,0 +1,190 @@
1
+ import { z } from "zod";
2
+ // A folder name (a top-level folder or a subfolder segment). Lowercase, digits,
3
+ // `_ - /`.
4
+ const folderNamePattern = /^[a-z0-9_/-]+$/;
5
+ const envVarNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
6
+ const envVarNameSchema = z
7
+ .string()
8
+ .regex(envVarNamePattern, "must be a valid env var name");
9
+ function pushIssues(ctx, result, at) {
10
+ if (result.success)
11
+ return;
12
+ for (const issue of result.error.issues) {
13
+ ctx.addIssue({ ...issue, path: [...at, ...issue.path] });
14
+ }
15
+ }
16
+ /**
17
+ * Validate a top-level entry: a folder object `{ name: [ ...contents ] }`. A
18
+ * folder's value must be an array — a string value at the top level would be an
19
+ * alias with no folder to live in, which is meaningless.
20
+ */
21
+ function validateFolderObject(entry, ctx, path) {
22
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
23
+ ctx.addIssue({
24
+ code: z.ZodIssueCode.custom,
25
+ path,
26
+ message: 'top-level entries must be folders: { "name": [ ... ] }',
27
+ });
28
+ return;
29
+ }
30
+ const names = Object.keys(entry);
31
+ if (names.length === 0) {
32
+ ctx.addIssue({
33
+ code: z.ZodIssueCode.custom,
34
+ path,
35
+ message: "folder object must name a folder",
36
+ });
37
+ }
38
+ for (const [name, value] of Object.entries(entry)) {
39
+ const at = [...path, name];
40
+ if (!folderNamePattern.test(name)) {
41
+ ctx.addIssue({
42
+ code: z.ZodIssueCode.custom,
43
+ path: at,
44
+ message: "folder name has invalid characters",
45
+ });
46
+ }
47
+ if (!Array.isArray(value)) {
48
+ ctx.addIssue({
49
+ code: z.ZodIssueCode.custom,
50
+ path: at,
51
+ message: "a folder's value must be an array of its contents",
52
+ });
53
+ continue;
54
+ }
55
+ validateFolderArray(value, ctx, at);
56
+ }
57
+ }
58
+ /**
59
+ * Recursively validate a folder's contents array. Zod's recursive inference is
60
+ * awkward for the mixed string / alias / subfolder shape, so structure and
61
+ * recursion are validated by hand here, giving precise, path-anchored messages.
62
+ * Value type discriminates an object entry: a **string** value is an alias
63
+ * target, an **array** value is a subfolder.
64
+ */
65
+ function validateFolderArray(value, ctx, path) {
66
+ if (!Array.isArray(value)) {
67
+ ctx.addIssue({
68
+ code: z.ZodIssueCode.custom,
69
+ path,
70
+ message: "folder contents must be an array",
71
+ });
72
+ return;
73
+ }
74
+ if (value.length === 0) {
75
+ ctx.addIssue({
76
+ code: z.ZodIssueCode.custom,
77
+ path,
78
+ message: "folder contents must be a non-empty array of keys, aliases, or subfolders",
79
+ });
80
+ }
81
+ value.forEach((entry, i) => validateFolderEntry(entry, ctx, [...path, i]));
82
+ }
83
+ function validateFolderEntry(entry, ctx, path) {
84
+ if (typeof entry === "string") {
85
+ pushIssues(ctx, envVarNameSchema.safeParse(entry), path);
86
+ return;
87
+ }
88
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
89
+ ctx.addIssue({
90
+ code: z.ZodIssueCode.custom,
91
+ path,
92
+ message: "folder entry must be a key name (string), an alias, or a subfolder",
93
+ });
94
+ return;
95
+ }
96
+ const keys = Object.keys(entry);
97
+ if (keys.length === 0) {
98
+ ctx.addIssue({
99
+ code: z.ZodIssueCode.custom,
100
+ path,
101
+ message: "object entry must declare at least one alias or subfolder",
102
+ });
103
+ }
104
+ for (const [key, value] of Object.entries(entry)) {
105
+ const at = [...path, key];
106
+ if (Array.isArray(value)) {
107
+ // Subfolder: the value is its own contents array.
108
+ if (!folderNamePattern.test(key)) {
109
+ ctx.addIssue({
110
+ code: z.ZodIssueCode.custom,
111
+ path: at,
112
+ message: "subfolder name has invalid characters",
113
+ });
114
+ }
115
+ validateFolderArray(value, ctx, at);
116
+ }
117
+ else if (typeof value === "string") {
118
+ // Alias: SOURCE (the entry key) -> TARGET (the value).
119
+ pushIssues(ctx, envVarNameSchema.safeParse(key), at);
120
+ pushIssues(ctx, envVarNameSchema.safeParse(value), at);
121
+ }
122
+ else {
123
+ ctx.addIssue({
124
+ code: z.ZodIssueCode.custom,
125
+ path: at,
126
+ message: "entry value must be a string (alias target) or an array (subfolder)",
127
+ });
128
+ }
129
+ }
130
+ }
131
+ /**
132
+ * Schema for the manifest's `secrets`: a non-empty array of folder objects, each
133
+ * validated recursively. Cast to the precise {@link SecretsTree} type — the base
134
+ * `z.array` infers `unknown[]`, but every element is structurally a folder
135
+ * object once {@link validateFolderObject} passes.
136
+ */
137
+ export const treeSchema = z
138
+ .array(z.unknown())
139
+ .superRefine((secrets, ctx) => {
140
+ if (secrets.length === 0) {
141
+ ctx.addIssue({
142
+ code: z.ZodIssueCode.custom,
143
+ message: "secrets must declare at least one folder",
144
+ });
145
+ }
146
+ secrets.forEach((entry, i) => validateFolderObject(entry, ctx, [i]));
147
+ });
148
+ /**
149
+ * Flatten a validated tree into an ordered list of {@link CompiledFolder}.
150
+ * String entries carry no aliases; each `SOURCE: "TARGET"` entry carries its
151
+ * single target (repeat the entry for several targets). A folder's own keys are
152
+ * emitted before recursing into its subfolders, so declaration order is
153
+ * preserved (last folder wins on a genuine cross-folder name collision at merge
154
+ * time).
155
+ */
156
+ export function compileTree(secrets) {
157
+ const out = [];
158
+ for (const folder of secrets) {
159
+ for (const [name, contents] of Object.entries(folder)) {
160
+ if (Array.isArray(contents))
161
+ walk(name, contents, out);
162
+ }
163
+ }
164
+ return out;
165
+ }
166
+ function walk(path, contents, out) {
167
+ const keys = [];
168
+ const subfolders = [];
169
+ for (const entry of contents) {
170
+ if (typeof entry === "string") {
171
+ keys.push({ key: entry, aliases: [] });
172
+ continue;
173
+ }
174
+ for (const [key, value] of Object.entries(entry)) {
175
+ if (Array.isArray(value)) {
176
+ subfolders.push([`${path}/${key}`, value]);
177
+ }
178
+ else {
179
+ keys.push({ key, aliases: [value] });
180
+ }
181
+ }
182
+ }
183
+ if (keys.length > 0) {
184
+ out.push({ path, keys });
185
+ }
186
+ for (const [subPath, subContents] of subfolders) {
187
+ walk(subPath, subContents, out);
188
+ }
189
+ }
190
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubble-ventures/infisicml",
3
- "version": "1.2.1",
3
+ "version": "2.1.0",
4
4
  "description": "Infisical Secret Orchestration — federated per-package secret manifests for monorepos, unified across local dev and CI.",
5
5
  "keywords": [
6
6
  "infisical",
@@ -53,9 +53,12 @@
53
53
  "test": "vitest run",
54
54
  "test:watch": "vitest",
55
55
  "smoke": "npm run build && bash scripts/smoke.sh",
56
- "type-check": "tsc --noEmit"
56
+ "type-check": "tsc --noEmit",
57
+ "release": "npm version --no-git-tag-version",
58
+ "version": "npm run build"
57
59
  },
58
60
  "dependencies": {
61
+ "yaml": "^2.9.0",
59
62
  "zod": "^3.23.8"
60
63
  },
61
64
  "devDependencies": {
@@ -1,44 +1,70 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://cdn.jsdelivr.net/npm/@hubble-ventures/infisicml@1/schema/secrets.schema.json",
3
+ "$id": "https://cdn.jsdelivr.net/npm/@hubble-ventures/infisicml@2/schema/secrets.schema.json",
4
4
  "title": "Infisicml secrets manifest",
5
- "description": "Declares which Infisical vault folders to pull into a gitignored .env.secrets file next to this manifest.",
5
+ "description": "Declares an array of Infisical vault folders and, per folder, exactly which keys to pull into a gitignored .env.secrets file next to this manifest.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
- "required": ["paths"],
9
- "properties": {
10
- "$schema": { "type": "string" },
11
- "paths": {
8
+ "required": ["secrets"],
9
+ "$defs": {
10
+ "envVarName": {
11
+ "type": "string",
12
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
13
+ },
14
+ "folderEntry": {
15
+ "description": "A key name (string), an alias { SOURCE: \"TARGET\" }, or a subfolder { name: [ ... ] }. In an object entry, a string value is an alias target and an array value is a subfolder.",
16
+ "oneOf": [
17
+ { "$ref": "#/$defs/envVarName" },
18
+ {
19
+ "type": "object",
20
+ "minProperties": 1,
21
+ "additionalProperties": {
22
+ "oneOf": [
23
+ { "$ref": "#/$defs/envVarName" },
24
+ { "$ref": "#/$defs/folderArray" }
25
+ ]
26
+ }
27
+ }
28
+ ]
29
+ },
30
+ "folderArray": {
12
31
  "type": "array",
13
32
  "minItems": 1,
14
- "items": { "type": "string", "pattern": "^[a-z0-9_/-]+$" },
15
- "description": "Infisical folder paths (without leading slash), e.g. clerk, vendor/app"
33
+ "description": "A folder's contents: keys, aliases, and subfolders.",
34
+ "items": { "$ref": "#/$defs/folderEntry" }
16
35
  },
36
+ "folderObject": {
37
+ "type": "object",
38
+ "minProperties": 1,
39
+ "description": "A folder: { folderName: [ ...contents ] }.",
40
+ "propertyNames": { "type": "string", "pattern": "^[a-z0-9_/-]+$" },
41
+ "additionalProperties": { "$ref": "#/$defs/folderArray" }
42
+ },
43
+ "secrets": {
44
+ "type": "array",
45
+ "minItems": 1,
46
+ "description": "Top-level array of folder objects.",
47
+ "items": { "$ref": "#/$defs/folderObject" }
48
+ }
49
+ },
50
+ "properties": {
51
+ "$schema": { "type": "string" },
52
+ "secrets": { "$ref": "#/$defs/secrets" },
17
53
  "profiles": {
18
54
  "type": "object",
19
55
  "additionalProperties": {
20
56
  "type": "object",
21
57
  "additionalProperties": false,
22
- "required": ["paths"],
58
+ "required": ["secrets"],
23
59
  "properties": {
24
- "paths": {
25
- "type": "array",
26
- "minItems": 1,
27
- "items": { "type": "string", "pattern": "^[a-z0-9_/-]+$" }
28
- },
29
- "include": {
30
- "type": "array",
31
- "minItems": 1,
32
- "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
33
- "description": "Key allowlist for this profile; replaces the root include when set"
34
- },
60
+ "secrets": { "$ref": "#/$defs/secrets" },
35
61
  "fetch": {
36
62
  "enum": ["folder", "keys"],
37
63
  "description": "Read strategy for this profile; replaces the root fetch when set"
38
64
  }
39
65
  }
40
66
  },
41
- "description": "Named path sets; profile paths replace default paths when --profile is set"
67
+ "description": "Named alternate trees; a profile's secrets replace the root secrets when --profile is set"
42
68
  },
43
69
  "ci": {
44
70
  "type": "object",
@@ -61,30 +87,10 @@
61
87
  "pattern": "^[^/\\\\]+$",
62
88
  "description": "Output filename only (no path separators), relative to this manifest directory"
63
89
  },
64
- "aliases": {
65
- "type": "object",
66
- "description": "Copy a pulled secret to extra env var name(s) a build/runtime expects (e.g. CLERK_PUBLISHABLE_KEY -> VITE_CLERK_PUBLISHABLE_KEY).",
67
- "additionalProperties": {
68
- "oneOf": [
69
- { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
70
- {
71
- "type": "array",
72
- "minItems": 1,
73
- "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }
74
- }
75
- ]
76
- }
77
- },
78
- "include": {
79
- "type": "array",
80
- "minItems": 1,
81
- "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
82
- "description": "Emit only these env var names from whatever the folders yielded (after aliases). Omit to emit all keys. Lets a client pull a shared vendor folder but emit only its public key, keeping server secrets out of client builds and GITHUB_ENV."
83
- },
84
90
  "fetch": {
85
91
  "enum": ["folder", "keys"],
86
92
  "default": "folder",
87
- "description": "Read strategy. 'folder' (default) pulls whole folders and filters locally. 'keys' fetches only the keys 'include' resolves to; in CI the vault transmits nothing else (per-key REST reads), locally the CLI fetches the folder and selects them. Requires 'include'. A per-profile 'fetch' replaces this one."
93
+ "description": "Read strategy. 'folder' (default) pulls whole folders and selects the declared keys locally. 'keys' fetches only the declared keys per folder; in CI the vault transmits nothing else (per-key REST reads). A per-profile 'fetch' replaces this one."
88
94
  },
89
95
  "environments": {
90
96
  "type": "object",
@@ -95,7 +101,7 @@
95
101
  "optionalKeys": {
96
102
  "type": "array",
97
103
  "items": { "type": "string" },
98
- "description": "Keys allowed to be absent in this environment; export-gha logs a notice instead of failing"
104
+ "description": "Declared keys allowed to be absent in this environment; a notice is logged instead of failing"
99
105
  }
100
106
  }
101
107
  },