camunda-cloud-idac 1.0.0 → 1.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/spec/compose.js +219 -0
- package/dist/spec/compose.js.map +1 -0
- package/dist/spec/errors.js +17 -0
- package/dist/spec/errors.js.map +1 -0
- package/dist/spec/load.js +12 -17
- package/dist/spec/load.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,7 @@ npm install
|
|
|
69
69
|
cp .env.example .env # fill in CAMUNDA_* connection details, then export them
|
|
70
70
|
|
|
71
71
|
npx tsx src/cli.ts validate spec.yaml # schema + referential integrity only, no network
|
|
72
|
+
npx tsx src/cli.ts render spec.yaml # print the fully resolved spec as YAML, no network
|
|
72
73
|
npx tsx src/cli.ts plan spec.yaml [--prune] # dry-run diff; exit 1 if there's drift (CI-friendly)
|
|
73
74
|
npx tsx src/cli.ts apply spec.yaml [--prune] [--yes]
|
|
74
75
|
```
|
|
@@ -90,6 +91,88 @@ some principals are granted access by username/client ID rather than by an
|
|
|
90
91
|
IdP group claim. These aren't declared entities elsewhere in the spec, so
|
|
91
92
|
there's no referential-integrity check on them (any string is accepted).
|
|
92
93
|
|
|
94
|
+
## Environment files
|
|
95
|
+
|
|
96
|
+
The single `<spec>` argument to `validate`/`render`/`plan`/`apply` can be either a
|
|
97
|
+
flat spec (above) or an **environment file** that composes several spec
|
|
98
|
+
fragments into one, for organizations that run the same identity model
|
|
99
|
+
across multiple environments/clusters with per-cluster differences:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
# specs/e0.yaml
|
|
103
|
+
include:
|
|
104
|
+
- base.yaml
|
|
105
|
+
- procapps/leistung.yaml
|
|
106
|
+
- procapps/workflow.yaml
|
|
107
|
+
# a procapp fragment can be left out here if this cluster doesn't need it
|
|
108
|
+
|
|
109
|
+
values:
|
|
110
|
+
ENV_SUFFIX: E0
|
|
111
|
+
KUMUL_CLIENT_ID: kumul
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
A file is treated as an environment file purely because it has a top-level
|
|
115
|
+
`include` key (flat specs never do, since `RawSpec` is `.strict()` and has
|
|
116
|
+
no such field, so detection can't collide with the existing format).
|
|
117
|
+
`include` paths resolve relative to the environment file's own directory.
|
|
118
|
+
See `test/fixtures/compose/` for a complete worked example (base + 3
|
|
119
|
+
procapp fragments + a full and a partial environment file).
|
|
120
|
+
|
|
121
|
+
Use `camunda-idac render <spec>` to print the fully composed and
|
|
122
|
+
interpolated spec as YAML - useful to double-check what an environment
|
|
123
|
+
file actually resolves to (which procapps ended up included, what
|
|
124
|
+
`${VAR}` placeholders became) before running `plan`/`apply` against it.
|
|
125
|
+
|
|
126
|
+
**Fragments** are plain YAML files shaped like a spec, but looser: only
|
|
127
|
+
each entity's ID field (`tenantId`/`roleId`/`groupId`/`mappingRuleId`) is
|
|
128
|
+
required - every other field is optional, since one fragment may only be
|
|
129
|
+
contributing a *piece* of an entity that another fragment (or a shared
|
|
130
|
+
`base.yaml`) already declares in full. This is what lets a role like
|
|
131
|
+
`process-owner` span every procapp without every procapp fragment knowing
|
|
132
|
+
about the others: `base.yaml` declares `process-owner`'s `name`, and each
|
|
133
|
+
`procapps/<name>.yaml` fragment separately contributes its own group to
|
|
134
|
+
`process-owner.groups`.
|
|
135
|
+
|
|
136
|
+
When multiple fragments mention the same entity ID:
|
|
137
|
+
|
|
138
|
+
- **Array fields** (`groups`, `mappingRules`, `users`, `clients`, `roles`)
|
|
139
|
+
are **unioned** (deduplicated, first-seen order).
|
|
140
|
+
- **Scalar fields** (`name`, `description`, `claimName`, `claimValue`) must
|
|
141
|
+
not disagree - two fragments giving the same ID a different value for the
|
|
142
|
+
same scalar field is a composition error naming both files and values.
|
|
143
|
+
- `authorizations` have no ID field and are simply concatenated; the
|
|
144
|
+
existing schema already tolerates exact duplicate authorization tuples
|
|
145
|
+
and flags genuine permission conflicts, so no special merging is needed.
|
|
146
|
+
|
|
147
|
+
Only the fully merged, ID-deduplicated result is validated against the same
|
|
148
|
+
unmodified `Spec` schema used for flat specs - so every existing guarantee
|
|
149
|
+
(referential integrity, no duplicate IDs, authorization-tuple conflicts)
|
|
150
|
+
still applies to the assembled spec exactly as it does today. If no
|
|
151
|
+
fragment ever provides a required field (e.g. `name`), that surfaces as the
|
|
152
|
+
same "Required" error you'd get from an incomplete flat spec.
|
|
153
|
+
|
|
154
|
+
`include` is exactly one level deep - a fragment listed under `include` may
|
|
155
|
+
not itself have a top-level `include` key (nested composition isn't
|
|
156
|
+
supported, and produces a clear error if attempted).
|
|
157
|
+
|
|
158
|
+
**`${VAR}` substitution**: each fragment's raw text is scanned for
|
|
159
|
+
`${NAME}` placeholders before it's parsed as YAML, substituted from the
|
|
160
|
+
environment file's `values` map. Any placeholder left unresolved after
|
|
161
|
+
substitution (a typo, or a `values` map missing an entry) is a hard error
|
|
162
|
+
naming the fragment file and the unresolved name(s) - it never silently
|
|
163
|
+
passes through as a literal string. A flat spec (no `include` key) is never
|
|
164
|
+
scanned for placeholders, so a literal `${...}`-looking value in a flat
|
|
165
|
+
spec is passed through untouched.
|
|
166
|
+
|
|
167
|
+
**Prune caveat**: omitting a procapp fragment from an environment's
|
|
168
|
+
`include` is, to the reconciler, indistinguishable from "this was
|
|
169
|
+
intentionally removed." If that procapp's tenant/group/mapping rules still
|
|
170
|
+
exist on the target cluster (e.g. it was deployed there before, or under a
|
|
171
|
+
different environment file), a later `apply --prune` run against that
|
|
172
|
+
cluster will delete them - same as removing any other entity from a flat
|
|
173
|
+
spec. Make sure `include` lists match what should actually exist on each
|
|
174
|
+
cluster before pruning.
|
|
175
|
+
|
|
93
176
|
## Known limitations
|
|
94
177
|
|
|
95
178
|
- Direct **tenant**-to-user/client assignments aren't modeled by the spec
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
4
5
|
import { loadSpec, SpecValidationError } from "./spec/load.js";
|
|
5
6
|
import { fetchCurrentState } from "./camunda/list-all.js";
|
|
6
7
|
import { buildPlan } from "./reconcile/diff.js";
|
|
@@ -60,6 +61,20 @@ program
|
|
|
60
61
|
process.exitCode = 1;
|
|
61
62
|
}
|
|
62
63
|
});
|
|
64
|
+
program
|
|
65
|
+
.command("render")
|
|
66
|
+
.description("print the fully resolved spec as YAML - resolves include/values composition, no network access")
|
|
67
|
+
.argument("<spec>", "path to the YAML spec file or environment file")
|
|
68
|
+
.action(async (specPath) => {
|
|
69
|
+
try {
|
|
70
|
+
const spec = await loadSpec(specPath);
|
|
71
|
+
console.log(stringifyYaml(spec));
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
reportError(err);
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
63
78
|
program
|
|
64
79
|
.command("plan")
|
|
65
80
|
.description("show what would change against the live cluster, without applying anything")
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { OwnerType, PermissionType, ResourceType } from "./schema.js";
|
|
6
|
+
import { formatZodError, SpecValidationError } from "./errors.js";
|
|
7
|
+
export const EnvironmentFile = z
|
|
8
|
+
.object({
|
|
9
|
+
include: z.array(z.string().min(1)).min(1),
|
|
10
|
+
values: z.record(z.string(), z.string()).default({}),
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
export function isEnvironmentFile(parsed) {
|
|
14
|
+
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && Object.hasOwn(parsed, "include");
|
|
15
|
+
}
|
|
16
|
+
const PLACEHOLDER_PATTERN = /\$\{([^}]+)\}/g;
|
|
17
|
+
export function substituteVariables(text, values) {
|
|
18
|
+
return text.replace(PLACEHOLDER_PATTERN, (match, name) => (Object.hasOwn(values, name) ? values[name] : match));
|
|
19
|
+
}
|
|
20
|
+
export function findUnresolvedPlaceholders(text) {
|
|
21
|
+
const found = new Set();
|
|
22
|
+
for (const match of text.matchAll(PLACEHOLDER_PATTERN)) {
|
|
23
|
+
found.add(match[1]);
|
|
24
|
+
}
|
|
25
|
+
return [...found];
|
|
26
|
+
}
|
|
27
|
+
// Fragment schemas mirror schema.ts's entities, but only the ID field is required -
|
|
28
|
+
// every other field (including `name`, required on the final Spec) is optional,
|
|
29
|
+
// since a fragment may only be contributing a piece of an entity that another
|
|
30
|
+
// fragment (or base.yaml) already fully declares. mergeEntitiesById() below unions
|
|
31
|
+
// array fields and rejects conflicting scalar fields across fragments; only the
|
|
32
|
+
// fully merged result is validated against the real, unmodified `Spec` schema in
|
|
33
|
+
// load.ts, which is what actually enforces that every entity ends up complete.
|
|
34
|
+
const MappingRuleFragment = z
|
|
35
|
+
.object({
|
|
36
|
+
mappingRuleId: z.string().min(1),
|
|
37
|
+
claimName: z.string().min(1).optional(),
|
|
38
|
+
claimValue: z.string().min(1).optional(),
|
|
39
|
+
name: z.string().optional(),
|
|
40
|
+
})
|
|
41
|
+
.strict();
|
|
42
|
+
const GroupFragment = z
|
|
43
|
+
.object({
|
|
44
|
+
groupId: z.string().min(1),
|
|
45
|
+
name: z.string().min(1).optional(),
|
|
46
|
+
description: z.string().optional(),
|
|
47
|
+
mappingRules: z.array(z.string()).default([]),
|
|
48
|
+
users: z.array(z.string()).default([]),
|
|
49
|
+
clients: z.array(z.string()).default([]),
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
52
|
+
const RoleFragment = z
|
|
53
|
+
.object({
|
|
54
|
+
roleId: z.string().min(1),
|
|
55
|
+
name: z.string().min(1).optional(),
|
|
56
|
+
description: z.string().optional(),
|
|
57
|
+
mappingRules: z.array(z.string()).default([]),
|
|
58
|
+
groups: z.array(z.string()).default([]),
|
|
59
|
+
users: z.array(z.string()).default([]),
|
|
60
|
+
clients: z.array(z.string()).default([]),
|
|
61
|
+
})
|
|
62
|
+
.strict();
|
|
63
|
+
const TenantFragment = z
|
|
64
|
+
.object({
|
|
65
|
+
tenantId: z.string().min(1),
|
|
66
|
+
name: z.string().min(1).optional(),
|
|
67
|
+
description: z.string().optional(),
|
|
68
|
+
roles: z.array(z.string()).default([]),
|
|
69
|
+
groups: z.array(z.string()).default([]),
|
|
70
|
+
mappingRules: z.array(z.string()).default([]),
|
|
71
|
+
})
|
|
72
|
+
.strict();
|
|
73
|
+
const AuthorizationFragment = z
|
|
74
|
+
.object({
|
|
75
|
+
ownerType: OwnerType,
|
|
76
|
+
ownerId: z.string().min(1),
|
|
77
|
+
resourceType: ResourceType,
|
|
78
|
+
resourceId: z.string().min(1),
|
|
79
|
+
permissions: z.array(PermissionType).min(1),
|
|
80
|
+
})
|
|
81
|
+
.strict();
|
|
82
|
+
const FragmentSpec = z
|
|
83
|
+
.object({
|
|
84
|
+
tenants: z.array(TenantFragment).default([]),
|
|
85
|
+
roles: z.array(RoleFragment).default([]),
|
|
86
|
+
groups: z.array(GroupFragment).default([]),
|
|
87
|
+
mappingRules: z.array(MappingRuleFragment).default([]),
|
|
88
|
+
authorizations: z.array(AuthorizationFragment).default([]),
|
|
89
|
+
})
|
|
90
|
+
.strict();
|
|
91
|
+
// Merges entities sharing the same ID across fragments: array fields are unioned
|
|
92
|
+
// (deduped, first-seen order), scalar fields must agree everywhere they're set -
|
|
93
|
+
// two fragments giving the same ID a different value for the same scalar field is
|
|
94
|
+
// a real authoring conflict, not something a union could resolve.
|
|
95
|
+
function mergeEntitiesById(entries, config, entityLabel) {
|
|
96
|
+
const order = [];
|
|
97
|
+
const merged = new Map();
|
|
98
|
+
const scalarSources = new Map();
|
|
99
|
+
for (const { filePath, entity } of entries) {
|
|
100
|
+
const id = entity[config.idField];
|
|
101
|
+
if (!merged.has(id)) {
|
|
102
|
+
merged.set(id, { [config.idField]: id });
|
|
103
|
+
scalarSources.set(id, new Map());
|
|
104
|
+
order.push(id);
|
|
105
|
+
}
|
|
106
|
+
const target = merged.get(id);
|
|
107
|
+
const sources = scalarSources.get(id);
|
|
108
|
+
for (const field of config.scalarFields) {
|
|
109
|
+
const value = entity[field];
|
|
110
|
+
if (value === undefined)
|
|
111
|
+
continue;
|
|
112
|
+
const existing = sources.get(field);
|
|
113
|
+
if (existing && existing.value !== value) {
|
|
114
|
+
throw new Error(`${entityLabel} "${id}" has conflicting "${field}": "${existing.value}" (${existing.filePath}) vs. "${value}" (${filePath})`);
|
|
115
|
+
}
|
|
116
|
+
if (!existing) {
|
|
117
|
+
sources.set(field, { value: value, filePath });
|
|
118
|
+
target[field] = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const field of config.arrayFields) {
|
|
122
|
+
const values = entity[field] ?? [];
|
|
123
|
+
const union = [...(target[field] ?? [])];
|
|
124
|
+
for (const v of values) {
|
|
125
|
+
if (!union.includes(v))
|
|
126
|
+
union.push(v);
|
|
127
|
+
}
|
|
128
|
+
target[field] = union;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return order.map((id) => merged.get(id));
|
|
132
|
+
}
|
|
133
|
+
async function loadFragment(fragmentPath, values) {
|
|
134
|
+
let raw;
|
|
135
|
+
try {
|
|
136
|
+
raw = await readFile(fragmentPath, "utf-8");
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
throw new Error(`Could not read fragment "${fragmentPath}": ${err instanceof Error ? err.message : String(err)}`);
|
|
140
|
+
}
|
|
141
|
+
const substituted = substituteVariables(raw, values);
|
|
142
|
+
const unresolved = findUnresolvedPlaceholders(substituted);
|
|
143
|
+
if (unresolved.length > 0) {
|
|
144
|
+
throw new Error(`Fragment "${fragmentPath}" has unresolved placeholder(s): ${unresolved.map((n) => `\${${n}}`).join(", ")}`);
|
|
145
|
+
}
|
|
146
|
+
let parsed;
|
|
147
|
+
try {
|
|
148
|
+
parsed = parseYaml(substituted);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (err instanceof YAMLParseError) {
|
|
152
|
+
throw new Error(`Fragment "${fragmentPath}" is not valid YAML: ${err.message}`);
|
|
153
|
+
}
|
|
154
|
+
throw err;
|
|
155
|
+
}
|
|
156
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && Object.hasOwn(parsed, "include")) {
|
|
157
|
+
throw new Error(`Fragment "${fragmentPath}" has a top-level "include" key - nested composition isn't supported, "include" may only appear in the top-level environment file`);
|
|
158
|
+
}
|
|
159
|
+
const result = FragmentSpec.safeParse(parsed);
|
|
160
|
+
if (!result.success) {
|
|
161
|
+
throw new Error(`Fragment "${fragmentPath}" is invalid:\n${formatZodError(result.error).map((i) => ` - ${i}`).join("\n")}`);
|
|
162
|
+
}
|
|
163
|
+
return result.data;
|
|
164
|
+
}
|
|
165
|
+
export function mergeFragments(fragments) {
|
|
166
|
+
const asEntries = (key) => fragments.flatMap((f) => f.data[key].map((entity) => ({ filePath: f.filePath, entity })));
|
|
167
|
+
return {
|
|
168
|
+
tenants: mergeEntitiesById(asEntries("tenants"), {
|
|
169
|
+
idField: "tenantId",
|
|
170
|
+
scalarFields: ["name", "description"],
|
|
171
|
+
arrayFields: ["roles", "groups", "mappingRules"],
|
|
172
|
+
}, "Tenant"),
|
|
173
|
+
roles: mergeEntitiesById(asEntries("roles"), {
|
|
174
|
+
idField: "roleId",
|
|
175
|
+
scalarFields: ["name", "description"],
|
|
176
|
+
arrayFields: ["mappingRules", "groups", "users", "clients"],
|
|
177
|
+
}, "Role"),
|
|
178
|
+
groups: mergeEntitiesById(asEntries("groups"), {
|
|
179
|
+
idField: "groupId",
|
|
180
|
+
scalarFields: ["name", "description"],
|
|
181
|
+
arrayFields: ["mappingRules", "users", "clients"],
|
|
182
|
+
}, "Group"),
|
|
183
|
+
mappingRules: mergeEntitiesById(asEntries("mappingRules"), {
|
|
184
|
+
idField: "mappingRuleId",
|
|
185
|
+
scalarFields: ["claimName", "claimValue", "name"],
|
|
186
|
+
arrayFields: [],
|
|
187
|
+
}, "Mapping rule"),
|
|
188
|
+
authorizations: fragments.flatMap((f) => f.data.authorizations),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
export async function composeSpec(envFilePath, envFile) {
|
|
192
|
+
const baseDir = dirname(envFilePath);
|
|
193
|
+
const seen = new Set();
|
|
194
|
+
const resolvedPaths = [];
|
|
195
|
+
for (const includePath of envFile.include) {
|
|
196
|
+
const resolved = resolve(baseDir, includePath);
|
|
197
|
+
if (seen.has(resolved)) {
|
|
198
|
+
throw new SpecValidationError(envFilePath, [`Duplicate include entry resolves to the same file: "${resolved}"`]);
|
|
199
|
+
}
|
|
200
|
+
seen.add(resolved);
|
|
201
|
+
resolvedPaths.push(resolved);
|
|
202
|
+
}
|
|
203
|
+
const fragments = [];
|
|
204
|
+
for (const fragmentPath of resolvedPaths) {
|
|
205
|
+
try {
|
|
206
|
+
fragments.push({ filePath: fragmentPath, data: await loadFragment(fragmentPath, envFile.values) });
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
throw new SpecValidationError(envFilePath, [err instanceof Error ? err.message : String(err)]);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
return mergeFragments(fragments);
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
throw new SpecValidationError(envFilePath, [err instanceof Error ? err.message : String(err)]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/spec/compose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class SpecValidationError extends Error {
|
|
2
|
+
filePath;
|
|
3
|
+
issues;
|
|
4
|
+
constructor(filePath, issues) {
|
|
5
|
+
super(`Invalid spec at ${filePath}:\n${issues.map((i) => ` - ${i}`).join("\n")}`);
|
|
6
|
+
this.filePath = filePath;
|
|
7
|
+
this.issues = issues;
|
|
8
|
+
this.name = "SpecValidationError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function formatZodError(error) {
|
|
12
|
+
return error.issues.map((issue) => {
|
|
13
|
+
const path = issue.path.join(".");
|
|
14
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/spec/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAE1B;IACA;IAFlB,YACkB,QAAgB,EAChB,MAAgB;QAEhC,KAAK,CAAC,mBAAmB,QAAQ,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAHnE,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAU;QAGhC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/spec/load.js
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
3
3
|
import { Spec } from "./schema.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
constructor(filePath, issues) {
|
|
8
|
-
super(`Invalid spec at ${filePath}:\n${issues.map((i) => ` - ${i}`).join("\n")}`);
|
|
9
|
-
this.filePath = filePath;
|
|
10
|
-
this.issues = issues;
|
|
11
|
-
this.name = "SpecValidationError";
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function formatZodError(error) {
|
|
15
|
-
return error.issues.map((issue) => {
|
|
16
|
-
const path = issue.path.join(".");
|
|
17
|
-
return path ? `${path}: ${issue.message}` : issue.message;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
4
|
+
import { composeSpec, EnvironmentFile, isEnvironmentFile } from "./compose.js";
|
|
5
|
+
import { formatZodError, SpecValidationError } from "./errors.js";
|
|
6
|
+
export { SpecValidationError } from "./errors.js";
|
|
20
7
|
export async function loadSpec(filePath) {
|
|
21
8
|
let raw;
|
|
22
9
|
try {
|
|
@@ -37,7 +24,15 @@ export async function loadSpec(filePath) {
|
|
|
37
24
|
}
|
|
38
25
|
throw err;
|
|
39
26
|
}
|
|
40
|
-
|
|
27
|
+
let assembled = parsed;
|
|
28
|
+
if (isEnvironmentFile(parsed)) {
|
|
29
|
+
const envResult = EnvironmentFile.safeParse(parsed);
|
|
30
|
+
if (!envResult.success) {
|
|
31
|
+
throw new SpecValidationError(filePath, formatZodError(envResult.error));
|
|
32
|
+
}
|
|
33
|
+
assembled = await composeSpec(filePath, envResult.data);
|
|
34
|
+
}
|
|
35
|
+
const result = Spec.safeParse(assembled);
|
|
41
36
|
if (!result.success) {
|
|
42
37
|
throw new SpecValidationError(filePath, formatZodError(result.error));
|
|
43
38
|
}
|
package/dist/spec/load.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/spec/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/spec/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE;YACtC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,MAAM,CAAC,GAAG,CAAC,EAAE;SAC3E,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,SAAS,GAAY,MAAM,CAAC;IAChC,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,SAAS,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
package/package.json
CHANGED