@terraforge/terraform 0.0.23 → 0.0.24
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.d.mts +9 -2
- package/dist/index.mjs +222 -154
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
//#region src/plugin/schema.d.ts
|
|
2
2
|
|
|
3
|
+
type RootProperty = {
|
|
4
|
+
type: 'object';
|
|
5
|
+
version?: number;
|
|
6
|
+
description?: string;
|
|
7
|
+
properties: Record<string, Property>;
|
|
8
|
+
};
|
|
3
9
|
type Property = {
|
|
4
10
|
description?: string;
|
|
5
11
|
required?: boolean;
|
|
@@ -13,6 +19,7 @@ type Property = {
|
|
|
13
19
|
} | {
|
|
14
20
|
type: 'array' | 'record';
|
|
15
21
|
item: Property;
|
|
22
|
+
collectionKind?: 'list' | 'set';
|
|
16
23
|
} | {
|
|
17
24
|
type: 'object' | 'array-object';
|
|
18
25
|
properties: Record<string, Property>;
|
|
@@ -28,8 +35,8 @@ type State$1 = Record<string, unknown>;
|
|
|
28
35
|
type Plugin = Readonly<{
|
|
29
36
|
schema: () => {
|
|
30
37
|
provider: Property;
|
|
31
|
-
resources: Record<string,
|
|
32
|
-
dataSources: Record<string,
|
|
38
|
+
resources: Record<string, RootProperty>;
|
|
39
|
+
dataSources: Record<string, RootProperty>;
|
|
33
40
|
};
|
|
34
41
|
stop: () => Promise<void>;
|
|
35
42
|
configure: (config: State$1) => Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { camelCase, pascalCase, snakeCase } from "change-case";
|
|
2
2
|
import { ResourceNotFound, createDebugger, createMeta, nodeMetaSymbol } from "@terraforge/core";
|
|
3
|
+
import { pack, unpack } from "msgpackr";
|
|
3
4
|
import { credentials, loadPackageDefinition } from "@grpc/grpc-js";
|
|
4
5
|
import { fromJSON } from "@grpc/proto-loader";
|
|
5
6
|
import jszip from "jszip";
|
|
@@ -8,7 +9,6 @@ import { arch, homedir, platform } from "node:os";
|
|
|
8
9
|
import { dirname, join } from "node:path";
|
|
9
10
|
import { compare } from "semver";
|
|
10
11
|
import { spawn } from "node:child_process";
|
|
11
|
-
import { pack, unpack } from "msgpackr";
|
|
12
12
|
|
|
13
13
|
//#region src/type-gen.ts
|
|
14
14
|
const tab = (indent) => {
|
|
@@ -215,6 +215,215 @@ const generateValue = (prop, ctx) => {
|
|
|
215
215
|
throw new Error(`Unknown property type: ${prop.type}`);
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/plugin/version/util.ts
|
|
220
|
+
const stableStringify = (value) => {
|
|
221
|
+
return JSON.stringify(value, (_, item) => {
|
|
222
|
+
if (item !== null && item instanceof Object && !Array.isArray(item)) return Object.keys(item).sort().reduce((sorted, key) => {
|
|
223
|
+
sorted[key] = item[key];
|
|
224
|
+
return sorted;
|
|
225
|
+
}, {});
|
|
226
|
+
return item;
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
const sortStateValues = (values) => {
|
|
230
|
+
return [...values].sort((left, right) => {
|
|
231
|
+
const l = stableStringify(left);
|
|
232
|
+
const r = stableStringify(right);
|
|
233
|
+
if (l < r) return -1;
|
|
234
|
+
if (l > r) return 1;
|
|
235
|
+
return 0;
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
const encodeDynamicValue = (value) => {
|
|
239
|
+
return {
|
|
240
|
+
msgpack: pack(value),
|
|
241
|
+
json: value
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
const decodeDynamicValue = (value) => {
|
|
245
|
+
return unpack(value.msgpack);
|
|
246
|
+
};
|
|
247
|
+
const getResourceSchema = (resources, type) => {
|
|
248
|
+
const resource = resources[type];
|
|
249
|
+
if (!resource) throw new Error(`Unknown resource type: ${type}`);
|
|
250
|
+
return resource;
|
|
251
|
+
};
|
|
252
|
+
const formatAttributePath = (state) => {
|
|
253
|
+
if (!state) return [];
|
|
254
|
+
return state.map((item) => {
|
|
255
|
+
if (!item.steps) throw new Error("AttributePath should always have steps");
|
|
256
|
+
return item.steps.map((attr) => {
|
|
257
|
+
if ("attributeName" in attr) return attr.attributeName;
|
|
258
|
+
if ("elementKeyString" in attr) return attr.elementKeyString;
|
|
259
|
+
if ("elementKeyInt" in attr) return attr.elementKeyInt;
|
|
260
|
+
throw new Error("AttributePath step should always have an element");
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
const getNestedValue = (obj, path) => {
|
|
265
|
+
let current = obj;
|
|
266
|
+
for (const key of path) {
|
|
267
|
+
if (current === null || current === void 0) return current;
|
|
268
|
+
if (Array.isArray(current)) current = current[key];
|
|
269
|
+
else if (typeof current === "object") current = current[key];
|
|
270
|
+
else return;
|
|
271
|
+
}
|
|
272
|
+
return current;
|
|
273
|
+
};
|
|
274
|
+
const filterRequiresReplace = (paths, priorState, proposedState) => {
|
|
275
|
+
return paths.filter((path) => {
|
|
276
|
+
const priorValue = getNestedValue(priorState, path);
|
|
277
|
+
const proposedValue = getNestedValue(proposedState, path);
|
|
278
|
+
return JSON.stringify(priorValue) !== JSON.stringify(proposedValue);
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
var IncorrectType = class extends TypeError {
|
|
282
|
+
constructor(type, path) {
|
|
283
|
+
super(`${path.join(".")} should be a ${type}`);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const isEmptyOutputValue = (value) => {
|
|
287
|
+
if (value === null || typeof value === "undefined") return true;
|
|
288
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
289
|
+
if (typeof value === "object") return Object.keys(value).length === 0;
|
|
290
|
+
return false;
|
|
291
|
+
};
|
|
292
|
+
const shouldOmitOutputValue = (schema, value) => {
|
|
293
|
+
if (!(schema.optional || schema.computed)) return false;
|
|
294
|
+
return isEmptyOutputValue(value);
|
|
295
|
+
};
|
|
296
|
+
const hasInputValue = (value) => typeof value !== "undefined";
|
|
297
|
+
const shouldIncludeFieldForComparison = (schema, inputValue) => {
|
|
298
|
+
return schema.required || hasInputValue(inputValue);
|
|
299
|
+
};
|
|
300
|
+
const normalizeStateForComparison = (schema, state, inputState) => {
|
|
301
|
+
if (!shouldIncludeFieldForComparison(schema, inputState)) return;
|
|
302
|
+
if (state === null || typeof state === "undefined") return state;
|
|
303
|
+
if (schema.type === "array") {
|
|
304
|
+
if (!Array.isArray(state)) return state;
|
|
305
|
+
const normalized = state.map((item, index) => {
|
|
306
|
+
const inputItem = Array.isArray(inputState) ? inputState[index] : void 0;
|
|
307
|
+
return normalizeStateForComparison(schema.item, item, inputItem);
|
|
308
|
+
});
|
|
309
|
+
return schema.collectionKind === "set" ? sortStateValues(normalized) : normalized;
|
|
310
|
+
}
|
|
311
|
+
if (schema.type === "record") {
|
|
312
|
+
if (typeof state !== "object" || state === null) return state;
|
|
313
|
+
return Object.fromEntries(Object.entries(state).map(([key, value]) => {
|
|
314
|
+
const inputValue = inputState && typeof inputState === "object" ? inputState[key] : void 0;
|
|
315
|
+
return [key, normalizeStateForComparison(schema.item, value, inputValue)];
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
if (schema.type === "object") {
|
|
319
|
+
if (typeof state !== "object" || state === null) return state;
|
|
320
|
+
return Object.fromEntries(Object.entries(schema.properties).flatMap(([key, prop]) => {
|
|
321
|
+
const stateValue = state[camelCase(key)];
|
|
322
|
+
const normalized = normalizeStateForComparison(prop, stateValue, inputState && typeof inputState === "object" ? inputState[camelCase(key)] : void 0);
|
|
323
|
+
if (typeof normalized === "undefined") return [];
|
|
324
|
+
return [[camelCase(key), normalized]];
|
|
325
|
+
}));
|
|
326
|
+
}
|
|
327
|
+
if (schema.type === "array-object") {
|
|
328
|
+
if (typeof state !== "object" || state === null) return state;
|
|
329
|
+
return Object.fromEntries(Object.entries(schema.properties).flatMap(([key, prop]) => {
|
|
330
|
+
const stateValue = state[camelCase(key)];
|
|
331
|
+
const normalized = normalizeStateForComparison(prop, stateValue, inputState && typeof inputState === "object" ? inputState[camelCase(key)] : void 0);
|
|
332
|
+
if (typeof normalized === "undefined") return [];
|
|
333
|
+
return [[camelCase(key), normalized]];
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
return state;
|
|
337
|
+
};
|
|
338
|
+
const formatInputState = (schema, state, includeSchemaFields = true, path = []) => {
|
|
339
|
+
if (state === null) return null;
|
|
340
|
+
if (typeof state === "undefined") return null;
|
|
341
|
+
if (schema.type === "unknown") return state;
|
|
342
|
+
if (schema.type === "string") {
|
|
343
|
+
if (typeof state === "string") return state;
|
|
344
|
+
throw new IncorrectType(schema.type, path);
|
|
345
|
+
}
|
|
346
|
+
if (schema.type === "number") {
|
|
347
|
+
if (typeof state === "number") return state;
|
|
348
|
+
throw new IncorrectType(schema.type, path);
|
|
349
|
+
}
|
|
350
|
+
if (schema.type === "boolean") {
|
|
351
|
+
if (typeof state === "boolean") return state;
|
|
352
|
+
throw new IncorrectType(schema.type, path);
|
|
353
|
+
}
|
|
354
|
+
if (schema.type === "array") {
|
|
355
|
+
if (Array.isArray(state)) return state.map((item, i) => formatInputState(schema.item, item, includeSchemaFields, [...path, i]));
|
|
356
|
+
throw new IncorrectType(schema.type, path);
|
|
357
|
+
}
|
|
358
|
+
if (schema.type === "record") {
|
|
359
|
+
if (typeof state === "object" && state !== null) {
|
|
360
|
+
const record = {};
|
|
361
|
+
for (const [key, value] of Object.entries(state)) record[key] = formatInputState(schema.item, value, includeSchemaFields, [...path, key]);
|
|
362
|
+
return record;
|
|
363
|
+
}
|
|
364
|
+
throw new IncorrectType(schema.type, path);
|
|
365
|
+
}
|
|
366
|
+
if (schema.type === "object" || schema.type === "array-object") {
|
|
367
|
+
if (typeof state === "object" && state !== null) {
|
|
368
|
+
const object = {};
|
|
369
|
+
if (includeSchemaFields) for (const [key, prop] of Object.entries(schema.properties)) {
|
|
370
|
+
const value = state[camelCase(key)];
|
|
371
|
+
object[key] = formatInputState(prop, value, true, [...path, key]);
|
|
372
|
+
}
|
|
373
|
+
else for (const [key, value] of Object.entries(state)) {
|
|
374
|
+
const prop = schema.properties[snakeCase(key)];
|
|
375
|
+
if (prop) object[key] = formatInputState(prop, value, false, [...path, key]);
|
|
376
|
+
}
|
|
377
|
+
if (schema.type === "array-object") return [object];
|
|
378
|
+
return object;
|
|
379
|
+
}
|
|
380
|
+
throw new IncorrectType(schema.type, path);
|
|
381
|
+
}
|
|
382
|
+
throw new Error(`Unknown schema type: ${schema.type}`);
|
|
383
|
+
};
|
|
384
|
+
const formatOutputState = (schema, state, path = []) => {
|
|
385
|
+
if (state === null || state === void 0) return null;
|
|
386
|
+
if (schema.type === "array") {
|
|
387
|
+
if (Array.isArray(state)) return state.map((item, i) => formatOutputState(schema.item, item, [...path, i]));
|
|
388
|
+
throw new IncorrectType(schema.type, path);
|
|
389
|
+
}
|
|
390
|
+
if (schema.type === "record") {
|
|
391
|
+
if (typeof state === "object" && state !== null) {
|
|
392
|
+
const record = {};
|
|
393
|
+
for (const [key, value] of Object.entries(state)) record[key] = formatOutputState(schema.item, value, [...path, key]);
|
|
394
|
+
return record;
|
|
395
|
+
}
|
|
396
|
+
throw new IncorrectType(schema.type, path);
|
|
397
|
+
}
|
|
398
|
+
if (schema.type === "object") {
|
|
399
|
+
if (typeof state === "object" && state !== null) {
|
|
400
|
+
const object = {};
|
|
401
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
402
|
+
const value = state[key];
|
|
403
|
+
const formatted = formatOutputState(prop, value, [...path, key]);
|
|
404
|
+
if (shouldOmitOutputValue(prop, formatted)) continue;
|
|
405
|
+
object[camelCase(key)] = formatted;
|
|
406
|
+
}
|
|
407
|
+
return object;
|
|
408
|
+
}
|
|
409
|
+
throw new IncorrectType(schema.type, path);
|
|
410
|
+
}
|
|
411
|
+
if (schema.type === "array-object") {
|
|
412
|
+
if (Array.isArray(state)) if (state.length === 1) {
|
|
413
|
+
const object = {};
|
|
414
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
415
|
+
const value = state[0][key];
|
|
416
|
+
const formatted = formatOutputState(prop, value, [...path, key]);
|
|
417
|
+
if (shouldOmitOutputValue(prop, formatted)) continue;
|
|
418
|
+
object[camelCase(key)] = formatted;
|
|
419
|
+
}
|
|
420
|
+
return object;
|
|
421
|
+
} else return null;
|
|
422
|
+
throw new IncorrectType(schema.type, path);
|
|
423
|
+
}
|
|
424
|
+
return state;
|
|
425
|
+
};
|
|
426
|
+
|
|
218
427
|
//#endregion
|
|
219
428
|
//#region src/provider.ts
|
|
220
429
|
const areStatesEqual = (left, right) => {
|
|
@@ -317,6 +526,7 @@ var TerraformProvider = class {
|
|
|
317
526
|
}
|
|
318
527
|
async refreshResource({ type, priorInputState, priorOutputState }) {
|
|
319
528
|
const plugin = await this.configure();
|
|
529
|
+
const schema = getResourceSchema(plugin.schema().resources, type);
|
|
320
530
|
const refreshedState = await plugin.readResource(type, priorOutputState);
|
|
321
531
|
if (!refreshedState) return { kind: "deleted" };
|
|
322
532
|
const mergedState = {
|
|
@@ -324,7 +534,9 @@ var TerraformProvider = class {
|
|
|
324
534
|
...priorInputState
|
|
325
535
|
};
|
|
326
536
|
const { requiresReplace, plannedState } = await plugin.planResourceChange(type, refreshedState, mergedState, priorInputState);
|
|
327
|
-
|
|
537
|
+
const normalizedPlannedState = normalizeStateForComparison(schema, plannedState, priorInputState);
|
|
538
|
+
const normalizedRefreshedState = normalizeStateForComparison(schema, refreshedState, priorInputState);
|
|
539
|
+
if (requiresReplace.length === 0 && areStatesEqual(normalizedPlannedState, normalizedRefreshedState)) return {
|
|
328
540
|
kind: "unchanged",
|
|
329
541
|
state: refreshedState
|
|
330
542
|
};
|
|
@@ -333,6 +545,8 @@ var TerraformProvider = class {
|
|
|
333
545
|
console.log("PRIOR_OUTPUT_STATE", priorOutputState);
|
|
334
546
|
console.log("PLANNED_STATE", plannedState);
|
|
335
547
|
console.log("REFRESH_STATE", refreshedState);
|
|
548
|
+
console.log("NORMALIZED_PLANNED_STATE", normalizedPlannedState);
|
|
549
|
+
console.log("NORMALIZED_REFRESH_STATE", normalizedRefreshedState);
|
|
336
550
|
console.log("REQUIRES_REPLACE", requiresReplace);
|
|
337
551
|
return {
|
|
338
552
|
kind: "updated",
|
|
@@ -1892,7 +2106,8 @@ const parseNestedBlock = (block) => {
|
|
|
1892
2106
|
if (type === "array" || type === "record") return {
|
|
1893
2107
|
...prop,
|
|
1894
2108
|
type,
|
|
1895
|
-
item
|
|
2109
|
+
item,
|
|
2110
|
+
collectionKind: block.nesting === NestingMode.SET ? "set" : "list"
|
|
1896
2111
|
};
|
|
1897
2112
|
if (type === "array-object") return {
|
|
1898
2113
|
...prop,
|
|
@@ -1939,12 +2154,14 @@ const parseAttribute = (attr) => {
|
|
|
1939
2154
|
};
|
|
1940
2155
|
const parseAttributeType = (item) => {
|
|
1941
2156
|
if (Array.isArray(item)) {
|
|
1942
|
-
const
|
|
2157
|
+
const sourceType = item[0];
|
|
2158
|
+
const type$1 = parseType(sourceType);
|
|
1943
2159
|
if (type$1 === "array" || type$1 === "record" && item) {
|
|
1944
2160
|
const record = item[1];
|
|
1945
2161
|
return {
|
|
1946
2162
|
type: type$1,
|
|
1947
|
-
item: parseAttributeType(record)
|
|
2163
|
+
item: parseAttributeType(record),
|
|
2164
|
+
collectionKind: sourceType === "set" ? "set" : "list"
|
|
1948
2165
|
};
|
|
1949
2166
|
}
|
|
1950
2167
|
if (type$1 === "object") {
|
|
@@ -1981,155 +2198,6 @@ const parseType = (type) => {
|
|
|
1981
2198
|
throw new Error(`Invalid type: ${type}`);
|
|
1982
2199
|
};
|
|
1983
2200
|
|
|
1984
|
-
//#endregion
|
|
1985
|
-
//#region src/plugin/version/util.ts
|
|
1986
|
-
const encodeDynamicValue = (value) => {
|
|
1987
|
-
return {
|
|
1988
|
-
msgpack: pack(value),
|
|
1989
|
-
json: value
|
|
1990
|
-
};
|
|
1991
|
-
};
|
|
1992
|
-
const decodeDynamicValue = (value) => {
|
|
1993
|
-
return unpack(value.msgpack);
|
|
1994
|
-
};
|
|
1995
|
-
const getResourceSchema = (resources, type) => {
|
|
1996
|
-
const resource = resources[type];
|
|
1997
|
-
if (!resource) throw new Error(`Unknown resource type: ${type}`);
|
|
1998
|
-
return resource;
|
|
1999
|
-
};
|
|
2000
|
-
const formatAttributePath = (state) => {
|
|
2001
|
-
if (!state) return [];
|
|
2002
|
-
return state.map((item) => {
|
|
2003
|
-
if (!item.steps) throw new Error("AttributePath should always have steps");
|
|
2004
|
-
return item.steps.map((attr) => {
|
|
2005
|
-
if ("attributeName" in attr) return attr.attributeName;
|
|
2006
|
-
if ("elementKeyString" in attr) return attr.elementKeyString;
|
|
2007
|
-
if ("elementKeyInt" in attr) return attr.elementKeyInt;
|
|
2008
|
-
throw new Error("AttributePath step should always have an element");
|
|
2009
|
-
});
|
|
2010
|
-
});
|
|
2011
|
-
};
|
|
2012
|
-
const getNestedValue = (obj, path) => {
|
|
2013
|
-
let current = obj;
|
|
2014
|
-
for (const key of path) {
|
|
2015
|
-
if (current === null || current === void 0) return current;
|
|
2016
|
-
if (Array.isArray(current)) current = current[key];
|
|
2017
|
-
else if (typeof current === "object") current = current[key];
|
|
2018
|
-
else return;
|
|
2019
|
-
}
|
|
2020
|
-
return current;
|
|
2021
|
-
};
|
|
2022
|
-
const filterRequiresReplace = (paths, priorState, proposedState) => {
|
|
2023
|
-
return paths.filter((path) => {
|
|
2024
|
-
const priorValue = getNestedValue(priorState, path);
|
|
2025
|
-
const proposedValue = getNestedValue(proposedState, path);
|
|
2026
|
-
return JSON.stringify(priorValue) !== JSON.stringify(proposedValue);
|
|
2027
|
-
});
|
|
2028
|
-
};
|
|
2029
|
-
var IncorrectType = class extends TypeError {
|
|
2030
|
-
constructor(type, path) {
|
|
2031
|
-
super(`${path.join(".")} should be a ${type}`);
|
|
2032
|
-
}
|
|
2033
|
-
};
|
|
2034
|
-
const isEmptyOutputValue = (value) => {
|
|
2035
|
-
if (value === null || typeof value === "undefined") return true;
|
|
2036
|
-
if (Array.isArray(value)) return value.length === 0;
|
|
2037
|
-
if (typeof value === "object") return Object.keys(value).length === 0;
|
|
2038
|
-
return false;
|
|
2039
|
-
};
|
|
2040
|
-
const shouldOmitOutputValue = (schema, value) => {
|
|
2041
|
-
if (!(schema.optional || schema.computed)) return false;
|
|
2042
|
-
return isEmptyOutputValue(value);
|
|
2043
|
-
};
|
|
2044
|
-
const formatInputState = (schema, state, includeSchemaFields = true, path = []) => {
|
|
2045
|
-
if (state === null) return null;
|
|
2046
|
-
if (typeof state === "undefined") return null;
|
|
2047
|
-
if (schema.type === "unknown") return state;
|
|
2048
|
-
if (schema.type === "string") {
|
|
2049
|
-
if (typeof state === "string") return state;
|
|
2050
|
-
throw new IncorrectType(schema.type, path);
|
|
2051
|
-
}
|
|
2052
|
-
if (schema.type === "number") {
|
|
2053
|
-
if (typeof state === "number") return state;
|
|
2054
|
-
throw new IncorrectType(schema.type, path);
|
|
2055
|
-
}
|
|
2056
|
-
if (schema.type === "boolean") {
|
|
2057
|
-
if (typeof state === "boolean") return state;
|
|
2058
|
-
throw new IncorrectType(schema.type, path);
|
|
2059
|
-
}
|
|
2060
|
-
if (schema.type === "array") {
|
|
2061
|
-
if (Array.isArray(state)) return state.map((item, i) => formatInputState(schema.item, item, includeSchemaFields, [...path, i]));
|
|
2062
|
-
throw new IncorrectType(schema.type, path);
|
|
2063
|
-
}
|
|
2064
|
-
if (schema.type === "record") {
|
|
2065
|
-
if (typeof state === "object" && state !== null) {
|
|
2066
|
-
const record = {};
|
|
2067
|
-
for (const [key, value] of Object.entries(state)) record[key] = formatInputState(schema.item, value, includeSchemaFields, [...path, key]);
|
|
2068
|
-
return record;
|
|
2069
|
-
}
|
|
2070
|
-
throw new IncorrectType(schema.type, path);
|
|
2071
|
-
}
|
|
2072
|
-
if (schema.type === "object" || schema.type === "array-object") {
|
|
2073
|
-
if (typeof state === "object" && state !== null) {
|
|
2074
|
-
const object = {};
|
|
2075
|
-
if (includeSchemaFields) for (const [key, prop] of Object.entries(schema.properties)) {
|
|
2076
|
-
const value = state[camelCase(key)];
|
|
2077
|
-
object[key] = formatInputState(prop, value, true, [...path, key]);
|
|
2078
|
-
}
|
|
2079
|
-
else for (const [key, value] of Object.entries(state)) {
|
|
2080
|
-
const prop = schema.properties[snakeCase(key)];
|
|
2081
|
-
if (prop) object[key] = formatInputState(prop, value, false, [...path, key]);
|
|
2082
|
-
}
|
|
2083
|
-
if (schema.type === "array-object") return [object];
|
|
2084
|
-
return object;
|
|
2085
|
-
}
|
|
2086
|
-
throw new IncorrectType(schema.type, path);
|
|
2087
|
-
}
|
|
2088
|
-
throw new Error(`Unknown schema type: ${schema.type}`);
|
|
2089
|
-
};
|
|
2090
|
-
const formatOutputState = (schema, state, path = []) => {
|
|
2091
|
-
if (state === null || state === void 0) return null;
|
|
2092
|
-
if (schema.type === "array") {
|
|
2093
|
-
if (Array.isArray(state)) return state.map((item, i) => formatOutputState(schema.item, item, [...path, i]));
|
|
2094
|
-
throw new IncorrectType(schema.type, path);
|
|
2095
|
-
}
|
|
2096
|
-
if (schema.type === "record") {
|
|
2097
|
-
if (typeof state === "object" && state !== null) {
|
|
2098
|
-
const record = {};
|
|
2099
|
-
for (const [key, value] of Object.entries(state)) record[key] = formatOutputState(schema.item, value, [...path, key]);
|
|
2100
|
-
return record;
|
|
2101
|
-
}
|
|
2102
|
-
throw new IncorrectType(schema.type, path);
|
|
2103
|
-
}
|
|
2104
|
-
if (schema.type === "object") {
|
|
2105
|
-
if (typeof state === "object" && state !== null) {
|
|
2106
|
-
const object = {};
|
|
2107
|
-
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
2108
|
-
const value = state[key];
|
|
2109
|
-
const formatted = formatOutputState(prop, value, [...path, key]);
|
|
2110
|
-
if (shouldOmitOutputValue(prop, formatted)) continue;
|
|
2111
|
-
object[camelCase(key)] = formatted;
|
|
2112
|
-
}
|
|
2113
|
-
return object;
|
|
2114
|
-
}
|
|
2115
|
-
throw new IncorrectType(schema.type, path);
|
|
2116
|
-
}
|
|
2117
|
-
if (schema.type === "array-object") {
|
|
2118
|
-
if (Array.isArray(state)) if (state.length === 1) {
|
|
2119
|
-
const object = {};
|
|
2120
|
-
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
2121
|
-
const value = state[0][key];
|
|
2122
|
-
const formatted = formatOutputState(prop, value, [...path, key]);
|
|
2123
|
-
if (shouldOmitOutputValue(prop, formatted)) continue;
|
|
2124
|
-
object[camelCase(key)] = formatted;
|
|
2125
|
-
}
|
|
2126
|
-
return object;
|
|
2127
|
-
} else return null;
|
|
2128
|
-
throw new IncorrectType(schema.type, path);
|
|
2129
|
-
}
|
|
2130
|
-
return state;
|
|
2131
|
-
};
|
|
2132
|
-
|
|
2133
2201
|
//#endregion
|
|
2134
2202
|
//#region src/plugin/version/5.ts
|
|
2135
2203
|
const createPlugin5 = async ({ server, client }) => {
|