diff --git a/dist/index.js b/dist/index.js index 4f117848..f44b8894 100644 --- a/dist/index.js +++ b/dist/index.js @@ -33428,6 +33428,7 @@ function composeDoc(options, directives, { offset, start, value, end }, onError) const opts = Object.assign({ _directives: directives }, options); const doc = new Document.Document(undefined, opts); const ctx = { + atKey: false, atRoot: true, directives: doc.directives, options: doc.options, @@ -33472,6 +33473,7 @@ exports.composeDoc = composeDoc; var Alias = __nccwpck_require__(4065); +var identity = __nccwpck_require__(1127); var composeCollection = __nccwpck_require__(7349); var composeScalar = __nccwpck_require__(5413); var resolveEnd = __nccwpck_require__(7788); @@ -33479,6 +33481,7 @@ var utilEmptyScalarPosition = __nccwpck_require__(2599); const CN = { composeNode, composeEmptyNode }; function composeNode(ctx, token, props, onError) { + const atKey = ctx.atKey; const { spaceBefore, comment, anchor, tag } = props; let node; let isSrcToken = true; @@ -33514,6 +33517,14 @@ function composeNode(ctx, token, props, onError) { } if (anchor && node.anchor === '') onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string'); + if (atKey && + ctx.options.stringKeys && + (!identity.isScalar(node) || + typeof node.value !== 'string' || + (node.tag && node.tag !== 'tag:yaml.org,2002:str'))) { + const msg = 'With stringKeys, all keys must be strings'; + onError(tag ?? token, 'NON_STRING_KEY', msg); + } if (spaceBefore) node.spaceBefore = true; if (comment) { @@ -33586,11 +33597,16 @@ function composeScalar(ctx, token, tagToken, onError) { const tagName = tagToken ? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg)) : null; - const tag = tagToken && tagName - ? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError) - : token.type === 'scalar' - ? findScalarTagByTest(ctx, value, token, onError) - : ctx.schema[identity.SCALAR]; + let tag; + if (ctx.options.stringKeys && ctx.atKey) { + tag = ctx.schema[identity.SCALAR]; + } + else if (tagName) + tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError); + else if (token.type === 'scalar') + tag = findScalarTagByTest(ctx, value, token, onError); + else + tag = ctx.schema[identity.SCALAR]; let scalar; try { const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options); @@ -33638,8 +33654,9 @@ function findScalarTagByName(schema, value, tagName, tagToken, onError) { onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str'); return schema[identity.SCALAR]; } -function findScalarTagByTest({ directives, schema }, value, token, onError) { - const tag = schema.tags.find(tag => tag.default && tag.test?.test(value)) || schema[identity.SCALAR]; +function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) { + const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) && + tag.test?.test(value)) || schema[identity.SCALAR]; if (schema.compat) { const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ?? schema[identity.SCALAR]; @@ -33945,12 +33962,14 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, ta onError(offset, 'BAD_INDENT', startColMsg); } // key value + ctx.atKey = true; const keyStart = keyProps.end; const keyNode = key ? composeNode(ctx, key, keyProps, onError) : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError); if (ctx.schema.compat) utilFlowIndentCheck.flowIndentCheck(bm.indent, key, onError); + ctx.atKey = false; if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode)) onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique'); // value properties @@ -34233,6 +34252,8 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta const seq = new NodeClass(ctx.schema); if (ctx.atRoot) ctx.atRoot = false; + if (ctx.atKey) + ctx.atKey = false; let offset = bs.offset; let commentEnd = null; for (const { start, value } of bs.items) { @@ -34348,6 +34369,8 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr const atRoot = ctx.atRoot; if (atRoot) ctx.atRoot = false; + if (ctx.atKey) + ctx.atKey = false; let offset = fc.offset + fc.start.source.length; for (let i = 0; i < fc.items.length; ++i) { const collItem = fc.items[i]; @@ -34427,12 +34450,14 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr else { // item is a key+value pair // key value + ctx.atKey = true; const keyStart = props.end; const keyNode = key ? composeNode(ctx, key, props, onError) : composeEmptyNode(ctx, keyStart, start, null, props, onError); if (isBlock(key)) onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg); + ctx.atKey = false; // value properties const valueProps = resolveProps.resolveProps(sep ?? [], { flow: fcName, @@ -35046,11 +35071,7 @@ function mapIncludes(ctx, items, search) { return false; const isEqual = typeof uniqueKeys === 'function' ? uniqueKeys - : (a, b) => a === b || - (identity.isScalar(a) && - identity.isScalar(b) && - a.value === b.value && - !(a.value === '<<' && ctx.schema.merge)); + : (a, b) => a === b || (identity.isScalar(a) && identity.isScalar(b) && a.value === b.value); return items.some(pair => isEqual(pair.key, search)); } @@ -35102,6 +35123,7 @@ class Document { logLevel: 'warn', prettyErrors: true, strict: true, + stringKeys: false, uniqueKeys: true, version: '1.2' }, options); @@ -35325,7 +35347,7 @@ class Document { this.directives.yaml.version = '1.1'; else this.directives = new directives.Directives({ version: '1.1' }); - opt = { merge: true, resolveKnownTags: false, schema: 'yaml-1.1' }; + opt = { resolveKnownTags: false, schema: 'yaml-1.1' }; break; case '1.2': case 'next': @@ -35333,7 +35355,7 @@ class Document { this.directives.yaml.version = version; else this.directives = new directives.Directives({ version }); - opt = { merge: false, resolveKnownTags: true, schema: 'core' }; + opt = { resolveKnownTags: true, schema: 'core' }; break; case null: if (this.directives) @@ -36676,24 +36698,17 @@ exports.YAMLSeq = YAMLSeq; var log = __nccwpck_require__(7249); +var merge = __nccwpck_require__(452); var stringify = __nccwpck_require__(2148); var identity = __nccwpck_require__(1127); -var Scalar = __nccwpck_require__(3301); var toJS = __nccwpck_require__(4043); -const MERGE_KEY = '<<'; function addPairToJSMap(ctx, map, { key, value }) { - if (ctx?.doc.schema.merge && isMergeKey(key)) { - value = identity.isAlias(value) ? value.resolve(ctx.doc) : value; - if (identity.isSeq(value)) - for (const it of value.items) - mergeToJSMap(ctx, map, it); - else if (Array.isArray(value)) - for (const it of value) - mergeToJSMap(ctx, map, it); - else - mergeToJSMap(ctx, map, value); - } + if (identity.isNode(key) && key.addToJSMap) + key.addToJSMap(ctx, map, value); + // TODO: Should drop this special case for bare << handling + else if (merge.isMergeKey(ctx, key)) + merge.addMergeToJSMap(ctx, map, value); else { const jsKey = toJS.toJS(key, '', ctx); if (map instanceof Map) { @@ -36718,41 +36733,6 @@ function addPairToJSMap(ctx, map, { key, value }) { } return map; } -const isMergeKey = (key) => key === MERGE_KEY || - (identity.isScalar(key) && - key.value === MERGE_KEY && - (!key.type || key.type === Scalar.Scalar.PLAIN)); -// If the value associated with a merge key is a single mapping node, each of -// its key/value pairs is inserted into the current mapping, unless the key -// already exists in it. If the value associated with the merge key is a -// sequence, then this sequence is expected to contain mapping nodes and each -// of these nodes is merged in turn according to its order in the sequence. -// Keys in mapping nodes earlier in the sequence override keys specified in -// later mapping nodes. -- http://yaml.org/type/merge.html -function mergeToJSMap(ctx, map, value) { - const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value; - if (!identity.isMap(source)) - throw new Error('Merge sources must be maps or map aliases'); - const srcMap = source.toJSON(null, ctx, Map); - for (const [key, value] of srcMap) { - if (map instanceof Map) { - if (!map.has(key)) - map.set(key, value); - } - else if (map instanceof Set) { - map.add(key); - } - else if (!Object.prototype.hasOwnProperty.call(map, key)) { - Object.defineProperty(map, key, { - value, - writable: true, - enumerable: true, - configurable: true - }); - } - } - return map; -} function stringifyKey(key, jsKey, ctx) { if (jsKey === null) return ''; @@ -39167,6 +39147,7 @@ var composer = __nccwpck_require__(9984); var Document = __nccwpck_require__(3021); var errors = __nccwpck_require__(1464); var log = __nccwpck_require__(7249); +var identity = __nccwpck_require__(1127); var lineCounter = __nccwpck_require__(6628); var parser = __nccwpck_require__(3456); @@ -39258,6 +39239,8 @@ function stringify(value, replacer, options) { if (!keepUndefined) return undefined; } + if (identity.isDocument(value) && !_replacer) + return value.toString(options); return new Document.Document(value, _replacer, options).toString(options); } @@ -39289,10 +39272,9 @@ class Schema { : compat ? tags.getTags(null, compat) : null; - this.merge = !!merge; this.name = (typeof schema === 'string' && schema) || 'core'; this.knownTags = resolveKnownTags ? tags.coreKnownTags : {}; - this.tags = tags.getTags(customTags, this.name); + this.tags = tags.getTags(customTags, this.name, merge); this.toStringOptions = toStringDefaults ?? null; Object.defineProperty(this, identity.MAP, { value: map.map }); Object.defineProperty(this, identity.SCALAR, { value: string.string }); @@ -39675,6 +39657,7 @@ var int = __nccwpck_require__(9874); var schema = __nccwpck_require__(896); var schema$1 = __nccwpck_require__(3559); var binary = __nccwpck_require__(6083); +var merge = __nccwpck_require__(452); var omap = __nccwpck_require__(303); var pairs = __nccwpck_require__(3147); var schema$2 = __nccwpck_require__(5913); @@ -39700,6 +39683,7 @@ const tagsByName = { intOct: int.intOct, intTime: timestamp.intTime, map: map.map, + merge: merge.merge, null: _null.nullTag, omap: omap.omap, pairs: pairs.pairs, @@ -39709,13 +39693,20 @@ const tagsByName = { }; const coreKnownTags = { 'tag:yaml.org,2002:binary': binary.binary, + 'tag:yaml.org,2002:merge': merge.merge, 'tag:yaml.org,2002:omap': omap.omap, 'tag:yaml.org,2002:pairs': pairs.pairs, 'tag:yaml.org,2002:set': set.set, 'tag:yaml.org,2002:timestamp': timestamp.timestamp }; -function getTags(customTags, schemaName) { - let tags = schemas.get(schemaName); +function getTags(customTags, schemaName, addMergeTag) { + const schemaTags = schemas.get(schemaName); + if (schemaTags && !customTags) { + return addMergeTag && !schemaTags.includes(merge.merge) + ? schemaTags.concat(merge.merge) + : schemaTags.slice(); + } + let tags = schemaTags; if (!tags) { if (Array.isArray(customTags)) tags = []; @@ -39734,17 +39725,21 @@ function getTags(customTags, schemaName) { else if (typeof customTags === 'function') { tags = customTags(tags.slice()); } - return tags.map(tag => { - if (typeof tag !== 'string') - return tag; - const tagObj = tagsByName[tag]; - if (tagObj) - return tagObj; - const keys = Object.keys(tagsByName) - .map(key => JSON.stringify(key)) - .join(', '); - throw new Error(`Unknown custom tag "${tag}"; use one of ${keys}`); - }); + if (addMergeTag) + tags = tags.concat(merge.merge); + return tags.reduce((tags, tag) => { + const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag; + if (!tagObj) { + const tagName = JSON.stringify(tag); + const keys = Object.keys(tagsByName) + .map(key => JSON.stringify(key)) + .join(', '); + throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`); + } + if (!tags.includes(tagObj)) + tags.push(tagObj); + return tags; + }, []); } exports.coreKnownTags = coreKnownTags; @@ -40006,6 +40001,82 @@ exports.intHex = intHex; exports.intOct = intOct; +/***/ }), + +/***/ 452: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +var identity = __nccwpck_require__(1127); +var Scalar = __nccwpck_require__(3301); + +// If the value associated with a merge key is a single mapping node, each of +// its key/value pairs is inserted into the current mapping, unless the key +// already exists in it. If the value associated with the merge key is a +// sequence, then this sequence is expected to contain mapping nodes and each +// of these nodes is merged in turn according to its order in the sequence. +// Keys in mapping nodes earlier in the sequence override keys specified in +// later mapping nodes. -- http://yaml.org/type/merge.html +const MERGE_KEY = '<<'; +const merge = { + identify: value => value === MERGE_KEY || + (typeof value === 'symbol' && value.description === MERGE_KEY), + default: 'key', + tag: 'tag:yaml.org,2002:merge', + test: /^<<$/, + resolve: () => Object.assign(new Scalar.Scalar(Symbol(MERGE_KEY)), { + addToJSMap: addMergeToJSMap + }), + stringify: () => MERGE_KEY +}; +const isMergeKey = (ctx, key) => (merge.identify(key) || + (identity.isScalar(key) && + (!key.type || key.type === Scalar.Scalar.PLAIN) && + merge.identify(key.value))) && + ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default); +function addMergeToJSMap(ctx, map, value) { + value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value; + if (identity.isSeq(value)) + for (const it of value.items) + mergeValue(ctx, map, it); + else if (Array.isArray(value)) + for (const it of value) + mergeValue(ctx, map, it); + else + mergeValue(ctx, map, value); +} +function mergeValue(ctx, map, value) { + const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value; + if (!identity.isMap(source)) + throw new Error('Merge sources must be maps or map aliases'); + const srcMap = source.toJSON(null, ctx, Map); + for (const [key, value] of srcMap) { + if (map instanceof Map) { + if (!map.has(key)) + map.set(key, value); + } + else if (map instanceof Set) { + map.add(key); + } + else if (!Object.prototype.hasOwnProperty.call(map, key)) { + Object.defineProperty(map, key, { + value, + writable: true, + enumerable: true, + configurable: true + }); + } + } + return map; +} + +exports.addMergeToJSMap = addMergeToJSMap; +exports.isMergeKey = isMergeKey; +exports.merge = merge; + + /***/ }), /***/ 303: @@ -40197,6 +40268,7 @@ var binary = __nccwpck_require__(6083); var bool = __nccwpck_require__(8398); var float = __nccwpck_require__(5782); var int = __nccwpck_require__(873); +var merge = __nccwpck_require__(452); var omap = __nccwpck_require__(303); var pairs = __nccwpck_require__(3147); var set = __nccwpck_require__(1528); @@ -40217,6 +40289,7 @@ const schema = [ float.floatExp, float.float, binary.binary, + merge.merge, omap.omap, pairs.pairs, set.set, @@ -40668,7 +40741,12 @@ function getTagObject(tags, item) { let obj; if (identity.isScalar(item)) { obj = item.value; - const match = tags.filter(t => t.identify?.(obj)); + let match = tags.filter(t => t.identify?.(obj)); + if (match.length > 1) { + const testMatch = match.filter(t => t.test); + if (testMatch.length > 0) + match = testMatch; + } tagObj = match.find(t => t.format === item.format) ?? match.find(t => !t.format); } diff --git a/package-lock.json b/package-lock.json index a424373e..9ad3a46e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@actions/core": "^1.10.1", "@aws-sdk/client-codedeploy": "^3.662.0", "@aws-sdk/client-ecs": "^3.662.0", - "yaml": "^2.5.1" + "yaml": "^2.6.0" }, "devDependencies": { "@eslint/js": "^9.13.0", @@ -5641,9 +5641,9 @@ "dev": true }, "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index 77a069b9..757df72e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@actions/core": "^1.10.1", "@aws-sdk/client-codedeploy": "^3.662.0", "@aws-sdk/client-ecs": "^3.662.0", - "yaml": "^2.5.1" + "yaml": "^2.6.0" }, "devDependencies": { "@eslint/js": "^9.13.0",