@roadiehq/scaffolder-backend-module-utils 3.6.0 → 4.0.0
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/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,12 @@ function mergeArrayCustomiser(objValue, srcValue) {
|
|
|
23
23
|
}
|
|
24
24
|
return void 0;
|
|
25
25
|
}
|
|
26
|
+
function replaceArrayCustomiser(objValue, srcValue) {
|
|
27
|
+
if (lodash.isArray(objValue) && !lodash.isNull(objValue)) {
|
|
28
|
+
return srcValue;
|
|
29
|
+
}
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
26
32
|
const existPathInObject = (object, path, value) => {
|
|
27
33
|
const keys = path.split(".");
|
|
28
34
|
if (typeof object !== "object") {
|
|
@@ -50,7 +56,7 @@ function createMergeJSONAction({ actionId }) {
|
|
|
50
56
|
"This will be merged into to the file. Can be either an object or a string."
|
|
51
57
|
),
|
|
52
58
|
mergeArrays: (z) => z.boolean().describe(
|
|
53
|
-
"
|
|
59
|
+
"When true, arrays will be concatenated. When false or undefined, arrays will be replaced entirely."
|
|
54
60
|
).optional(),
|
|
55
61
|
matchFileIndent: (z) => z.boolean().describe(
|
|
56
62
|
"Make the output file indentation match that of the specified input file."
|
|
@@ -95,7 +101,7 @@ function createMergeJSONAction({ actionId }) {
|
|
|
95
101
|
lodash.mergeWith(
|
|
96
102
|
existingContent,
|
|
97
103
|
content,
|
|
98
|
-
ctx.input.mergeArrays ? mergeArrayCustomiser :
|
|
104
|
+
ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser
|
|
99
105
|
),
|
|
100
106
|
null,
|
|
101
107
|
fileIndent
|
|
@@ -117,7 +123,7 @@ function createMergeAction() {
|
|
|
117
123
|
"This will be merged into to the file. Can be either an object or a string."
|
|
118
124
|
),
|
|
119
125
|
mergeArrays: (z) => z.boolean().describe(
|
|
120
|
-
"
|
|
126
|
+
"When true, arrays will be concatenated. When false or undefined, arrays will be replaced entirely."
|
|
121
127
|
).optional(),
|
|
122
128
|
preserveYamlComments: (z) => z.boolean().describe(
|
|
123
129
|
"Will preserve standalone and inline comments in YAML files"
|
|
@@ -156,7 +162,7 @@ function createMergeAction() {
|
|
|
156
162
|
lodash.mergeWith(
|
|
157
163
|
YAML__default.default.parse(originalContent),
|
|
158
164
|
newContent,
|
|
159
|
-
ctx.input.mergeArrays ? mergeArrayCustomiser :
|
|
165
|
+
ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser
|
|
160
166
|
),
|
|
161
167
|
null,
|
|
162
168
|
2
|
|
@@ -199,7 +205,7 @@ function mergeDocumentsRemovingComments(originalContent, newContent, ctx) {
|
|
|
199
205
|
lodash.mergeWith(
|
|
200
206
|
documents[0].toJSON(),
|
|
201
207
|
newContent,
|
|
202
|
-
ctx.input.mergeArrays ? mergeArrayCustomiser :
|
|
208
|
+
ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser
|
|
203
209
|
)
|
|
204
210
|
];
|
|
205
211
|
}
|
|
@@ -222,7 +228,7 @@ function mergeDocumentsRemovingComments(originalContent, newContent, ctx) {
|
|
|
222
228
|
return lodash.mergeWith(
|
|
223
229
|
document.toJSON(),
|
|
224
230
|
newContent,
|
|
225
|
-
ctx.input.mergeArrays ? mergeArrayCustomiser :
|
|
231
|
+
ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser
|
|
226
232
|
);
|
|
227
233
|
}
|
|
228
234
|
return document.toJSON();
|
|
@@ -273,7 +279,7 @@ function mergeYawn(yawn, newContent, mergeArrays) {
|
|
|
273
279
|
yawn.json = lodash.mergeWith(
|
|
274
280
|
parsedOriginal,
|
|
275
281
|
newContent,
|
|
276
|
-
mergeArrays ? mergeArrayCustomiser :
|
|
282
|
+
mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser
|
|
277
283
|
);
|
|
278
284
|
return yawn;
|
|
279
285
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.cjs.js","sources":["../../../src/actions/merge/merge.ts"],"sourcesContent":["/*\n * Copyright 2021 Larder Software Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport { extname } from 'path';\nimport { isArray, isNull, mergeWith } from 'lodash';\nimport YAML, { Document } from 'yaml';\nimport YAWN from 'yawn-yaml';\nimport { yamlOptionsSchema } from '../../types';\nimport detectIndent from 'detect-indent';\n\nfunction mergeArrayCustomiser(objValue: string | any[], srcValue: any) {\n if (isArray(objValue) && !isNull(objValue)) {\n return Array.from(new Set(objValue.concat(srcValue)));\n }\n return undefined;\n}\n\nconst existPathInObject = (object: any, path: string, value: string) => {\n const keys = path.split('.');\n if (typeof object !== 'object') {\n return false;\n }\n\n let current = object;\n for (const key of keys) {\n if (current[key] === undefined) {\n current = undefined;\n break;\n }\n current = current[key];\n }\n return current?.toString() === value;\n};\n\nexport function createMergeJSONAction({ actionId }: { actionId?: string }) {\n return createTemplateAction({\n id: actionId || 'roadiehq:utils:json:merge',\n description: 'Merge new data into an existing JSON file.',\n supportsDryRun: true,\n schema: {\n input: {\n path: z => z.string().describe('Path to existing file to append.'),\n content: z =>\n z\n .union([z.string(), z.record(z.any())])\n .describe(\n 'This will be merged into to the file. Can be either an object or a string.',\n ),\n mergeArrays: z =>\n z\n .boolean()\n .describe(\n 'Where a value is an array the merge function should concatenate the provided array value with the target array',\n )\n .optional(),\n matchFileIndent: z =>\n z\n .boolean()\n .describe(\n 'Make the output file indentation match that of the specified input file.',\n )\n .optional(),\n },\n output: {\n path: z => z.string().describe('Path to the file that was written'),\n },\n },\n async handler(ctx) {\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.path,\n );\n\n let existingContent;\n\n if (fs.existsSync(sourceFilepath)) {\n existingContent = JSON.parse(\n fs.readFileSync(sourceFilepath).toString(),\n );\n } else {\n ctx.logger.info(\n `The file ${sourceFilepath} does not exist, creating it.`,\n );\n existingContent = {};\n }\n const content =\n typeof ctx.input.content === 'string'\n ? JSON.parse(ctx.input.content)\n : ctx.input.content;\n\n let fileIndent = 2;\n if (ctx.input.matchFileIndent) {\n fileIndent = detectIndent(\n fs.readFileSync(sourceFilepath, 'utf8'),\n ).amount;\n if (!fileIndent) {\n fileIndent = 2;\n ctx.logger.info(\n `Failed to detect source file indentation, using default value of 2.`,\n );\n }\n }\n fs.writeFileSync(\n sourceFilepath,\n JSON.stringify(\n mergeWith(\n existingContent,\n content,\n ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,\n ),\n null,\n fileIndent,\n ),\n );\n ctx.output('path', sourceFilepath);\n },\n });\n}\n\nexport function createMergeAction() {\n return createTemplateAction({\n id: 'roadiehq:utils:merge',\n description: 'Merges data into an existing structured file.',\n supportsDryRun: true,\n schema: {\n input: {\n path: z => z.string().describe('Path to existing file to append.'),\n content: z =>\n z\n .union([z.string(), z.record(z.any())])\n .describe(\n 'This will be merged into to the file. Can be either an object or a string.',\n ),\n mergeArrays: z =>\n z\n .boolean()\n .describe(\n 'Where a value is an array the merge function should concatenate the provided array value with the target array',\n )\n .optional(),\n preserveYamlComments: z =>\n z\n .boolean()\n .describe(\n 'Will preserve standalone and inline comments in YAML files',\n )\n .optional(),\n useDocumentIncludingField: z =>\n z\n .object({\n key: z\n .string()\n .describe(\n 'The key of the field to use to find the document to merge into.',\n ),\n value: z\n .string()\n .describe(\n 'The value of the field to use to find the document to merge into.',\n ),\n })\n .describe(\n 'This option is only applicable to YAML files. It allows you to specify a field to use as a key to find the document to merge into.',\n )\n .optional(),\n options: yamlOptionsSchema,\n },\n output: {\n path: z => z.string().describe('Path to the file that was written'),\n },\n },\n async handler(ctx) {\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.path,\n );\n\n if (!fs.existsSync(sourceFilepath)) {\n ctx.logger.error(`The file ${sourceFilepath} does not exist.`);\n throw new Error(`The file ${sourceFilepath} does not exist.`);\n }\n const originalContent = fs.readFileSync(sourceFilepath).toString();\n let mergedContent;\n\n switch (extname(sourceFilepath)) {\n case '.json': {\n const newContent =\n typeof ctx.input.content === 'string'\n ? JSON.parse(ctx.input.content)\n : ctx.input.content; // This supports the case where dynamic keys are required\n mergedContent = JSON.stringify(\n mergeWith(\n YAML.parse(originalContent),\n newContent,\n ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,\n ),\n null,\n 2,\n );\n break;\n }\n case '.yml':\n case '.yaml':\n {\n const newContent =\n typeof ctx.input.content === 'string'\n ? YAML.parse(ctx.input.content)\n : ctx.input.content; // This supports the case where dynamic keys are required\n if (ctx.input.preserveYamlComments) {\n mergedContent = mergeContentPreserveComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n } else {\n mergedContent = mergeDocumentsRemovingComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n }\n }\n break;\n default:\n break;\n }\n if (!mergedContent) {\n return;\n }\n fs.writeFileSync(sourceFilepath, mergedContent);\n ctx.output('path', sourceFilepath);\n },\n });\n}\n\nfunction mergeDocumentsRemovingComments(\n originalContent: string,\n newContent: any,\n ctx: any,\n): Document[] {\n const documents = YAML.parseAllDocuments(originalContent);\n checkDocumentExists(ctx, documents);\n if (documents.length === 1) {\n return [\n mergeWith(\n documents[0].toJSON(),\n newContent,\n ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,\n ),\n ];\n }\n checkUseDocumentIncludingFieldSet(ctx);\n const { key, value } = ctx.input.useDocumentIncludingField;\n return documents.map((document: Document) => {\n let includingField = document.get(key);\n if (typeof includingField === 'number') {\n includingField = includingField.toString();\n }\n if (typeof includingField !== 'string') {\n ctx.logger.error(\n `The value at \"${key}\" defined in useDocumentIncludingField must be a string or a number.`,\n );\n throw new Error(\n `The value at \"${key}\" defined in useDocumentIncludingField must be a string or a number.`,\n );\n }\n if ((includingField as string) === value) {\n return mergeWith(\n document.toJSON(),\n newContent,\n ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,\n );\n }\n return document.toJSON();\n });\n}\n\nfunction mergeContentPreserveComments(\n originalContent: string,\n newContent: any,\n ctx: any,\n): Document[] {\n const yawns = splitYaml(originalContent).map(\n (document: string) => new YAWN(document),\n );\n checkDocumentExists(ctx, yawns);\n if (yawns.length === 1) {\n return [\n YAML.parseDocument(\n mergeYawn(yawns[0], newContent, ctx.input.mergeArrays).yaml,\n ),\n ];\n }\n checkUseDocumentIncludingFieldSet(ctx);\n const { key, value } = ctx.input.useDocumentIncludingField;\n return yawns.map((yawn: YAWN) =>\n YAML.parseDocument(\n existPathInObject(yawn.json, key, value)\n ? mergeYawn(yawn, newContent, ctx.input.mergeArrays).yaml\n : yawn.yaml,\n ),\n );\n}\n\nfunction checkDocumentExists(ctx: any, documents: any[]) {\n if (documents.length === 0) {\n ctx.logger.error(\n `No documents found in the input content. Please provide a valid YAML file.`,\n );\n throw new Error(\n `No documents found in the input content. Please provide a valid YAML file.`,\n );\n }\n}\n\nfunction checkUseDocumentIncludingFieldSet(ctx: any) {\n if (!ctx.input.useDocumentIncludingField) {\n ctx.logger.error(\n `Multiple documents found in the input content. Please provide a key and value to use to find the document to merge into.`,\n );\n throw new Error(\n `Multiple documents found in the input content. Please provide a key and value to use to find the document to merge into.`,\n );\n }\n}\n\nfunction mergeYawn(\n yawn: YAWN,\n newContent: any,\n mergeArrays: boolean | undefined,\n) {\n const parsedOriginal = yawn.json;\n yawn.json = mergeWith(\n parsedOriginal,\n newContent,\n mergeArrays ? mergeArrayCustomiser : undefined,\n );\n return yawn;\n}\n\nfunction splitYaml(originalContent: string): string[] {\n return originalContent.split(/^---\\s*$/m).filter(doc => doc.trim() !== '');\n}\n"],"names":["isArray","isNull","createTemplateAction","resolveSafeChildPath","fs","detectIndent","mergeWith","yamlOptionsSchema","extname","YAML","YAWN"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"merge.cjs.js","sources":["../../../src/actions/merge/merge.ts"],"sourcesContent":["/*\n * Copyright 2021 Larder Software Limited\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport { extname } from 'path';\nimport { isArray, isNull, mergeWith } from 'lodash';\nimport YAML, { Document } from 'yaml';\nimport YAWN from 'yawn-yaml';\nimport { yamlOptionsSchema } from '../../types';\nimport detectIndent from 'detect-indent';\n\nfunction mergeArrayCustomiser(objValue: string | any[], srcValue: any) {\n if (isArray(objValue) && !isNull(objValue)) {\n return Array.from(new Set(objValue.concat(srcValue)));\n }\n return undefined;\n}\n\nfunction replaceArrayCustomiser(objValue: string | any[], srcValue: any) {\n if (isArray(objValue) && !isNull(objValue)) {\n return srcValue;\n }\n return undefined;\n}\n\nconst existPathInObject = (object: any, path: string, value: string) => {\n const keys = path.split('.');\n if (typeof object !== 'object') {\n return false;\n }\n\n let current = object;\n for (const key of keys) {\n if (current[key] === undefined) {\n current = undefined;\n break;\n }\n current = current[key];\n }\n return current?.toString() === value;\n};\n\nexport function createMergeJSONAction({ actionId }: { actionId?: string }) {\n return createTemplateAction({\n id: actionId || 'roadiehq:utils:json:merge',\n description: 'Merge new data into an existing JSON file.',\n supportsDryRun: true,\n schema: {\n input: {\n path: z => z.string().describe('Path to existing file to append.'),\n content: z =>\n z\n .union([z.string(), z.record(z.any())])\n .describe(\n 'This will be merged into to the file. Can be either an object or a string.',\n ),\n mergeArrays: z =>\n z\n .boolean()\n .describe(\n 'When true, arrays will be concatenated. When false or undefined, arrays will be replaced entirely.',\n )\n .optional(),\n matchFileIndent: z =>\n z\n .boolean()\n .describe(\n 'Make the output file indentation match that of the specified input file.',\n )\n .optional(),\n },\n output: {\n path: z => z.string().describe('Path to the file that was written'),\n },\n },\n async handler(ctx) {\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.path,\n );\n\n let existingContent;\n\n if (fs.existsSync(sourceFilepath)) {\n existingContent = JSON.parse(\n fs.readFileSync(sourceFilepath).toString(),\n );\n } else {\n ctx.logger.info(\n `The file ${sourceFilepath} does not exist, creating it.`,\n );\n existingContent = {};\n }\n const content =\n typeof ctx.input.content === 'string'\n ? JSON.parse(ctx.input.content)\n : ctx.input.content;\n\n let fileIndent = 2;\n if (ctx.input.matchFileIndent) {\n fileIndent = detectIndent(\n fs.readFileSync(sourceFilepath, 'utf8'),\n ).amount;\n if (!fileIndent) {\n fileIndent = 2;\n ctx.logger.info(\n `Failed to detect source file indentation, using default value of 2.`,\n );\n }\n }\n fs.writeFileSync(\n sourceFilepath,\n JSON.stringify(\n mergeWith(\n existingContent,\n content,\n ctx.input.mergeArrays\n ? mergeArrayCustomiser\n : replaceArrayCustomiser,\n ),\n null,\n fileIndent,\n ),\n );\n ctx.output('path', sourceFilepath);\n },\n });\n}\n\nexport function createMergeAction() {\n return createTemplateAction({\n id: 'roadiehq:utils:merge',\n description: 'Merges data into an existing structured file.',\n supportsDryRun: true,\n schema: {\n input: {\n path: z => z.string().describe('Path to existing file to append.'),\n content: z =>\n z\n .union([z.string(), z.record(z.any())])\n .describe(\n 'This will be merged into to the file. Can be either an object or a string.',\n ),\n mergeArrays: z =>\n z\n .boolean()\n .describe(\n 'When true, arrays will be concatenated. When false or undefined, arrays will be replaced entirely.',\n )\n .optional(),\n preserveYamlComments: z =>\n z\n .boolean()\n .describe(\n 'Will preserve standalone and inline comments in YAML files',\n )\n .optional(),\n useDocumentIncludingField: z =>\n z\n .object({\n key: z\n .string()\n .describe(\n 'The key of the field to use to find the document to merge into.',\n ),\n value: z\n .string()\n .describe(\n 'The value of the field to use to find the document to merge into.',\n ),\n })\n .describe(\n 'This option is only applicable to YAML files. It allows you to specify a field to use as a key to find the document to merge into.',\n )\n .optional(),\n options: yamlOptionsSchema,\n },\n output: {\n path: z => z.string().describe('Path to the file that was written'),\n },\n },\n async handler(ctx) {\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.path,\n );\n\n if (!fs.existsSync(sourceFilepath)) {\n ctx.logger.error(`The file ${sourceFilepath} does not exist.`);\n throw new Error(`The file ${sourceFilepath} does not exist.`);\n }\n const originalContent = fs.readFileSync(sourceFilepath).toString();\n let mergedContent;\n\n switch (extname(sourceFilepath)) {\n case '.json': {\n const newContent =\n typeof ctx.input.content === 'string'\n ? JSON.parse(ctx.input.content)\n : ctx.input.content; // This supports the case where dynamic keys are required\n mergedContent = JSON.stringify(\n mergeWith(\n YAML.parse(originalContent),\n newContent,\n ctx.input.mergeArrays\n ? mergeArrayCustomiser\n : replaceArrayCustomiser,\n ),\n null,\n 2,\n );\n break;\n }\n case '.yml':\n case '.yaml':\n {\n const newContent =\n typeof ctx.input.content === 'string'\n ? YAML.parse(ctx.input.content)\n : ctx.input.content; // This supports the case where dynamic keys are required\n if (ctx.input.preserveYamlComments) {\n mergedContent = mergeContentPreserveComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n } else {\n mergedContent = mergeDocumentsRemovingComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n }\n }\n break;\n default:\n break;\n }\n if (!mergedContent) {\n return;\n }\n fs.writeFileSync(sourceFilepath, mergedContent);\n ctx.output('path', sourceFilepath);\n },\n });\n}\n\nfunction mergeDocumentsRemovingComments(\n originalContent: string,\n newContent: any,\n ctx: any,\n): Document[] {\n const documents = YAML.parseAllDocuments(originalContent);\n checkDocumentExists(ctx, documents);\n if (documents.length === 1) {\n return [\n mergeWith(\n documents[0].toJSON(),\n newContent,\n ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser,\n ),\n ];\n }\n checkUseDocumentIncludingFieldSet(ctx);\n const { key, value } = ctx.input.useDocumentIncludingField;\n return documents.map((document: Document) => {\n let includingField = document.get(key);\n if (typeof includingField === 'number') {\n includingField = includingField.toString();\n }\n if (typeof includingField !== 'string') {\n ctx.logger.error(\n `The value at \"${key}\" defined in useDocumentIncludingField must be a string or a number.`,\n );\n throw new Error(\n `The value at \"${key}\" defined in useDocumentIncludingField must be a string or a number.`,\n );\n }\n if ((includingField as string) === value) {\n return mergeWith(\n document.toJSON(),\n newContent,\n ctx.input.mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser,\n );\n }\n return document.toJSON();\n });\n}\n\nfunction mergeContentPreserveComments(\n originalContent: string,\n newContent: any,\n ctx: any,\n): Document[] {\n const yawns = splitYaml(originalContent).map(\n (document: string) => new YAWN(document),\n );\n checkDocumentExists(ctx, yawns);\n if (yawns.length === 1) {\n return [\n YAML.parseDocument(\n mergeYawn(yawns[0], newContent, ctx.input.mergeArrays).yaml,\n ),\n ];\n }\n checkUseDocumentIncludingFieldSet(ctx);\n const { key, value } = ctx.input.useDocumentIncludingField;\n return yawns.map((yawn: YAWN) =>\n YAML.parseDocument(\n existPathInObject(yawn.json, key, value)\n ? mergeYawn(yawn, newContent, ctx.input.mergeArrays).yaml\n : yawn.yaml,\n ),\n );\n}\n\nfunction checkDocumentExists(ctx: any, documents: any[]) {\n if (documents.length === 0) {\n ctx.logger.error(\n `No documents found in the input content. Please provide a valid YAML file.`,\n );\n throw new Error(\n `No documents found in the input content. Please provide a valid YAML file.`,\n );\n }\n}\n\nfunction checkUseDocumentIncludingFieldSet(ctx: any) {\n if (!ctx.input.useDocumentIncludingField) {\n ctx.logger.error(\n `Multiple documents found in the input content. Please provide a key and value to use to find the document to merge into.`,\n );\n throw new Error(\n `Multiple documents found in the input content. Please provide a key and value to use to find the document to merge into.`,\n );\n }\n}\n\nfunction mergeYawn(\n yawn: YAWN,\n newContent: any,\n mergeArrays: boolean | undefined,\n) {\n const parsedOriginal = yawn.json;\n yawn.json = mergeWith(\n parsedOriginal,\n newContent,\n mergeArrays ? mergeArrayCustomiser : replaceArrayCustomiser,\n );\n return yawn;\n}\n\nfunction splitYaml(originalContent: string): string[] {\n return originalContent.split(/^---\\s*$/m).filter(doc => doc.trim() !== '');\n}\n"],"names":["isArray","isNull","createTemplateAction","resolveSafeChildPath","fs","detectIndent","mergeWith","yamlOptionsSchema","extname","YAML","YAWN"],"mappings":"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"}
|