@backstage/plugin-scaffolder-backend 3.1.1-next.2 → 3.1.1

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,34 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
+ ## 3.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 5012852: Remove unused abort controller in debug:wait action
8
+ - c641c14: Wrap some of the action logic with `resolveSafeChildPath` and improve symlink handling when fetching remote and local files
9
+ - 27f9061: REwrite]
10
+ - 872eb91: Upgrade `zod-to-json-schema` to latest version
11
+ - Updated dependencies
12
+ - @backstage/backend-defaults@0.15.0
13
+ - @backstage/backend-plugin-api@1.6.1
14
+ - @backstage/plugin-scaffolder-node@0.12.3
15
+ - @backstage/integration@1.19.2
16
+ - @backstage/backend-openapi-utils@0.6.5
17
+ - @backstage/plugin-scaffolder-backend-module-github@0.9.4
18
+ - @backstage/plugin-auth-node@0.6.11
19
+ - @backstage/plugin-scaffolder-backend-module-azure@0.2.17
20
+ - @backstage/plugin-permission-common@0.9.4
21
+ - @backstage/plugin-permission-node@0.10.8
22
+ - @backstage/plugin-bitbucket-cloud-common@0.3.6
23
+ - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.16
24
+ - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.18
25
+ - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.3.1
26
+ - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.17
27
+ - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.17
28
+ - @backstage/plugin-scaffolder-backend-module-gitea@0.2.17
29
+ - @backstage/plugin-scaffolder-backend-module-gitlab@0.11.1
30
+ - @backstage/plugin-scaffolder-common@1.7.5
31
+
3
32
  ## 3.1.1-next.2
4
33
 
5
34
  ### Patch Changes
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
3
4
  var fs$1 = require('fs-extra');
4
5
  var path = require('path');
5
6
  var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
@@ -37,10 +38,18 @@ function createDebugLogAction() {
37
38
  ${files.map((f) => {
38
39
  const relativePath = path.relative(ctx.workspacePath, f);
39
40
  if (ctx.input?.listWorkspace === "with-contents") {
40
- const content = fs__default.default.readFileSync(f, "utf-8");
41
- return ` - ${relativePath}:
41
+ try {
42
+ const safePath = backendPluginApi.resolveSafeChildPath(
43
+ ctx.workspacePath,
44
+ relativePath
45
+ );
46
+ const content = fs__default.default.readFileSync(safePath, "utf-8");
47
+ return ` - ${relativePath}:
42
48
 
43
49
  ${content}`;
50
+ } catch {
51
+ return ` - ${relativePath}: [skipped]`;
52
+ }
44
53
  }
45
54
  return ` - ${relativePath}`;
46
55
  }).join("\n")}`
@@ -1 +1 @@
1
- {"version":3,"file":"log.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/log.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { readdir, stat } from 'fs-extra';\nimport { join, relative } from 'path';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { examples } from './log.examples';\nimport fs from 'fs';\n\nconst id = 'debug:log';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction({\n id,\n description:\n 'Writes a message into the log and/or lists all files in the workspace.',\n examples,\n schema: {\n input: {\n message: z =>\n z.string({ description: 'Message to output.' }).optional(),\n listWorkspace: z =>\n z\n .union([z.boolean(), z.enum(['with-filenames', 'with-contents'])], {\n description:\n 'List all files in the workspace. If used with \"with-contents\", also the file contents are listed.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logger.info(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logger.info(\n `Workspace:\\n${files\n .map(f => {\n const relativePath = relative(ctx.workspacePath, f);\n if (ctx.input?.listWorkspace === 'with-contents') {\n const content = fs.readFileSync(f, 'utf-8');\n return ` - ${relativePath}:\\n\\n ${content}`;\n }\n return ` - ${relativePath}`;\n })\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n"],"names":["createTemplateAction","examples","relative","fs","readdir","join","stat"],"mappings":";;;;;;;;;;;;AAsBA,MAAM,EAAA,GAAK,WAAA;AAYJ,SAAS,oBAAA,GAAuB;AACrC,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA;AAAA,IACA,WAAA,EACE,wEAAA;AAAA,cACFC,qBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,OACP,CAAA,CAAE,MAAA,CAAO,EAAE,WAAA,EAAa,oBAAA,EAAsB,CAAA,CAAE,QAAA,EAAS;AAAA,QAC3D,aAAA,EAAe,CAAA,CAAA,KACb,CAAA,CACG,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,EAAQ,EAAG,CAAA,CAAE,KAAK,CAAC,gBAAA,EAAkB,eAAe,CAAC,CAAC,CAAA,EAAG;AAAA,UACjE,WAAA,EACE;AAAA,SACH,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,KAAK,IAAA,CAAK,SAAA,CAAU,IAAI,KAAA,EAAO,IAAA,EAAM,CAAC,CAAC,CAAA;AAElD,MAAA,IAAI,GAAA,CAAI,OAAO,OAAA,EAAS;AACtB,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAAA,MACnC;AAEA,MAAA,IAAI,GAAA,CAAI,OAAO,aAAA,EAAe;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,gBAAA,CAAiB,GAAA,CAAI,aAAa,CAAA;AACtD,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,UACT,CAAA;AAAA,EAAe,KAAA,CACZ,IAAI,CAAA,CAAA,KAAK;AACR,YAAA,MAAM,YAAA,GAAeC,aAAA,CAAS,GAAA,CAAI,aAAA,EAAe,CAAC,CAAA;AAClD,YAAA,IAAI,GAAA,CAAI,KAAA,EAAO,aAAA,KAAkB,eAAA,EAAiB;AAChD,cAAA,MAAM,OAAA,GAAUC,mBAAA,CAAG,YAAA,CAAa,CAAA,EAAG,OAAO,CAAA;AAC1C,cAAA,OAAO,MAAM,YAAY,CAAA;;AAAA,EAAA,EAAU,OAAO,CAAA,CAAA;AAAA,YAC5C;AACA,YAAA,OAAO,OAAO,YAAY,CAAA,CAAA;AAAA,UAC5B,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,SACf;AAAA,MACF;AAAA,IACF;AAAA,GACD,CAAA;AACH;AAEA,eAAsB,iBAAiB,GAAA,EAAgC;AACrE,EAAA,MAAM,OAAA,GAAU,MAAMC,YAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA;AAAA,IAC1B,OAAA,CAAQ,GAAA,CAAI,OAAM,MAAA,KAAU;AAC1B,MAAA,MAAM,GAAA,GAAMC,SAAA,CAAK,GAAA,EAAK,MAAM,CAAA;AAC5B,MAAA,OAAA,CAAQ,MAAMC,SAAA,CAAK,GAAG,CAAA,EAAG,WAAA,KAAgB,gBAAA,CAAiB,GAAG,CAAA,GAAI,CAAC,GAAG,CAAA;AAAA,IACvE,CAAC;AAAA,GACH;AACA,EAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,MAAA,CAAO,CAAC,CAAA,EAAG,EAAE,CAAA;AAC/C;;;;;"}
1
+ {"version":3,"file":"log.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/log.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { readdir, stat } from 'fs-extra';\nimport { join, relative } from 'path';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { examples } from './log.examples';\nimport fs from 'fs';\n\nconst id = 'debug:log';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction({\n id,\n description:\n 'Writes a message into the log and/or lists all files in the workspace.',\n examples,\n schema: {\n input: {\n message: z =>\n z.string({ description: 'Message to output.' }).optional(),\n listWorkspace: z =>\n z\n .union([z.boolean(), z.enum(['with-filenames', 'with-contents'])], {\n description:\n 'List all files in the workspace. If used with \"with-contents\", also the file contents are listed.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logger.info(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logger.info(\n `Workspace:\\n${files\n .map(f => {\n const relativePath = relative(ctx.workspacePath, f);\n if (ctx.input?.listWorkspace === 'with-contents') {\n try {\n const safePath = resolveSafeChildPath(\n ctx.workspacePath,\n relativePath,\n );\n const content = fs.readFileSync(safePath, 'utf-8');\n return ` - ${relativePath}:\\n\\n ${content}`;\n } catch {\n return ` - ${relativePath}: [skipped]`;\n }\n }\n return ` - ${relativePath}`;\n })\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n"],"names":["createTemplateAction","examples","relative","resolveSafeChildPath","fs","readdir","join","stat"],"mappings":";;;;;;;;;;;;;AAuBA,MAAM,EAAA,GAAK,WAAA;AAYJ,SAAS,oBAAA,GAAuB;AACrC,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA;AAAA,IACA,WAAA,EACE,wEAAA;AAAA,cACFC,qBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,OACP,CAAA,CAAE,MAAA,CAAO,EAAE,WAAA,EAAa,oBAAA,EAAsB,CAAA,CAAE,QAAA,EAAS;AAAA,QAC3D,aAAA,EAAe,CAAA,CAAA,KACb,CAAA,CACG,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,EAAQ,EAAG,CAAA,CAAE,KAAK,CAAC,gBAAA,EAAkB,eAAe,CAAC,CAAC,CAAA,EAAG;AAAA,UACjE,WAAA,EACE;AAAA,SACH,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,KAAK,IAAA,CAAK,SAAA,CAAU,IAAI,KAAA,EAAO,IAAA,EAAM,CAAC,CAAC,CAAA;AAElD,MAAA,IAAI,GAAA,CAAI,OAAO,OAAA,EAAS;AACtB,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAAA,MACnC;AAEA,MAAA,IAAI,GAAA,CAAI,OAAO,aAAA,EAAe;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,gBAAA,CAAiB,GAAA,CAAI,aAAa,CAAA;AACtD,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,UACT,CAAA;AAAA,EAAe,KAAA,CACZ,IAAI,CAAA,CAAA,KAAK;AACR,YAAA,MAAM,YAAA,GAAeC,aAAA,CAAS,GAAA,CAAI,aAAA,EAAe,CAAC,CAAA;AAClD,YAAA,IAAI,GAAA,CAAI,KAAA,EAAO,aAAA,KAAkB,eAAA,EAAiB;AAChD,cAAA,IAAI;AACF,gBAAA,MAAM,QAAA,GAAWC,qCAAA;AAAA,kBACf,GAAA,CAAI,aAAA;AAAA,kBACJ;AAAA,iBACF;AACA,gBAAA,MAAM,OAAA,GAAUC,mBAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AACjD,gBAAA,OAAO,MAAM,YAAY,CAAA;;AAAA,EAAA,EAAU,OAAO,CAAA,CAAA;AAAA,cAC5C,CAAA,CAAA,MAAQ;AACN,gBAAA,OAAO,MAAM,YAAY,CAAA,WAAA,CAAA;AAAA,cAC3B;AAAA,YACF;AACA,YAAA,OAAO,OAAO,YAAY,CAAA,CAAA;AAAA,UAC5B,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,SACf;AAAA,MACF;AAAA,IACF;AAAA,GACD,CAAA;AACH;AAEA,eAAsB,iBAAiB,GAAA,EAAgC;AACrE,EAAA,MAAM,OAAA,GAAU,MAAMC,YAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA;AAAA,IAC1B,OAAA,CAAQ,GAAA,CAAI,OAAM,MAAA,KAAU;AAC1B,MAAA,MAAM,GAAA,GAAMC,SAAA,CAAK,GAAA,EAAK,MAAM,CAAA;AAC5B,MAAA,OAAA,CAAQ,MAAMC,SAAA,CAAK,GAAG,CAAA,EAAG,WAAA,KAAgB,gBAAA,CAAiB,GAAG,CAAA,GAAI,CAAC,GAAG,CAAA;AAAA,IACvE,CAAC;AAAA,GACH;AACA,EAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,MAAA,CAAO,CAAC,CAAA,EAAG,EAAE,CAAA;AAC/C;;;;;"}
@@ -42,14 +42,12 @@ function createWaitAction(options) {
42
42
  );
43
43
  }
44
44
  await new Promise((resolve) => {
45
- const controller = new AbortController();
46
45
  const timeoutHandle = setTimeout(abort, delayTime.toMillis());
47
46
  ctx.signal?.addEventListener("abort", abort);
48
47
  function abort() {
49
48
  ctx.signal?.removeEventListener("abort", abort);
50
49
  clearTimeout(timeoutHandle);
51
- controller.abort();
52
- resolve("finished");
50
+ resolve();
53
51
  }
54
52
  });
55
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wait.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/wait.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { HumanDuration } from '@backstage/types';\nimport { Duration } from 'luxon';\nimport { examples } from './wait.examples';\n\nconst id = 'debug:wait';\n\nconst MAX_WAIT_TIME_IN_ISO = 'T00:10:00';\n\n/**\n * Waits for a certain period of time.\n *\n * @remarks\n *\n * This task is useful to give some waiting time for manual intervention.\n * Has to be used in a combination with other actions.\n *\n * @public\n */\nexport function createWaitAction(options?: {\n maxWaitTime?: Duration | HumanDuration;\n}) {\n const toDuration = (\n maxWaitTime: Duration | HumanDuration | undefined,\n ): Duration => {\n if (maxWaitTime) {\n if (maxWaitTime instanceof Duration) {\n return maxWaitTime;\n }\n return Duration.fromObject(maxWaitTime);\n }\n return Duration.fromISOTime(MAX_WAIT_TIME_IN_ISO);\n };\n\n return createTemplateAction({\n id,\n description: 'Waits for a certain period of time.',\n examples,\n schema: {\n input: {\n minutes: z =>\n z\n .number({\n description: 'Waiting period in minutes.',\n })\n .optional(),\n seconds: z =>\n z\n .number({\n description: 'Waiting period in seconds.',\n })\n .optional(),\n milliseconds: z =>\n z\n .number({\n description: 'Waiting period in milliseconds.',\n })\n .optional(),\n },\n },\n async handler(ctx) {\n const delayTime = Duration.fromObject(ctx.input);\n const maxWait = toDuration(options?.maxWaitTime);\n\n if (delayTime.minus(maxWait).toMillis() > 0) {\n throw new Error(\n `Waiting duration is longer than the maximum threshold of ${maxWait.toHuman()}`,\n );\n }\n\n await new Promise(resolve => {\n const controller = new AbortController();\n const timeoutHandle = setTimeout(abort, delayTime.toMillis());\n ctx.signal?.addEventListener('abort', abort);\n\n function abort() {\n ctx.signal?.removeEventListener('abort', abort);\n clearTimeout(timeoutHandle!);\n controller.abort();\n resolve('finished');\n }\n });\n },\n });\n}\n"],"names":["Duration","createTemplateAction","examples"],"mappings":";;;;;;AAqBA,MAAM,EAAA,GAAK,YAAA;AAEX,MAAM,oBAAA,GAAuB,WAAA;AAYtB,SAAS,iBAAiB,OAAA,EAE9B;AACD,EAAA,MAAM,UAAA,GAAa,CACjB,WAAA,KACa;AACb,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,IAAI,uBAAuBA,cAAA,EAAU;AACnC,QAAA,OAAO,WAAA;AAAA,MACT;AACA,MAAA,OAAOA,cAAA,CAAS,WAAW,WAAW,CAAA;AAAA,IACxC;AACA,IAAA,OAAOA,cAAA,CAAS,YAAY,oBAAoB,CAAA;AAAA,EAClD,CAAA;AAEA,EAAA,OAAOC,yCAAA,CAAqB;AAAA,IAC1B,EAAA;AAAA,IACA,WAAA,EAAa,qCAAA;AAAA,cACbC,sBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,CAAA,CAAA,KACP,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA,EAAS;AAAA,QACd,OAAA,EAAS,CAAA,CAAA,KACP,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA,EAAS;AAAA,QACd,YAAA,EAAc,CAAA,CAAA,KACZ,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,MAAM,SAAA,GAAYF,cAAA,CAAS,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA;AAC/C,MAAA,MAAM,OAAA,GAAU,UAAA,CAAW,OAAA,EAAS,WAAW,CAAA;AAE/C,MAAA,IAAI,UAAU,KAAA,CAAM,OAAO,CAAA,CAAE,QAAA,KAAa,CAAA,EAAG;AAC3C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,yDAAA,EAA4D,OAAA,CAAQ,OAAA,EAAS,CAAA;AAAA,SAC/E;AAAA,MACF;AAEA,MAAA,MAAM,IAAI,QAAQ,CAAA,OAAA,KAAW;AAC3B,QAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,QAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,KAAA,EAAO,SAAA,CAAU,UAAU,CAAA;AAC5D,QAAA,GAAA,CAAI,MAAA,EAAQ,gBAAA,CAAiB,OAAA,EAAS,KAAK,CAAA;AAE3C,QAAA,SAAS,KAAA,GAAQ;AACf,UAAA,GAAA,CAAI,MAAA,EAAQ,mBAAA,CAAoB,OAAA,EAAS,KAAK,CAAA;AAC9C,UAAA,YAAA,CAAa,aAAc,CAAA;AAC3B,UAAA,UAAA,CAAW,KAAA,EAAM;AACjB,UAAA,OAAA,CAAQ,UAAU,CAAA;AAAA,QACpB;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"wait.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/wait.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { HumanDuration } from '@backstage/types';\nimport { Duration } from 'luxon';\nimport { examples } from './wait.examples';\n\nconst id = 'debug:wait';\n\nconst MAX_WAIT_TIME_IN_ISO = 'T00:10:00';\n\n/**\n * Waits for a certain period of time.\n *\n * @remarks\n *\n * This task is useful to give some waiting time for manual intervention.\n * Has to be used in a combination with other actions.\n *\n * @public\n */\nexport function createWaitAction(options?: {\n maxWaitTime?: Duration | HumanDuration;\n}) {\n const toDuration = (\n maxWaitTime: Duration | HumanDuration | undefined,\n ): Duration => {\n if (maxWaitTime) {\n if (maxWaitTime instanceof Duration) {\n return maxWaitTime;\n }\n return Duration.fromObject(maxWaitTime);\n }\n return Duration.fromISOTime(MAX_WAIT_TIME_IN_ISO);\n };\n\n return createTemplateAction({\n id,\n description: 'Waits for a certain period of time.',\n examples,\n schema: {\n input: {\n minutes: z =>\n z\n .number({\n description: 'Waiting period in minutes.',\n })\n .optional(),\n seconds: z =>\n z\n .number({\n description: 'Waiting period in seconds.',\n })\n .optional(),\n milliseconds: z =>\n z\n .number({\n description: 'Waiting period in milliseconds.',\n })\n .optional(),\n },\n },\n async handler(ctx) {\n const delayTime = Duration.fromObject(ctx.input);\n const maxWait = toDuration(options?.maxWaitTime);\n\n if (delayTime.minus(maxWait).toMillis() > 0) {\n throw new Error(\n `Waiting duration is longer than the maximum threshold of ${maxWait.toHuman()}`,\n );\n }\n\n await new Promise<void>(resolve => {\n const timeoutHandle = setTimeout(abort, delayTime.toMillis());\n ctx.signal?.addEventListener('abort', abort);\n\n function abort() {\n ctx.signal?.removeEventListener('abort', abort);\n clearTimeout(timeoutHandle);\n resolve();\n }\n });\n },\n });\n}\n"],"names":["Duration","createTemplateAction","examples"],"mappings":";;;;;;AAqBA,MAAM,EAAA,GAAK,YAAA;AAEX,MAAM,oBAAA,GAAuB,WAAA;AAYtB,SAAS,iBAAiB,OAAA,EAE9B;AACD,EAAA,MAAM,UAAA,GAAa,CACjB,WAAA,KACa;AACb,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,IAAI,uBAAuBA,cAAA,EAAU;AACnC,QAAA,OAAO,WAAA;AAAA,MACT;AACA,MAAA,OAAOA,cAAA,CAAS,WAAW,WAAW,CAAA;AAAA,IACxC;AACA,IAAA,OAAOA,cAAA,CAAS,YAAY,oBAAoB,CAAA;AAAA,EAClD,CAAA;AAEA,EAAA,OAAOC,yCAAA,CAAqB;AAAA,IAC1B,EAAA;AAAA,IACA,WAAA,EAAa,qCAAA;AAAA,cACbC,sBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,CAAA,CAAA,KACP,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA,EAAS;AAAA,QACd,OAAA,EAAS,CAAA,CAAA,KACP,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA,EAAS;AAAA,QACd,YAAA,EAAc,CAAA,CAAA,KACZ,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EAAa;AAAA,SACd,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,MAAM,SAAA,GAAYF,cAAA,CAAS,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA;AAC/C,MAAA,MAAM,OAAA,GAAU,UAAA,CAAW,OAAA,EAAS,WAAW,CAAA;AAE/C,MAAA,IAAI,UAAU,KAAA,CAAM,OAAO,CAAA,CAAE,QAAA,KAAa,CAAA,EAAG;AAC3C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,yDAAA,EAA4D,OAAA,CAAQ,OAAA,EAAS,CAAA;AAAA,SAC/E;AAAA,MACF;AAEA,MAAA,MAAM,IAAI,QAAc,CAAA,OAAA,KAAW;AACjC,QAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,KAAA,EAAO,SAAA,CAAU,UAAU,CAAA;AAC5D,QAAA,GAAA,CAAI,MAAA,EAAQ,gBAAA,CAAiB,OAAA,EAAS,KAAK,CAAA;AAE3C,QAAA,SAAS,KAAA,GAAQ;AACf,UAAA,GAAA,CAAI,MAAA,EAAQ,mBAAA,CAAoB,OAAA,EAAS,KAAK,CAAA;AAC9C,UAAA,YAAA,CAAa,aAAa,CAAA;AAC1B,UAAA,OAAA,EAAQ;AAAA,QACV;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AACH;;;;"}
@@ -41,10 +41,11 @@ const createFilesystemDeleteAction = () => {
41
41
  });
42
42
  for (const filepath of resolvedPaths) {
43
43
  try {
44
- await fs__default.default.remove(filepath);
45
- ctx.logger.info(`File ${filepath} deleted successfully`);
44
+ const safePath = backendPluginApi.resolveSafeChildPath(ctx.workspacePath, filepath);
45
+ await fs__default.default.remove(safePath);
46
+ ctx.logger.info(`File ${safePath} deleted successfully`);
46
47
  } catch (err) {
47
- ctx.logger.error(`Failed to delete file ${filepath}:`, err);
48
+ ctx.logger.error(`Failed to delete file`, err);
48
49
  throw err;
49
50
  }
50
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"delete.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/filesystem/delete.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport globby from 'globby';\nimport { examples } from './delete.examples';\n\n/**\n * Creates new action that enables deletion of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemDeleteAction = () => {\n return createTemplateAction({\n id: 'fs:delete',\n description: 'Deletes files and directories from the workspace',\n examples,\n schema: {\n input: {\n files: z =>\n z.array(z.string(), {\n description: 'A list of files and directories that will be deleted',\n }),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n // globby cannot handle backslash file separators\n const safeFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n file,\n ).replace(/\\\\/g, '/');\n const resolvedPaths = await globby(safeFilepath, {\n cwd: ctx.workspacePath,\n absolute: true,\n dot: true,\n });\n\n for (const filepath of resolvedPaths) {\n try {\n await fs.remove(filepath);\n ctx.logger.info(`File ${filepath} deleted successfully`);\n } catch (err) {\n ctx.logger.error(`Failed to delete file ${filepath}:`, err);\n throw err;\n }\n }\n }\n },\n });\n};\n"],"names":["createTemplateAction","examples","InputError","resolveSafeChildPath","globby","fs"],"mappings":";;;;;;;;;;;;;;AA2BO,MAAM,+BAA+B,MAAM;AAChD,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,WAAA;AAAA,IACJ,WAAA,EAAa,kDAAA;AAAA,cACbC,wBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAO,CAAA,CAAA,KACL,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAO,EAAG;AAAA,UAClB,WAAA,EAAa;AAAA,SACd;AAAA;AACL,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA,EAAG;AACpC,QAAA,MAAM,IAAIC,kBAAW,wBAAwB,CAAA;AAAA,MAC/C;AAEA,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO;AAElC,QAAA,MAAM,YAAA,GAAeC,qCAAA;AAAA,UACnB,GAAA,CAAI,aAAA;AAAA,UACJ;AAAA,SACF,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACpB,QAAA,MAAM,aAAA,GAAgB,MAAMC,uBAAA,CAAO,YAAA,EAAc;AAAA,UAC/C,KAAK,GAAA,CAAI,aAAA;AAAA,UACT,QAAA,EAAU,IAAA;AAAA,UACV,GAAA,EAAK;AAAA,SACN,CAAA;AAED,QAAA,KAAA,MAAW,YAAY,aAAA,EAAe;AACpC,UAAA,IAAI;AACF,YAAA,MAAMC,mBAAA,CAAG,OAAO,QAAQ,CAAA;AACxB,YAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,CAAA,KAAA,EAAQ,QAAQ,CAAA,qBAAA,CAAuB,CAAA;AAAA,UACzD,SAAS,GAAA,EAAK;AACZ,YAAA,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,CAAA,sBAAA,EAAyB,QAAQ,KAAK,GAAG,CAAA;AAC1D,YAAA,MAAM,GAAA;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,GACD,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"delete.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/filesystem/delete.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs-extra';\nimport globby from 'globby';\nimport { examples } from './delete.examples';\n\n/**\n * Creates new action that enables deletion of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemDeleteAction = () => {\n return createTemplateAction({\n id: 'fs:delete',\n description: 'Deletes files and directories from the workspace',\n examples,\n schema: {\n input: {\n files: z =>\n z.array(z.string(), {\n description: 'A list of files and directories that will be deleted',\n }),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n // globby cannot handle backslash file separators\n const safeFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n file,\n ).replace(/\\\\/g, '/');\n const resolvedPaths = await globby(safeFilepath, {\n cwd: ctx.workspacePath,\n absolute: true,\n dot: true,\n });\n\n for (const filepath of resolvedPaths) {\n try {\n const safePath = resolveSafeChildPath(ctx.workspacePath, filepath);\n await fs.remove(safePath);\n ctx.logger.info(`File ${safePath} deleted successfully`);\n } catch (err) {\n ctx.logger.error(`Failed to delete file`, err);\n throw err;\n }\n }\n }\n },\n });\n};\n"],"names":["createTemplateAction","examples","InputError","resolveSafeChildPath","globby","fs"],"mappings":";;;;;;;;;;;;;;AA2BO,MAAM,+BAA+B,MAAM;AAChD,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,WAAA;AAAA,IACJ,WAAA,EAAa,kDAAA;AAAA,cACbC,wBAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,OAAO,CAAA,CAAA,KACL,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAO,EAAG;AAAA,UAClB,WAAA,EAAa;AAAA,SACd;AAAA;AACL,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA,EAAG;AACpC,QAAA,MAAM,IAAIC,kBAAW,wBAAwB,CAAA;AAAA,MAC/C;AAEA,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO;AAElC,QAAA,MAAM,YAAA,GAAeC,qCAAA;AAAA,UACnB,GAAA,CAAI,aAAA;AAAA,UACJ;AAAA,SACF,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACpB,QAAA,MAAM,aAAA,GAAgB,MAAMC,uBAAA,CAAO,YAAA,EAAc;AAAA,UAC/C,KAAK,GAAA,CAAI,aAAA;AAAA,UACT,QAAA,EAAU,IAAA;AAAA,UACV,GAAA,EAAK;AAAA,SACN,CAAA;AAED,QAAA,KAAA,MAAW,YAAY,aAAA,EAAe;AACpC,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,GAAWD,qCAAA,CAAqB,GAAA,CAAI,aAAA,EAAe,QAAQ,CAAA;AACjE,YAAA,MAAME,mBAAA,CAAG,OAAO,QAAQ,CAAA;AACxB,YAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,CAAA,KAAA,EAAQ,QAAQ,CAAA,qBAAA,CAAuB,CAAA;AAAA,UACzD,SAAS,GAAA,EAAK;AACZ,YAAA,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,CAAA,qBAAA,CAAA,EAAyB,GAAG,CAAA;AAC7C,YAAA,MAAM,GAAA;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,GACD,CAAA;AACH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend",
3
- "version": "3.1.1-next.2",
3
+ "version": "3.1.1",
4
4
  "description": "The Backstage backend plugin that helps you create new things",
5
5
  "backstage": {
6
6
  "role": "backend-plugin",
@@ -74,31 +74,31 @@
74
74
  "test": "backstage-cli package test"
75
75
  },
76
76
  "dependencies": {
77
- "@backstage/backend-defaults": "0.15.0-next.2",
78
- "@backstage/backend-openapi-utils": "0.6.5-next.0",
79
- "@backstage/backend-plugin-api": "1.6.0",
80
- "@backstage/catalog-model": "1.7.6",
81
- "@backstage/config": "1.3.6",
82
- "@backstage/errors": "1.2.7",
83
- "@backstage/integration": "1.19.2-next.0",
84
- "@backstage/plugin-auth-node": "0.6.10",
85
- "@backstage/plugin-bitbucket-cloud-common": "0.3.6-next.0",
86
- "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.16-next.0",
87
- "@backstage/plugin-catalog-node": "1.20.1",
88
- "@backstage/plugin-events-node": "0.4.18",
89
- "@backstage/plugin-permission-common": "0.9.3",
90
- "@backstage/plugin-permission-node": "0.10.7",
91
- "@backstage/plugin-scaffolder-backend-module-azure": "0.2.17-next.0",
92
- "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.18-next.0",
93
- "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.3.1-next.0",
94
- "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.17-next.0",
95
- "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.17-next.0",
96
- "@backstage/plugin-scaffolder-backend-module-gitea": "0.2.17-next.0",
97
- "@backstage/plugin-scaffolder-backend-module-github": "0.9.4-next.1",
98
- "@backstage/plugin-scaffolder-backend-module-gitlab": "0.11.1-next.0",
99
- "@backstage/plugin-scaffolder-common": "1.7.5-next.0",
100
- "@backstage/plugin-scaffolder-node": "0.12.3-next.0",
101
- "@backstage/types": "1.2.2",
77
+ "@backstage/backend-defaults": "^0.15.0",
78
+ "@backstage/backend-openapi-utils": "^0.6.5",
79
+ "@backstage/backend-plugin-api": "^1.6.1",
80
+ "@backstage/catalog-model": "^1.7.6",
81
+ "@backstage/config": "^1.3.6",
82
+ "@backstage/errors": "^1.2.7",
83
+ "@backstage/integration": "^1.19.2",
84
+ "@backstage/plugin-auth-node": "^0.6.11",
85
+ "@backstage/plugin-bitbucket-cloud-common": "^0.3.6",
86
+ "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^0.2.16",
87
+ "@backstage/plugin-catalog-node": "^1.20.1",
88
+ "@backstage/plugin-events-node": "^0.4.18",
89
+ "@backstage/plugin-permission-common": "^0.9.4",
90
+ "@backstage/plugin-permission-node": "^0.10.8",
91
+ "@backstage/plugin-scaffolder-backend-module-azure": "^0.2.17",
92
+ "@backstage/plugin-scaffolder-backend-module-bitbucket": "^0.3.18",
93
+ "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "^0.3.1",
94
+ "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "^0.2.17",
95
+ "@backstage/plugin-scaffolder-backend-module-gerrit": "^0.2.17",
96
+ "@backstage/plugin-scaffolder-backend-module-gitea": "^0.2.17",
97
+ "@backstage/plugin-scaffolder-backend-module-github": "^0.9.4",
98
+ "@backstage/plugin-scaffolder-backend-module-gitlab": "^0.11.1",
99
+ "@backstage/plugin-scaffolder-common": "^1.7.5",
100
+ "@backstage/plugin-scaffolder-node": "^0.12.3",
101
+ "@backstage/types": "^1.2.2",
102
102
  "@opentelemetry/api": "^1.9.0",
103
103
  "@types/luxon": "^3.0.0",
104
104
  "concat-stream": "^2.0.0",
@@ -124,15 +124,15 @@
124
124
  "yaml": "^2.0.0",
125
125
  "zen-observable": "^0.10.0",
126
126
  "zod": "^3.22.4",
127
- "zod-to-json-schema": "^3.20.4"
127
+ "zod-to-json-schema": "^3.25.1"
128
128
  },
129
129
  "devDependencies": {
130
- "@backstage/backend-app-api": "1.4.0",
131
- "@backstage/backend-defaults": "0.15.0-next.2",
132
- "@backstage/backend-test-utils": "1.10.3-next.1",
133
- "@backstage/cli": "0.35.2-next.1",
134
- "@backstage/plugin-scaffolder-node-test-utils": "0.3.7-next.1",
135
- "@backstage/repo-tools": "0.16.1",
130
+ "@backstage/backend-app-api": "^1.4.1",
131
+ "@backstage/backend-defaults": "^0.15.0",
132
+ "@backstage/backend-test-utils": "^1.10.3",
133
+ "@backstage/cli": "^0.35.2",
134
+ "@backstage/plugin-scaffolder-node-test-utils": "^0.3.7",
135
+ "@backstage/repo-tools": "^0.16.2",
136
136
  "@types/express": "^4.17.6",
137
137
  "@types/fs-extra": "^11.0.0",
138
138
  "@types/nunjucks": "^3.1.4",