ng-form-foundry-transformers 0.4.1 → 0.5.1
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 +27 -4
- package/dist/core/infer.d.ts +3 -2
- package/dist/core/infer.js +7 -4
- package/dist/core/merge-inferred.d.ts +20 -0
- package/dist/core/merge-inferred.js +46 -0
- package/dist/core/schema-keys.d.ts +33 -0
- package/dist/core/schema-keys.js +57 -0
- package/dist/core/schema.d.ts +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/transformers/json/json-transformer.d.ts +35 -7
- package/dist/transformers/json/json-transformer.js +75 -11
- package/dist/transformers/libconfig/index.d.ts +1 -1
- package/dist/transformers/libconfig/index.js +1 -2
- package/dist/transformers/libconfig/libconfig-transformer.d.ts +29 -5
- package/dist/transformers/libconfig/libconfig-transformer.js +27 -19
- package/dist/transformers/libconfig/revert.d.ts +14 -2
- package/dist/transformers/libconfig/revert.js +30 -13
- package/dist/transformers/libconfig/schema.d.ts +11 -0
- package/dist/transformers/libconfig/schema.js +85 -5
- package/dist/transformers/yaml/index.d.ts +1 -1
- package/dist/transformers/yaml/revert.d.ts +8 -1
- package/dist/transformers/yaml/revert.js +43 -11
- package/dist/transformers/yaml/yaml-transformer.d.ts +32 -5
- package/dist/transformers/yaml/yaml-transformer.js +88 -8
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ const yaml_1 = require("yaml");
|
|
|
5
5
|
const thesaurus_1 = require("../../core/thesaurus");
|
|
6
6
|
const infer_1 = require("../../core/infer");
|
|
7
7
|
const json_schema_1 = require("../../core/json-schema");
|
|
8
|
+
const merge_inferred_1 = require("../../core/merge-inferred");
|
|
8
9
|
const bigint_1 = require("../../core/bigint");
|
|
9
10
|
const revert_1 = require("./revert");
|
|
10
11
|
/**
|
|
@@ -13,8 +14,9 @@ const revert_1 = require("./revert");
|
|
|
13
14
|
* preserves comments, key order, and formatting by applying edits onto the parsed
|
|
14
15
|
* document (see {@link applyValueToDocument}).
|
|
15
16
|
*
|
|
16
|
-
* The `binding` it round-trips is
|
|
17
|
-
* it before applying, so a single `toSchema` result can serve
|
|
17
|
+
* The `binding` it round-trips is a {@link YamlBinding}; `toSource` clones the
|
|
18
|
+
* document inside it before applying, so a single `toSchema` result can serve
|
|
19
|
+
* many edits.
|
|
18
20
|
*
|
|
19
21
|
* With a JSON Schema in {@link YamlOptions}, the form is schema-driven; without
|
|
20
22
|
* one it is inferred from the data.
|
|
@@ -27,20 +29,97 @@ exports.yamlTransformer = {
|
|
|
27
29
|
// out-of-range integers become strings there (safe ones become plain numbers).
|
|
28
30
|
const doc = (0, yaml_1.parseDocument)(source, { intAsBigInt: true });
|
|
29
31
|
const data = (normalizeBigInts(doc.toJS()) ?? {});
|
|
30
|
-
const
|
|
32
|
+
const unknownKeys = options?.unknownKeys ?? 'preserve';
|
|
33
|
+
const fromJsonSchema = options?.schema
|
|
31
34
|
? (0, json_schema_1.jsonSchemaToNodeGroup)(options.schema, options.rootName, options.schemaOptions)
|
|
32
|
-
:
|
|
35
|
+
: undefined;
|
|
36
|
+
const schema = fromJsonSchema && unknownKeys === 'edit'
|
|
37
|
+
? (0, merge_inferred_1.mergeInferred)(fromJsonSchema, (0, infer_1.inferNodeGroup)(data, options?.rootName))
|
|
38
|
+
: fromJsonSchema ?? (0, infer_1.inferNodeGroup)(data, options?.rootName);
|
|
39
|
+
// Inferred leaves (the whole schema, or the uncovered slice under 'edit')
|
|
40
|
+
// pick up the document's hex/octal presentation.
|
|
41
|
+
if ((!fromJsonSchema || unknownKeys === 'edit') && doc.contents)
|
|
42
|
+
annotateRadix(doc.contents, schema);
|
|
33
43
|
const labeled = options?.thesaurus ? (0, thesaurus_1.applyThesaurus)(schema, options.thesaurus) : schema;
|
|
34
|
-
return {
|
|
44
|
+
return {
|
|
45
|
+
schema: labeled,
|
|
46
|
+
// 'preserve' gates the revert on the JSON Schema's NodeGroup; 'edit' on
|
|
47
|
+
// the merged one (schema-born ≈ everything, but keys no form field can
|
|
48
|
+
// carry stay protected); 'drop' and inferred mode leave the value
|
|
49
|
+
// authoritative for the whole document.
|
|
50
|
+
binding: { doc, schema: fromJsonSchema && unknownKeys !== 'drop' ? schema : undefined },
|
|
51
|
+
initialValue: data,
|
|
52
|
+
};
|
|
35
53
|
},
|
|
36
54
|
toSource(value, binding) {
|
|
37
|
-
const doc = binding.clone();
|
|
38
|
-
(0, revert_1.applyValueToDocument)(doc, value);
|
|
55
|
+
const doc = binding.doc.clone();
|
|
56
|
+
(0, revert_1.applyValueToDocument)(doc, value, binding.schema);
|
|
39
57
|
return String(doc);
|
|
40
58
|
},
|
|
41
59
|
// `satisfies` verifies conformance to the catalog contract while keeping the
|
|
42
60
|
// concrete sync return types, so direct callers need no `await`.
|
|
43
61
|
};
|
|
62
|
+
const RADIX_BY_FORMAT = { BIN: 2, OCT: 8, HEX: 16 };
|
|
63
|
+
/**
|
|
64
|
+
* Copy non-decimal integer presentation (`0x`/`0o`/`0b` literals) from the
|
|
65
|
+
* parsed document onto the inferred schema as leaf/leafList `radix` display
|
|
66
|
+
* hints — the plain-data inference cannot see them, because `toJS()` drops the
|
|
67
|
+
* scalar format. The revert needs nothing: scalars are mutated in place, so an
|
|
68
|
+
* edited value re-emits in its literal's own base. Across group-list items the
|
|
69
|
+
* first non-decimal occurrence wins — one shared item schema cannot vary the
|
|
70
|
+
* display per item. Schema-driven mode is untouched (JSON Schema has no radix
|
|
71
|
+
* vocabulary).
|
|
72
|
+
*/
|
|
73
|
+
function annotateRadix(node, schema) {
|
|
74
|
+
switch (schema.kind) {
|
|
75
|
+
case 'leaf': {
|
|
76
|
+
const radix = scalarRadix(node);
|
|
77
|
+
if (radix && !schema.radix)
|
|
78
|
+
schema.radix = radix;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
case 'leafList': {
|
|
82
|
+
if (!(0, yaml_1.isSeq)(node) || schema.radix)
|
|
83
|
+
return;
|
|
84
|
+
const radixes = node.items.map(scalarRadix);
|
|
85
|
+
if (radixes[0] && radixes.every((r) => r === radixes[0]))
|
|
86
|
+
schema.radix = radixes[0];
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
case 'nodeGroup': {
|
|
90
|
+
if (!(0, yaml_1.isMap)(node))
|
|
91
|
+
return;
|
|
92
|
+
for (const pair of node.items) {
|
|
93
|
+
const child = schema.children[pairKey(pair.key)];
|
|
94
|
+
if (child)
|
|
95
|
+
annotateRadix(pair.value, child);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
case 'nodeGroupList': {
|
|
100
|
+
if (!(0, yaml_1.isSeq)(node))
|
|
101
|
+
return;
|
|
102
|
+
for (const item of node.items)
|
|
103
|
+
annotateRadix(item, schema.type);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
return; // choice/map never come out of plain-data inference
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** The display radix of a non-decimal integer scalar node, else undefined. */
|
|
111
|
+
function scalarRadix(node) {
|
|
112
|
+
if (!(0, yaml_1.isScalar)(node))
|
|
113
|
+
return undefined;
|
|
114
|
+
if (typeof node.value !== 'number' && typeof node.value !== 'bigint')
|
|
115
|
+
return undefined;
|
|
116
|
+
return RADIX_BY_FORMAT[node.format ?? ''];
|
|
117
|
+
}
|
|
118
|
+
/** The string a key node takes as a JS object key, matching `doc.toJS()`. */
|
|
119
|
+
function pairKey(key) {
|
|
120
|
+
const v = (0, yaml_1.isScalar)(key) ? key.value : key;
|
|
121
|
+
return v == null ? '' : String(v);
|
|
122
|
+
}
|
|
44
123
|
/**
|
|
45
124
|
* Replace every BigInt from an `intAsBigInt` parse with a form-value scalar: a
|
|
46
125
|
* plain `number` when it fits the safe range, otherwise its decimal string (so
|
|
@@ -52,7 +131,8 @@ function normalizeBigInts(value) {
|
|
|
52
131
|
if (Array.isArray(value))
|
|
53
132
|
return value.map(normalizeBigInts);
|
|
54
133
|
if (value && typeof value === 'object') {
|
|
55
|
-
|
|
134
|
+
// Null prototype: a `__proto__` document key must stay a data key.
|
|
135
|
+
const out = Object.create(null);
|
|
56
136
|
for (const key of Object.keys(value))
|
|
57
137
|
out[key] = normalizeBigInts(value[key]);
|
|
58
138
|
return out;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ng-form-foundry-transformers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Framework-agnostic Node + TypeScript catalog of source-format transformers: turn a YANG model (and more) into an ng-form-foundry schema and revert the edited form value back to the source format.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ng-form-foundry",
|