1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import { Alias } from '../nodes/Alias.js';
- import { isNode, isPair, MAP, SEQ, isDocument } from '../nodes/identity.js';
- import { Scalar } from '../nodes/Scalar.js';
- const defaultTagPrefix = 'tag:yaml.org,2002:';
- function findTagObject(value, tagName, tags) {
- if (tagName) {
- const match = tags.filter(t => t.tag === tagName);
- const tagObj = match.find(t => !t.format) ?? match[0];
- if (!tagObj)
- throw new Error(`Tag ${tagName} not found`);
- return tagObj;
- }
- return tags.find(t => t.identify?.(value) && !t.format);
- }
- function createNode(value, tagName, ctx) {
- if (isDocument(value))
- value = value.contents;
- if (isNode(value))
- return value;
- if (isPair(value)) {
- const map = ctx.schema[MAP].createNode?.(ctx.schema, null, ctx);
- map.items.push(value);
- return map;
- }
- if (value instanceof String ||
- value instanceof Number ||
- value instanceof Boolean ||
- (typeof BigInt !== 'undefined' && value instanceof BigInt) // not supported everywhere
- ) {
- // https://tc39.es/ecma262/#sec-serializejsonproperty
- value = value.valueOf();
- }
- const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
- // Detect duplicate references to the same object & use Alias nodes for all
- // after first. The `ref` wrapper allows for circular references to resolve.
- let ref = undefined;
- if (aliasDuplicateObjects && value && typeof value === 'object') {
- ref = sourceObjects.get(value);
- if (ref) {
- if (!ref.anchor)
- ref.anchor = onAnchor(value);
- return new Alias(ref.anchor);
- }
- else {
- ref = { anchor: null, node: null };
- sourceObjects.set(value, ref);
- }
- }
- if (tagName?.startsWith('!!'))
- tagName = defaultTagPrefix + tagName.slice(2);
- let tagObj = findTagObject(value, tagName, schema.tags);
- if (!tagObj) {
- if (value && typeof value.toJSON === 'function') {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
- value = value.toJSON();
- }
- if (!value || typeof value !== 'object') {
- const node = new Scalar(value);
- if (ref)
- ref.node = node;
- return node;
- }
- tagObj =
- value instanceof Map
- ? schema[MAP]
- : Symbol.iterator in Object(value)
- ? schema[SEQ]
- : schema[MAP];
- }
- if (onTagObj) {
- onTagObj(tagObj);
- delete ctx.onTagObj;
- }
- const node = tagObj?.createNode
- ? tagObj.createNode(ctx.schema, value, ctx)
- : typeof tagObj?.nodeClass?.from === 'function'
- ? tagObj.nodeClass.from(ctx.schema, value, ctx)
- : new Scalar(value);
- if (tagName)
- node.tag = tagName;
- else if (!tagObj.default)
- node.tag = tagObj.tag;
- if (ref)
- ref.node = node;
- return node;
- }
- export { createNode };
|