@roadiehq/scaffolder-backend-module-utils 4.0.3 → 4.1.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
@@ -1,5 +1,17 @@
1
1
  # @roadiehq/scaffolder-backend-module-utils
2
2
 
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c2274f9: Upgrade backstage version to `1.44.2`.
8
+
9
+ ## 4.0.4
10
+
11
+ ### Patch Changes
12
+
13
+ - 3ff52f3: Add null check to ignore block comments in yaml merges
14
+
3
15
  ## 4.0.3
4
16
 
5
17
  ### Patch Changes
@@ -31,7 +31,7 @@ function replaceArrayCustomiser(objValue, srcValue) {
31
31
  }
32
32
  const existPathInObject = (object, path, value) => {
33
33
  const keys = path.split(".");
34
- if (typeof object !== "object") {
34
+ if (object === null || typeof object !== "object") {
35
35
  return false;
36
36
  }
37
37
  let current = object;
@@ -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\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 try {\n mergedContent = mergeContentPreserveComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n } catch (error: any) {\n ctx.logger.warn(\n `Failed to preserve YAML comments due to parsing error: ${error.message}. Falling back to merge without comment preservation.`,\n );\n mergedContent = mergeDocumentsRemovingComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\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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"}
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 (object === null || 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 try {\n mergedContent = mergeContentPreserveComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\n } catch (error: any) {\n ctx.logger.warn(\n `Failed to preserve YAML comments due to parsing error: ${error.message}. Falling back to merge without comment preservation.`,\n );\n mergedContent = mergeDocumentsRemovingComments(\n originalContent,\n newContent,\n ctx,\n )\n .map(doc => YAML.stringify(doc, ctx.input.options))\n .join('---\\n');\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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"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var backendPluginApi = require('@backstage/backend-plugin-api');
4
- var alpha = require('@backstage/plugin-scaffolder-node/alpha');
4
+ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
5
5
  var zip = require('./actions/zip.cjs.js');
6
6
  var writeFile = require('./actions/fs/writeFile.cjs.js');
7
7
  var appendFile = require('./actions/fs/appendFile.cjs.js');
@@ -21,7 +21,7 @@ const scaffolderBackendModuleUtils = backendPluginApi.createBackendModule({
21
21
  register({ registerInit }) {
22
22
  registerInit({
23
23
  deps: {
24
- scaffolder: alpha.scaffolderActionsExtensionPoint
24
+ scaffolder: pluginScaffolderNode.scaffolderActionsExtensionPoint
25
25
  },
26
26
  async init({ scaffolder }) {
27
27
  scaffolder.addActions(
@@ -1 +1 @@
1
- {"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["/*\n * Copyright 2024 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 */\nimport { createBackendModule } from '@backstage/backend-plugin-api';\nimport { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';\nimport * as backendModuleUtils from './actions';\n\n/**\n * @public\n * The Roadie Module for the Scaffolder Backend\n */\nexport const scaffolderBackendModuleUtils = createBackendModule({\n pluginId: 'scaffolder',\n moduleId: 'scaffolder-backend-module-utils',\n register({ registerInit }) {\n registerInit({\n deps: {\n scaffolder: scaffolderActionsExtensionPoint,\n },\n async init({ scaffolder }) {\n scaffolder.addActions(\n backendModuleUtils.createAppendFileAction(),\n backendModuleUtils.createJSONataAction(),\n backendModuleUtils.createJsonJSONataTransformAction(),\n backendModuleUtils.createMergeAction(),\n backendModuleUtils.createMergeJSONAction({}),\n backendModuleUtils.createParseFileAction(),\n backendModuleUtils.createReplaceInFileAction(),\n backendModuleUtils.createSerializeJsonAction(),\n backendModuleUtils.createSerializeYamlAction(),\n backendModuleUtils.createSleepAction(),\n backendModuleUtils.createWriteFileAction(),\n backendModuleUtils.createYamlJSONataTransformAction(),\n backendModuleUtils.createZipAction(),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","scaffolderActionsExtensionPoint","backendModuleUtils.createAppendFileAction","backendModuleUtils.createJSONataAction","backendModuleUtils.createJsonJSONataTransformAction","backendModuleUtils.createMergeAction","backendModuleUtils.createMergeJSONAction","backendModuleUtils.createParseFileAction","backendModuleUtils.createReplaceInFileAction","backendModuleUtils.createSerializeJsonAction","backendModuleUtils.createSerializeYamlAction","backendModuleUtils.createSleepAction","backendModuleUtils.createWriteFileAction","backendModuleUtils.createYamlJSONataTransformAction","backendModuleUtils.createZipAction"],"mappings":";;;;;;;;;;;;;;;;;AAuBO,MAAM,+BAA+BA,oCAAoB,CAAA;AAAA,EAC9D,QAAU,EAAA,YAAA;AAAA,EACV,QAAU,EAAA,iCAAA;AAAA,EACV,QAAA,CAAS,EAAE,YAAA,EAAgB,EAAA;AACzB,IAAa,YAAA,CAAA;AAAA,MACX,IAAM,EAAA;AAAA,QACJ,UAAY,EAAAC;AAAA,OACd;AAAA,MACA,MAAM,IAAA,CAAK,EAAE,UAAA,EAAc,EAAA;AACzB,QAAW,UAAA,CAAA,UAAA;AAAA,UACTC,iCAA0C,EAAA;AAAA,UAC1CC,2BAAuC,EAAA;AAAA,UACvCC,qCAAoD,EAAA;AAAA,UACpDC,uBAAqC,EAAA;AAAA,UACrCC,2BAAyC,CAAA,EAAE,CAAA;AAAA,UAC3CC,+BAAyC,EAAA;AAAA,UACzCC,uCAA6C,EAAA;AAAA,UAC7CC,gCAA6C,EAAA;AAAA,UAC7CC,8BAA6C,EAAA;AAAA,UAC7CC,uBAAqC,EAAA;AAAA,UACrCC,+BAAyC,EAAA;AAAA,UACzCC,uCAAoD,EAAA;AAAA,UACpDC,mBAAmC;AAAA,SACrC;AAAA;AACF,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
1
+ {"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["/*\n * Copyright 2024 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 */\nimport { createBackendModule } from '@backstage/backend-plugin-api';\nimport { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node';\nimport * as backendModuleUtils from './actions';\n\n/**\n * @public\n * The Roadie Module for the Scaffolder Backend\n */\nexport const scaffolderBackendModuleUtils = createBackendModule({\n pluginId: 'scaffolder',\n moduleId: 'scaffolder-backend-module-utils',\n register({ registerInit }) {\n registerInit({\n deps: {\n scaffolder: scaffolderActionsExtensionPoint,\n },\n async init({ scaffolder }) {\n scaffolder.addActions(\n backendModuleUtils.createAppendFileAction(),\n backendModuleUtils.createJSONataAction(),\n backendModuleUtils.createJsonJSONataTransformAction(),\n backendModuleUtils.createMergeAction(),\n backendModuleUtils.createMergeJSONAction({}),\n backendModuleUtils.createParseFileAction(),\n backendModuleUtils.createReplaceInFileAction(),\n backendModuleUtils.createSerializeJsonAction(),\n backendModuleUtils.createSerializeYamlAction(),\n backendModuleUtils.createSleepAction(),\n backendModuleUtils.createWriteFileAction(),\n backendModuleUtils.createYamlJSONataTransformAction(),\n backendModuleUtils.createZipAction(),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","scaffolderActionsExtensionPoint","backendModuleUtils.createAppendFileAction","backendModuleUtils.createJSONataAction","backendModuleUtils.createJsonJSONataTransformAction","backendModuleUtils.createMergeAction","backendModuleUtils.createMergeJSONAction","backendModuleUtils.createParseFileAction","backendModuleUtils.createReplaceInFileAction","backendModuleUtils.createSerializeJsonAction","backendModuleUtils.createSerializeYamlAction","backendModuleUtils.createSleepAction","backendModuleUtils.createWriteFileAction","backendModuleUtils.createYamlJSONataTransformAction","backendModuleUtils.createZipAction"],"mappings":";;;;;;;;;;;;;;;;;AAuBO,MAAM,+BAA+BA,oCAAoB,CAAA;AAAA,EAC9D,QAAU,EAAA,YAAA;AAAA,EACV,QAAU,EAAA,iCAAA;AAAA,EACV,QAAA,CAAS,EAAE,YAAA,EAAgB,EAAA;AACzB,IAAa,YAAA,CAAA;AAAA,MACX,IAAM,EAAA;AAAA,QACJ,UAAY,EAAAC;AAAA,OACd;AAAA,MACA,MAAM,IAAA,CAAK,EAAE,UAAA,EAAc,EAAA;AACzB,QAAW,UAAA,CAAA,UAAA;AAAA,UACTC,iCAA0C,EAAA;AAAA,UAC1CC,2BAAuC,EAAA;AAAA,UACvCC,qCAAoD,EAAA;AAAA,UACpDC,uBAAqC,EAAA;AAAA,UACrCC,2BAAyC,CAAA,EAAE,CAAA;AAAA,UAC3CC,+BAAyC,EAAA;AAAA,UACzCC,uCAA6C,EAAA;AAAA,UAC7CC,gCAA6C,EAAA;AAAA,UAC7CC,8BAA6C,EAAA;AAAA,UAC7CC,uBAAqC,EAAA;AAAA,UACrCC,+BAAyC,EAAA;AAAA,UACzCC,uCAAoD,EAAA;AAAA,UACpDC,mBAAmC;AAAA,SACrC;AAAA;AACF,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roadiehq/scaffolder-backend-module-utils",
3
- "version": "4.0.3",
3
+ "version": "4.1.0",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -60,10 +60,10 @@
60
60
  "clean": "backstage-cli clean"
61
61
  },
62
62
  "dependencies": {
63
- "@backstage/backend-plugin-api": "^1.4.0",
64
- "@backstage/config": "^1.3.2",
63
+ "@backstage/backend-plugin-api": "^1.4.4",
64
+ "@backstage/config": "^1.3.5",
65
65
  "@backstage/errors": "^1.2.7",
66
- "@backstage/plugin-scaffolder-node": "^0.9.0",
66
+ "@backstage/plugin-scaffolder-node": "^0.12.0",
67
67
  "adm-zip": "^0.5.9",
68
68
  "detect-indent": "^6.1.0",
69
69
  "fast-glob": "^3.3.3",
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "devDependencies": {
78
78
  "@backstage/backend-common": "^0.25.0",
79
- "@backstage/cli": "^0.33.0",
79
+ "@backstage/cli": "^0.34.4",
80
80
  "@testing-library/jest-dom": "^6.0.0",
81
81
  "@types/adm-zip": "^0.4.34",
82
82
  "@types/fs-extra": "^9.0.13",