@burojs/config 0.2.0 → 0.4.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/dist/index.cjs +435 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -29
- package/dist/index.d.ts +33 -29
- package/dist/index.js +434 -492
- package/dist/index.js.map +1 -1
- package/package.json +5 -6
package/dist/index.cjs
CHANGED
|
@@ -1,563 +1,504 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let yaml = require("yaml");
|
|
3
|
+
//#region src/parse.ts
|
|
4
|
+
const RESERVED_KEYS = new Set([
|
|
5
|
+
"__proto__",
|
|
6
|
+
"prototype",
|
|
7
|
+
"constructor"
|
|
8
|
+
]);
|
|
9
|
+
const FORBIDDEN_VALUE_CATEGORIES = new Map([
|
|
10
|
+
["action", "action"],
|
|
11
|
+
["actions", "action"],
|
|
12
|
+
["provider", "provider"],
|
|
13
|
+
["providers", "provider"],
|
|
14
|
+
["mapper", "mapper"],
|
|
15
|
+
["mappers", "mapper"],
|
|
16
|
+
["service", "service"],
|
|
17
|
+
["services", "service"],
|
|
18
|
+
["credential", "credential"],
|
|
19
|
+
["credentials", "credential"],
|
|
20
|
+
["schema", "schema"],
|
|
21
|
+
["schemas", "schema"],
|
|
22
|
+
["component", "component"],
|
|
23
|
+
["components", "component"],
|
|
24
|
+
["attachment", "attachment"],
|
|
25
|
+
["attachments", "attachment"],
|
|
26
|
+
["validator", "validator"],
|
|
27
|
+
["validators", "validator"]
|
|
28
|
+
]);
|
|
29
|
+
const LAYER_KEYS = new Set([
|
|
30
|
+
"id",
|
|
31
|
+
"priority",
|
|
32
|
+
"defaultNamespace",
|
|
33
|
+
"revision",
|
|
34
|
+
"declarations",
|
|
35
|
+
"transforms"
|
|
36
|
+
]);
|
|
37
|
+
const DECLARATION_KEYS = new Set([
|
|
38
|
+
"kind",
|
|
39
|
+
"ref",
|
|
40
|
+
"schemaVersion",
|
|
41
|
+
"value"
|
|
26
42
|
]);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"declarations",
|
|
33
|
-
"transforms"
|
|
43
|
+
const TRANSFORM_KEYS = new Set([
|
|
44
|
+
"id",
|
|
45
|
+
"scope",
|
|
46
|
+
"select",
|
|
47
|
+
"operation"
|
|
34
48
|
]);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
const SELECTOR_KEYS = new Set([
|
|
50
|
+
"kinds",
|
|
51
|
+
"namespaces",
|
|
52
|
+
"layers",
|
|
53
|
+
"refs",
|
|
54
|
+
"excludeRefs",
|
|
55
|
+
"tags"
|
|
56
|
+
]);
|
|
57
|
+
const OPERATION_KEYS = {
|
|
58
|
+
merge: new Set(["op", "value"]),
|
|
59
|
+
replace: new Set([
|
|
60
|
+
"op",
|
|
61
|
+
"value",
|
|
62
|
+
"ifMissing"
|
|
63
|
+
]),
|
|
64
|
+
disable: new Set(["op", "reason"]),
|
|
65
|
+
delete: new Set(["op"])
|
|
43
66
|
};
|
|
44
|
-
|
|
67
|
+
const ATTACHMENT_TAG = "@burojs/core/trusted-attachment";
|
|
45
68
|
var Diagnostics = class {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
limit;
|
|
70
|
+
values = [];
|
|
71
|
+
limited = false;
|
|
72
|
+
constructor(limit) {
|
|
73
|
+
this.limit = limit;
|
|
74
|
+
}
|
|
75
|
+
add(code) {
|
|
76
|
+
if (this.limited) return;
|
|
77
|
+
if (this.values.length + 1 < this.limit) {
|
|
78
|
+
this.values.push(Object.freeze({
|
|
79
|
+
code,
|
|
80
|
+
message: messageFor(code)
|
|
81
|
+
}));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.limited = true;
|
|
85
|
+
this.values.push(Object.freeze({
|
|
86
|
+
code: "source.diagnostic-limit",
|
|
87
|
+
message: messageFor("source.diagnostic-limit")
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
66
90
|
};
|
|
67
91
|
function messageFor(code) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return "The source requests a forbidden declaration kind.";
|
|
101
|
-
case "source.forbidden-namespace":
|
|
102
|
-
return "The source requests a forbidden namespace.";
|
|
103
|
-
case "source.forbidden-transform-op":
|
|
104
|
-
return "The source requests a forbidden transform operation.";
|
|
105
|
-
case "source.forbidden-transform-scope":
|
|
106
|
-
return "The source requests a forbidden transform scope.";
|
|
107
|
-
case "source.forbidden-capability":
|
|
108
|
-
return "The source requests a forbidden capability.";
|
|
109
|
-
case "source.forbidden-action":
|
|
110
|
-
return "The source requests a forbidden action binding.";
|
|
111
|
-
case "source.forbidden-provider":
|
|
112
|
-
return "The source requests a forbidden provider binding.";
|
|
113
|
-
case "source.forbidden-mapper":
|
|
114
|
-
return "The source requests a forbidden mapper binding.";
|
|
115
|
-
case "source.forbidden-service":
|
|
116
|
-
return "The source requests a forbidden service value.";
|
|
117
|
-
case "source.forbidden-credential":
|
|
118
|
-
return "The source requests a forbidden credential value.";
|
|
119
|
-
case "source.forbidden-schema":
|
|
120
|
-
return "The source requests a forbidden schema value.";
|
|
121
|
-
case "source.forbidden-component":
|
|
122
|
-
return "The source requests a forbidden component value.";
|
|
123
|
-
case "source.forbidden-attachment":
|
|
124
|
-
return "The source requests a forbidden attachment value.";
|
|
125
|
-
case "source.forbidden-validator":
|
|
126
|
-
return "The source requests a forbidden validator value.";
|
|
127
|
-
default:
|
|
128
|
-
return "The source is invalid.";
|
|
129
|
-
}
|
|
92
|
+
switch (code) {
|
|
93
|
+
case "source.invalid-json": return "The source is not valid JSON.";
|
|
94
|
+
case "source.invalid-yaml": return "The source is not valid YAML.";
|
|
95
|
+
case "source.invalid-policy": return "The source policy is invalid.";
|
|
96
|
+
case "source.byte-limit": return "The source exceeds its byte limit.";
|
|
97
|
+
case "source.declaration-limit": return "The source exceeds its declaration limit.";
|
|
98
|
+
case "source.depth-limit": return "The source exceeds its nesting-depth limit.";
|
|
99
|
+
case "source.string-limit": return "The source contains an overlong string.";
|
|
100
|
+
case "source.diagnostic-limit": return "Additional source diagnostics were omitted.";
|
|
101
|
+
case "source.unknown-key": return "The source contains an unknown key.";
|
|
102
|
+
case "source.reserved-key": return "The source contains a reserved key.";
|
|
103
|
+
case "source.accessor": return "The source must use data properties.";
|
|
104
|
+
case "source.cyclic-value": return "The source must not contain cyclic values.";
|
|
105
|
+
case "source.invalid-layer": return "The source layer is invalid.";
|
|
106
|
+
case "source.invalid-declaration": return "The source declaration is invalid.";
|
|
107
|
+
case "source.invalid-transform": return "The source transform is invalid.";
|
|
108
|
+
case "source.forbidden-kind": return "The source requests a forbidden declaration kind.";
|
|
109
|
+
case "source.forbidden-namespace": return "The source requests a forbidden namespace.";
|
|
110
|
+
case "source.forbidden-transform-op": return "The source requests a forbidden transform operation.";
|
|
111
|
+
case "source.forbidden-transform-scope": return "The source requests a forbidden transform scope.";
|
|
112
|
+
case "source.forbidden-capability": return "The source requests a forbidden capability.";
|
|
113
|
+
case "source.forbidden-action": return "The source requests a forbidden action binding.";
|
|
114
|
+
case "source.forbidden-provider": return "The source requests a forbidden provider binding.";
|
|
115
|
+
case "source.forbidden-mapper": return "The source requests a forbidden mapper binding.";
|
|
116
|
+
case "source.forbidden-service": return "The source requests a forbidden service value.";
|
|
117
|
+
case "source.forbidden-credential": return "The source requests a forbidden credential value.";
|
|
118
|
+
case "source.forbidden-schema": return "The source requests a forbidden schema value.";
|
|
119
|
+
case "source.forbidden-component": return "The source requests a forbidden component value.";
|
|
120
|
+
case "source.forbidden-attachment": return "The source requests a forbidden attachment value.";
|
|
121
|
+
case "source.forbidden-validator": return "The source requests a forbidden validator value.";
|
|
122
|
+
default: return "The source is invalid.";
|
|
123
|
+
}
|
|
130
124
|
}
|
|
131
125
|
function validLimits(limits) {
|
|
132
|
-
|
|
126
|
+
return Object.values(limits).every((value) => Number.isSafeInteger(value) && value > 0);
|
|
133
127
|
}
|
|
134
128
|
function validCapabilities(value) {
|
|
135
|
-
|
|
136
|
-
(capabilities) => Array.isArray(capabilities) && capabilities.every((capability) => typeof capability === "string")
|
|
137
|
-
);
|
|
129
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((capabilities) => Array.isArray(capabilities) && capabilities.every((capability) => typeof capability === "string"));
|
|
138
130
|
}
|
|
139
131
|
function validPolicy(policy) {
|
|
140
|
-
|
|
132
|
+
return policy !== null && typeof policy === "object" && Array.isArray(policy.allowedKinds) && Array.isArray(policy.allowedNamespaces) && Array.isArray(policy.allowedTransformOps) && (policy.maxTransformScope === "layer" || policy.maxTransformScope === "namespace" || policy.maxTransformScope === "application") && validCapabilities(policy.allowedCapabilities) && validLimits(policy.limits);
|
|
141
133
|
}
|
|
142
134
|
function failure(diagnostics) {
|
|
143
|
-
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
diagnostics: Object.freeze(diagnostics.values)
|
|
138
|
+
};
|
|
144
139
|
}
|
|
145
140
|
function plainObject(value) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
142
|
+
const prototype = Object.getPrototypeOf(value);
|
|
143
|
+
return prototype === Object.prototype || prototype === null;
|
|
149
144
|
}
|
|
150
145
|
function ownData(value, key) {
|
|
151
|
-
|
|
152
|
-
|
|
146
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
147
|
+
return descriptor !== void 0 && "value" in descriptor ? descriptor.value : void 0;
|
|
153
148
|
}
|
|
154
149
|
function hasData(value, key) {
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
151
|
+
return descriptor !== void 0 && "value" in descriptor;
|
|
157
152
|
}
|
|
158
153
|
function clonePortable(value, limits, diagnostics) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
return copy(value, 0);
|
|
154
|
+
const ancestors = new WeakSet();
|
|
155
|
+
function copy(current, depth) {
|
|
156
|
+
if (depth > limits.maxDepth) {
|
|
157
|
+
diagnostics.add("source.depth-limit");
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
if (current === null || typeof current === "boolean" || typeof current === "number") return current;
|
|
161
|
+
if (typeof current === "string") {
|
|
162
|
+
if ([...current].length > limits.maxStringLength) diagnostics.add("source.string-limit");
|
|
163
|
+
return current;
|
|
164
|
+
}
|
|
165
|
+
if (typeof current !== "object") {
|
|
166
|
+
diagnostics.add("source.invalid-layer");
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
if (ancestors.has(current)) {
|
|
170
|
+
diagnostics.add("source.cyclic-value");
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
ancestors.add(current);
|
|
174
|
+
if (Array.isArray(current)) {
|
|
175
|
+
const output = [];
|
|
176
|
+
for (const key of Reflect.ownKeys(current)) {
|
|
177
|
+
if (typeof key !== "string" || key !== "length" && !/^(0|[1-9]\d*)$/u.test(key)) {
|
|
178
|
+
diagnostics.add("source.invalid-layer");
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (key === "length") continue;
|
|
182
|
+
if (!hasData(current, key)) diagnostics.add("source.accessor");
|
|
183
|
+
}
|
|
184
|
+
const length = ownData(current, "length");
|
|
185
|
+
const arrayLength = typeof length === "number" && Number.isSafeInteger(length) && length >= 0 ? length : void 0;
|
|
186
|
+
if (arrayLength === void 0) diagnostics.add("source.invalid-layer");
|
|
187
|
+
else for (let index = 0; index < arrayLength; index += 1) {
|
|
188
|
+
if (!hasData(current, String(index))) diagnostics.add("source.accessor");
|
|
189
|
+
output.push(copy(ownData(current, String(index)), depth + 1));
|
|
190
|
+
}
|
|
191
|
+
ancestors.delete(current);
|
|
192
|
+
return Object.freeze(output);
|
|
193
|
+
}
|
|
194
|
+
if (!plainObject(current)) diagnostics.add("source.invalid-layer");
|
|
195
|
+
const output = Object.create(null);
|
|
196
|
+
for (const key of Reflect.ownKeys(current)) {
|
|
197
|
+
if (typeof key !== "string") {
|
|
198
|
+
diagnostics.add("source.invalid-layer");
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (RESERVED_KEYS.has(key)) diagnostics.add("source.reserved-key");
|
|
202
|
+
if ([...key].length > limits.maxStringLength) diagnostics.add("source.string-limit");
|
|
203
|
+
if (!hasData(current, key)) {
|
|
204
|
+
diagnostics.add("source.accessor");
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
output[key] = copy(ownData(current, key), depth + 1);
|
|
208
|
+
}
|
|
209
|
+
ancestors.delete(current);
|
|
210
|
+
return Object.freeze(output);
|
|
211
|
+
}
|
|
212
|
+
return copy(value, 0);
|
|
220
213
|
}
|
|
221
214
|
function unknownKeys(value, allowed, diagnostics) {
|
|
222
|
-
|
|
223
|
-
if (!allowed.has(key)) diagnostics.add("source.unknown-key");
|
|
215
|
+
for (const key of Object.keys(value)) if (!allowed.has(key)) diagnostics.add("source.unknown-key");
|
|
224
216
|
}
|
|
225
217
|
function allowedNamespace(value, policy, diagnostics) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
218
|
+
if (typeof value !== "string" || !policy.allowedNamespaces.includes(value)) {
|
|
219
|
+
diagnostics.add("source.forbidden-namespace");
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
231
223
|
}
|
|
232
224
|
function namespaceFor(ref, defaultNamespace, diagnostics) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return typeof namespace === "string" ? namespace : void 0;
|
|
225
|
+
if (typeof ref === "string") {
|
|
226
|
+
const separator = ref.indexOf(":");
|
|
227
|
+
return separator === -1 ? defaultNamespace : ref.slice(0, separator);
|
|
228
|
+
}
|
|
229
|
+
if (!plainObject(ref) || !hasData(ref, "id")) {
|
|
230
|
+
diagnostics.add("source.invalid-declaration");
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
for (const key of Object.keys(ref)) if (key !== "id" && key !== "namespace") diagnostics.add("source.unknown-key");
|
|
234
|
+
const namespace = hasData(ref, "namespace") ? ownData(ref, "namespace") : defaultNamespace;
|
|
235
|
+
if (typeof namespace !== "string") diagnostics.add("source.invalid-declaration");
|
|
236
|
+
return typeof namespace === "string" ? namespace : void 0;
|
|
246
237
|
}
|
|
247
238
|
function validateValue(value, kind, policy, diagnostics) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
validateValue(ownData(value, key), kind, policy, diagnostics);
|
|
264
|
-
}
|
|
239
|
+
if (value === null || typeof value !== "object") return;
|
|
240
|
+
if (Array.isArray(value)) {
|
|
241
|
+
for (const item of value) validateValue(item, kind, policy, diagnostics);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (!plainObject(value)) return;
|
|
245
|
+
if (value.$buro === ATTACHMENT_TAG) {
|
|
246
|
+
const capability = ownData(value, "capability");
|
|
247
|
+
if (typeof capability !== "string" || !policy.allowedCapabilities[kind]?.includes(capability)) diagnostics.add("source.forbidden-capability");
|
|
248
|
+
}
|
|
249
|
+
for (const key of Object.keys(value)) {
|
|
250
|
+
const category = FORBIDDEN_VALUE_CATEGORIES.get(key);
|
|
251
|
+
if (category !== void 0) diagnostics.add(`source.forbidden-${category}`);
|
|
252
|
+
validateValue(ownData(value, key), kind, policy, diagnostics);
|
|
253
|
+
}
|
|
265
254
|
}
|
|
266
255
|
function scopeRank(scope) {
|
|
267
|
-
|
|
256
|
+
return scope === "layer" ? 0 : scope === "namespace" ? 1 : 2;
|
|
268
257
|
}
|
|
269
258
|
function transformOperation(value) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
259
|
+
if (!plainObject(value)) return void 0;
|
|
260
|
+
const operation = ownData(value, "op");
|
|
261
|
+
return operation === "merge" || operation === "replace" || operation === "disable" || operation === "delete" ? operation : void 0;
|
|
273
262
|
}
|
|
274
263
|
function validateSelectorRefs(value, defaultNamespace, policy, diagnostics) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
264
|
+
if (value === void 0) return;
|
|
265
|
+
if (!Array.isArray(value)) {
|
|
266
|
+
diagnostics.add("source.invalid-transform");
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
for (const ref of value) {
|
|
270
|
+
const namespace = namespaceFor(ref, defaultNamespace, diagnostics);
|
|
271
|
+
if (namespace !== void 0) allowedNamespace(namespace, policy, diagnostics);
|
|
272
|
+
}
|
|
284
273
|
}
|
|
285
274
|
function validateTransforms(value, defaultNamespace, policy, diagnostics) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
else {
|
|
331
|
-
if (!policy.allowedTransformOps.includes(op))
|
|
332
|
-
diagnostics.add("source.forbidden-transform-op");
|
|
333
|
-
if (plainObject(operation)) {
|
|
334
|
-
unknownKeys(operation, OPERATION_KEYS[op], diagnostics);
|
|
335
|
-
if (hasData(operation, "value"))
|
|
336
|
-
validateValue(ownData(operation, "value"), "", policy, diagnostics);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
275
|
+
if (value === void 0) return;
|
|
276
|
+
if (!Array.isArray(value)) {
|
|
277
|
+
diagnostics.add("source.invalid-transform");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
for (const transform of value) {
|
|
281
|
+
if (!plainObject(transform)) {
|
|
282
|
+
diagnostics.add("source.invalid-transform");
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
unknownKeys(transform, TRANSFORM_KEYS, diagnostics);
|
|
286
|
+
const scope = ownData(transform, "scope") ?? "layer";
|
|
287
|
+
if (scope !== "layer" && scope !== "application") diagnostics.add("source.invalid-transform");
|
|
288
|
+
else if (scopeRank(scope) > scopeRank(policy.maxTransformScope)) diagnostics.add("source.forbidden-transform-scope");
|
|
289
|
+
const select = ownData(transform, "select");
|
|
290
|
+
if (!plainObject(select)) diagnostics.add("source.invalid-transform");
|
|
291
|
+
else {
|
|
292
|
+
unknownKeys(select, SELECTOR_KEYS, diagnostics);
|
|
293
|
+
const selectedKinds = ownData(select, "kinds");
|
|
294
|
+
if (selectedKinds !== void 0) {
|
|
295
|
+
if (!Array.isArray(selectedKinds)) diagnostics.add("source.invalid-transform");
|
|
296
|
+
else for (const kind of selectedKinds) if (typeof kind !== "string") diagnostics.add("source.invalid-transform");
|
|
297
|
+
else if (!policy.allowedKinds.includes(kind)) diagnostics.add("source.forbidden-kind");
|
|
298
|
+
}
|
|
299
|
+
const selectedNamespaces = ownData(select, "namespaces");
|
|
300
|
+
if (selectedNamespaces !== void 0) {
|
|
301
|
+
if (!Array.isArray(selectedNamespaces)) diagnostics.add("source.invalid-transform");
|
|
302
|
+
else for (const namespace of selectedNamespaces) allowedNamespace(namespace, policy, diagnostics);
|
|
303
|
+
}
|
|
304
|
+
validateSelectorRefs(ownData(select, "refs"), defaultNamespace, policy, diagnostics);
|
|
305
|
+
validateSelectorRefs(ownData(select, "excludeRefs"), defaultNamespace, policy, diagnostics);
|
|
306
|
+
}
|
|
307
|
+
const operation = ownData(transform, "operation");
|
|
308
|
+
const op = transformOperation(operation);
|
|
309
|
+
if (typeof (plainObject(operation) ? ownData(operation, "op") : void 0) === "string" && op === void 0) diagnostics.add("source.forbidden-transform-op");
|
|
310
|
+
else if (op === void 0) diagnostics.add("source.invalid-transform");
|
|
311
|
+
else {
|
|
312
|
+
if (!policy.allowedTransformOps.includes(op)) diagnostics.add("source.forbidden-transform-op");
|
|
313
|
+
if (plainObject(operation)) {
|
|
314
|
+
unknownKeys(operation, OPERATION_KEYS[op], diagnostics);
|
|
315
|
+
if (hasData(operation, "value")) validateValue(ownData(operation, "value"), "", policy, diagnostics);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
340
319
|
}
|
|
341
320
|
function validateLayerValue(value, policy) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
if (!Number.isSafeInteger(ownData(declaration, "schemaVersion")) || !hasData(declaration, "value")) {
|
|
390
|
-
diagnostics.add("source.invalid-declaration");
|
|
391
|
-
}
|
|
392
|
-
if (typeof kind === "string" && hasData(declaration, "value")) {
|
|
393
|
-
validateValue(ownData(declaration, "value"), kind, policy, diagnostics);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
validateTransforms(
|
|
397
|
-
ownData(cloned, "transforms"),
|
|
398
|
-
typeof defaultNamespace === "string" ? defaultNamespace : "default",
|
|
399
|
-
policy,
|
|
400
|
-
diagnostics
|
|
401
|
-
);
|
|
402
|
-
if (diagnostics.values.length > 0) return failure(diagnostics);
|
|
403
|
-
return { ok: true, value: cloned };
|
|
321
|
+
if (!validPolicy(policy)) return {
|
|
322
|
+
ok: false,
|
|
323
|
+
diagnostics: Object.freeze([Object.freeze({
|
|
324
|
+
code: "source.invalid-policy",
|
|
325
|
+
message: messageFor("source.invalid-policy")
|
|
326
|
+
})])
|
|
327
|
+
};
|
|
328
|
+
const diagnostics = new Diagnostics(policy.limits.maxDiagnostics);
|
|
329
|
+
const cloned = clonePortable(value, policy.limits, diagnostics);
|
|
330
|
+
if (diagnostics.values.length > 0) return failure(diagnostics);
|
|
331
|
+
if (!plainObject(cloned)) {
|
|
332
|
+
diagnostics.add("source.invalid-layer");
|
|
333
|
+
return failure(diagnostics);
|
|
334
|
+
}
|
|
335
|
+
unknownKeys(cloned, LAYER_KEYS, diagnostics);
|
|
336
|
+
const id = ownData(cloned, "id");
|
|
337
|
+
const priority = ownData(cloned, "priority");
|
|
338
|
+
const declarations = ownData(cloned, "declarations");
|
|
339
|
+
if (typeof id !== "string" || !Number.isSafeInteger(priority) || !Array.isArray(declarations)) {
|
|
340
|
+
diagnostics.add("source.invalid-layer");
|
|
341
|
+
return failure(diagnostics);
|
|
342
|
+
}
|
|
343
|
+
if (declarations.length > policy.limits.maxDeclarations) diagnostics.add("source.declaration-limit");
|
|
344
|
+
const rawDefaultNamespace = ownData(cloned, "defaultNamespace");
|
|
345
|
+
const defaultNamespace = rawDefaultNamespace === void 0 ? "default" : rawDefaultNamespace;
|
|
346
|
+
if (typeof defaultNamespace !== "string") diagnostics.add("source.invalid-layer");
|
|
347
|
+
else allowedNamespace(defaultNamespace, policy, diagnostics);
|
|
348
|
+
for (const declaration of declarations) {
|
|
349
|
+
if (!plainObject(declaration)) {
|
|
350
|
+
diagnostics.add("source.invalid-declaration");
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
unknownKeys(declaration, DECLARATION_KEYS, diagnostics);
|
|
354
|
+
const kind = ownData(declaration, "kind");
|
|
355
|
+
if (typeof kind !== "string") diagnostics.add("source.invalid-declaration");
|
|
356
|
+
else if (!policy.allowedKinds.includes(kind)) diagnostics.add("source.forbidden-kind");
|
|
357
|
+
const namespace = namespaceFor(ownData(declaration, "ref"), typeof defaultNamespace === "string" ? defaultNamespace : "default", diagnostics);
|
|
358
|
+
if (namespace !== void 0) allowedNamespace(namespace, policy, diagnostics);
|
|
359
|
+
if (!Number.isSafeInteger(ownData(declaration, "schemaVersion")) || !hasData(declaration, "value")) diagnostics.add("source.invalid-declaration");
|
|
360
|
+
if (typeof kind === "string" && hasData(declaration, "value")) validateValue(ownData(declaration, "value"), kind, policy, diagnostics);
|
|
361
|
+
}
|
|
362
|
+
validateTransforms(ownData(cloned, "transforms"), typeof defaultNamespace === "string" ? defaultNamespace : "default", policy, diagnostics);
|
|
363
|
+
if (diagnostics.values.length > 0) return failure(diagnostics);
|
|
364
|
+
return {
|
|
365
|
+
ok: true,
|
|
366
|
+
value: cloned
|
|
367
|
+
};
|
|
404
368
|
}
|
|
405
369
|
function byteLength(value) {
|
|
406
|
-
|
|
370
|
+
return new TextEncoder().encode(value).byteLength;
|
|
407
371
|
}
|
|
408
372
|
function parseSource(source, policy, format) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
373
|
+
if (!validPolicy(policy)) return validateLayerValue(null, policy);
|
|
374
|
+
const diagnostics = new Diagnostics(policy.limits.maxDiagnostics);
|
|
375
|
+
if (byteLength(source) > policy.limits.maxBytes) {
|
|
376
|
+
diagnostics.add("source.byte-limit");
|
|
377
|
+
return failure(diagnostics);
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
if (format === "json") return validateLayerValue(JSON.parse(source), policy);
|
|
381
|
+
const document = (0, yaml.parseDocument)(source, {
|
|
382
|
+
prettyErrors: false,
|
|
383
|
+
strict: true,
|
|
384
|
+
uniqueKeys: true
|
|
385
|
+
});
|
|
386
|
+
if (document.errors.length > 0) {
|
|
387
|
+
diagnostics.add("source.invalid-yaml");
|
|
388
|
+
return failure(diagnostics);
|
|
389
|
+
}
|
|
390
|
+
return validateLayerValue(document.toJS({ maxAliasCount: 0 }), policy);
|
|
391
|
+
} catch {
|
|
392
|
+
diagnostics.add(format === "json" ? "source.invalid-json" : "source.invalid-yaml");
|
|
393
|
+
return failure(diagnostics);
|
|
394
|
+
}
|
|
427
395
|
}
|
|
428
396
|
function parseJsonLayer(source, policy) {
|
|
429
|
-
|
|
397
|
+
return parseSource(source, policy, "json");
|
|
430
398
|
}
|
|
431
399
|
function parseYamlLayer(source, policy) {
|
|
432
|
-
|
|
400
|
+
return parseSource(source, policy, "yaml");
|
|
433
401
|
}
|
|
434
|
-
|
|
435
|
-
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/adapter.ts
|
|
436
404
|
function diagnostic(code, message) {
|
|
437
|
-
|
|
405
|
+
return Object.freeze({
|
|
406
|
+
code,
|
|
407
|
+
message
|
|
408
|
+
});
|
|
438
409
|
}
|
|
439
410
|
function diagnosticLimit(policy) {
|
|
440
|
-
|
|
441
|
-
|
|
411
|
+
const candidate = policy?.limits?.maxDiagnostics;
|
|
412
|
+
return typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate > 0 ? candidate : 1;
|
|
442
413
|
}
|
|
443
414
|
function frozenPolicy(policy) {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
limits
|
|
456
|
-
});
|
|
415
|
+
const capabilities = Object.create(null);
|
|
416
|
+
for (const [kind, values] of Object.entries(policy.allowedCapabilities)) capabilities[kind] = Object.freeze([...values]);
|
|
417
|
+
const limits = Object.freeze({ ...policy.limits });
|
|
418
|
+
return Object.freeze({
|
|
419
|
+
allowedKinds: Object.freeze([...policy.allowedKinds]),
|
|
420
|
+
allowedNamespaces: Object.freeze([...policy.allowedNamespaces]),
|
|
421
|
+
allowedTransformOps: Object.freeze([...policy.allowedTransformOps]),
|
|
422
|
+
maxTransformScope: policy.maxTransformScope,
|
|
423
|
+
allowedCapabilities: Object.freeze(capabilities),
|
|
424
|
+
limits
|
|
425
|
+
});
|
|
457
426
|
}
|
|
458
427
|
function copyDiagnostic(value) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
value.code,
|
|
462
|
-
value.message
|
|
463
|
-
);
|
|
464
|
-
}
|
|
465
|
-
return diagnostic(
|
|
466
|
-
"source.invalid-adapter-diagnostic",
|
|
467
|
-
"The source adapter returned an invalid diagnostic."
|
|
468
|
-
);
|
|
428
|
+
if (value !== null && typeof value === "object" && typeof value.code === "string" && typeof value.message === "string") return diagnostic(value.code, value.message);
|
|
429
|
+
return diagnostic("source.invalid-adapter-diagnostic", "The source adapter returned an invalid diagnostic.");
|
|
469
430
|
}
|
|
470
431
|
function adaptRawConfig(input, adapter, policy) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
for (const entry of result.diagnostics) add(copyDiagnostic(entry));
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
if (diagnostics.length > 0) {
|
|
515
|
-
return { ok: false, diagnostics: Object.freeze(diagnostics) };
|
|
516
|
-
}
|
|
517
|
-
if (result === null || typeof result !== "object" || result.layer === void 0) {
|
|
518
|
-
return {
|
|
519
|
-
ok: false,
|
|
520
|
-
diagnostics: Object.freeze([
|
|
521
|
-
diagnostic(
|
|
522
|
-
"source.invalid-adapter-result",
|
|
523
|
-
"The source adapter did not return a declaration layer."
|
|
524
|
-
)
|
|
525
|
-
])
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
return validateLayerValue(result.layer, ownedPolicy);
|
|
432
|
+
const policyValidation = validateLayerValue(null, policy);
|
|
433
|
+
if (!policyValidation.ok && policyValidation.diagnostics.some((entry) => entry.code === "source.invalid-policy")) return policyValidation;
|
|
434
|
+
const ownedPolicy = frozenPolicy(policy);
|
|
435
|
+
const diagnostics = [];
|
|
436
|
+
const maxDiagnostics = diagnosticLimit(ownedPolicy);
|
|
437
|
+
let limited = false;
|
|
438
|
+
const add = (value) => {
|
|
439
|
+
if (limited) return;
|
|
440
|
+
if (diagnostics.length + 1 < maxDiagnostics) {
|
|
441
|
+
diagnostics.push(value);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
limited = true;
|
|
445
|
+
diagnostics.push(diagnostic("source.diagnostic-limit", "Additional source diagnostics were omitted."));
|
|
446
|
+
};
|
|
447
|
+
const context = Object.freeze({
|
|
448
|
+
policy: ownedPolicy,
|
|
449
|
+
limits: ownedPolicy.limits,
|
|
450
|
+
diagnose(code, message) {
|
|
451
|
+
add(copyDiagnostic({
|
|
452
|
+
code,
|
|
453
|
+
message
|
|
454
|
+
}));
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
const result = adapter.adapt(input, context);
|
|
458
|
+
if (result === null || typeof result !== "object") add(diagnostic("source.invalid-adapter-result", "The source adapter returned an invalid result."));
|
|
459
|
+
else if (result.diagnostics !== void 0) {
|
|
460
|
+
if (!Array.isArray(result.diagnostics)) add(diagnostic("source.invalid-adapter-result", "The source adapter returned an invalid result."));
|
|
461
|
+
else for (const entry of result.diagnostics) add(copyDiagnostic(entry));
|
|
462
|
+
}
|
|
463
|
+
if (diagnostics.length > 0) return {
|
|
464
|
+
ok: false,
|
|
465
|
+
diagnostics: Object.freeze(diagnostics)
|
|
466
|
+
};
|
|
467
|
+
if (result === null || typeof result !== "object" || result.layer === void 0) return {
|
|
468
|
+
ok: false,
|
|
469
|
+
diagnostics: Object.freeze([diagnostic("source.invalid-adapter-result", "The source adapter did not return a declaration layer.")])
|
|
470
|
+
};
|
|
471
|
+
return validateLayerValue(result.layer, ownedPolicy);
|
|
529
472
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
// src/runtime-source.ts
|
|
473
|
+
const parseResultAdapter = Object.freeze({ adapt(input) {
|
|
474
|
+
return input.ok ? { layer: input.value } : { diagnostics: input.diagnostics };
|
|
475
|
+
} });
|
|
476
|
+
//#endregion
|
|
477
|
+
//#region src/runtime-source.ts
|
|
537
478
|
function adaptationFailure(diagnostics) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
479
|
+
return Object.freeze({
|
|
480
|
+
status: "rejected",
|
|
481
|
+
diagnostics: Object.freeze(diagnostics.map((entry) => Object.freeze({
|
|
482
|
+
code: entry.code,
|
|
483
|
+
message: entry.message
|
|
484
|
+
})))
|
|
485
|
+
});
|
|
544
486
|
}
|
|
545
487
|
function createConfigRuntimeSource(id, fetchRaw, adapter, policy) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
});
|
|
488
|
+
return Object.freeze({
|
|
489
|
+
id,
|
|
490
|
+
async load(context) {
|
|
491
|
+
const adapted = adaptRawConfig(await fetchRaw(context), adapter, policy);
|
|
492
|
+
if (!adapted.ok) return adaptationFailure(adapted.diagnostics);
|
|
493
|
+
return adapted.value;
|
|
494
|
+
}
|
|
495
|
+
});
|
|
555
496
|
}
|
|
556
|
-
|
|
497
|
+
//#endregion
|
|
557
498
|
exports.adaptRawConfig = adaptRawConfig;
|
|
558
499
|
exports.createConfigRuntimeSource = createConfigRuntimeSource;
|
|
559
500
|
exports.parseJsonLayer = parseJsonLayer;
|
|
560
501
|
exports.parseResultAdapter = parseResultAdapter;
|
|
561
502
|
exports.parseYamlLayer = parseYamlLayer;
|
|
562
|
-
|
|
503
|
+
|
|
563
504
|
//# sourceMappingURL=index.cjs.map
|