1 | 'use strict';
|
2 |
|
3 | var identity = require('../nodes/identity.js');
|
4 | var Scalar = require('../nodes/Scalar.js');
|
5 | var resolveBlockScalar = require('./resolve-block-scalar.js');
|
6 | var resolveFlowScalar = require('./resolve-flow-scalar.js');
|
7 |
|
8 | function composeScalar(ctx, token, tagToken, onError) {
|
9 | const { value, type, comment, range } = token.type === 'block-scalar'
|
10 | ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError)
|
11 | : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
12 | const tagName = tagToken
|
13 | ? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
|
14 | : null;
|
15 | let tag;
|
16 | if (ctx.options.stringKeys && ctx.atKey) {
|
17 | tag = ctx.schema[identity.SCALAR];
|
18 | }
|
19 | else if (tagName)
|
20 | tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
|
21 | else if (token.type === 'scalar')
|
22 | tag = findScalarTagByTest(ctx, value, token, onError);
|
23 | else
|
24 | tag = ctx.schema[identity.SCALAR];
|
25 | let scalar;
|
26 | try {
|
27 | const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
|
28 | scalar = identity.isScalar(res) ? res : new Scalar.Scalar(res);
|
29 | }
|
30 | catch (error) {
|
31 | const msg = error instanceof Error ? error.message : String(error);
|
32 | onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg);
|
33 | scalar = new Scalar.Scalar(value);
|
34 | }
|
35 | scalar.range = range;
|
36 | scalar.source = value;
|
37 | if (type)
|
38 | scalar.type = type;
|
39 | if (tagName)
|
40 | scalar.tag = tagName;
|
41 | if (tag.format)
|
42 | scalar.format = tag.format;
|
43 | if (comment)
|
44 | scalar.comment = comment;
|
45 | return scalar;
|
46 | }
|
47 | function findScalarTagByName(schema, value, tagName, tagToken, onError) {
|
48 | if (tagName === '!')
|
49 | return schema[identity.SCALAR];
|
50 | const matchWithTest = [];
|
51 | for (const tag of schema.tags) {
|
52 | if (!tag.collection && tag.tag === tagName) {
|
53 | if (tag.default && tag.test)
|
54 | matchWithTest.push(tag);
|
55 | else
|
56 | return tag;
|
57 | }
|
58 | }
|
59 | for (const tag of matchWithTest)
|
60 | if (tag.test?.test(value))
|
61 | return tag;
|
62 | const kt = schema.knownTags[tagName];
|
63 | if (kt && !kt.collection) {
|
64 |
|
65 |
|
66 | schema.tags.push(Object.assign({}, kt, { default: false, test: undefined }));
|
67 | return kt;
|
68 | }
|
69 | onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
|
70 | return schema[identity.SCALAR];
|
71 | }
|
72 | function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
|
73 | const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) &&
|
74 | tag.test?.test(value)) || schema[identity.SCALAR];
|
75 | if (schema.compat) {
|
76 | const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ??
|
77 | schema[identity.SCALAR];
|
78 | if (tag.tag !== compat.tag) {
|
79 | const ts = directives.tagString(tag.tag);
|
80 | const cs = directives.tagString(compat.tag);
|
81 | const msg = `Value may be parsed as either ${ts} or ${cs}`;
|
82 | onError(token, 'TAG_RESOLVE_FAILED', msg, true);
|
83 | }
|
84 | }
|
85 | return tag;
|
86 | }
|
87 |
|
88 | exports.composeScalar = composeScalar;
|