@backstage/plugin-scaffolder 1.33.1-next.0 → 1.34.0-next.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,33 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.34.0-next.1
4
+
5
+ ### Minor Changes
6
+
7
+ - c08cbc4: Move Scaffolder API to OpenAPI
8
+
9
+ ### Patch Changes
10
+
11
+ - f2f133c: Internal update to use the new variant of `ApiBlueprint`.
12
+ - b0dc9b8: differentiate between entirely and partially composite schemas in schema rendering
13
+ - c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor.
14
+ - Updated dependencies
15
+ - @backstage/plugin-scaffolder-react@1.19.0-next.1
16
+ - @backstage/plugin-scaffolder-common@1.7.0-next.0
17
+ - @backstage/core-compat-api@0.4.5-next.1
18
+ - @backstage/plugin-catalog-react@1.20.0-next.1
19
+ - @backstage/frontend-plugin-api@0.11.0-next.0
20
+ - @backstage/catalog-client@1.11.0-next.0
21
+ - @backstage/core-components@0.17.5-next.0
22
+ - @backstage/catalog-model@1.7.5
23
+ - @backstage/core-plugin-api@1.10.9
24
+ - @backstage/errors@1.2.7
25
+ - @backstage/integration@1.17.1
26
+ - @backstage/integration-react@1.2.9
27
+ - @backstage/types@1.2.1
28
+ - @backstage/plugin-catalog-common@1.1.5
29
+ - @backstage/plugin-permission-react@0.4.36
30
+
3
31
  ## 1.33.1-next.0
4
32
 
5
33
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { ApiBlueprint, createExtensionInput, createApiFactory } from '@backstage/frontend-plugin-api';
1
+ import { ApiBlueprint, createExtensionInput } from '@backstage/frontend-plugin-api';
2
2
  import { formDecoratorsApiRef } from './ref.esm.js';
3
3
  import { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';
4
4
 
@@ -26,15 +26,15 @@ const formDecoratorsApi = ApiBlueprint.makeWithOverrides({
26
26
  const formDecorators = inputs.formDecorators.map(
27
27
  (e) => e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader)
28
28
  );
29
- return originalFactory({
30
- factory: createApiFactory({
29
+ return originalFactory(
30
+ (define) => define({
31
31
  api: formDecoratorsApiRef,
32
32
  deps: {},
33
33
  factory: () => DefaultScaffolderFormDecoratorsApi.create({
34
34
  decorators: formDecorators
35
35
  })
36
36
  })
37
- });
37
+ );
38
38
  }
39
39
  });
40
40
 
@@ -1 +1 @@
1
- {"version":3,"file":"FormDecoratorsApi.esm.js","sources":["../../../src/alpha/api/FormDecoratorsApi.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n ApiBlueprint,\n createApiFactory,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\nimport { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApiRef } from './ref';\nimport { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\n\n/** @alpha */\nexport class DefaultScaffolderFormDecoratorsApi\n implements ScaffolderFormDecoratorsApi\n{\n private constructor(\n private readonly options: {\n decorators: Array<ScaffolderFormDecorator>;\n },\n ) {}\n\n static create(options?: { decorators: ScaffolderFormDecorator[] }) {\n return new DefaultScaffolderFormDecoratorsApi(\n options ?? { decorators: [] },\n );\n }\n\n async getFormDecorators(): Promise<ScaffolderFormDecorator[]> {\n return this.options.decorators;\n }\n}\n\n/** @alpha */\nexport const formDecoratorsApi = ApiBlueprint.makeWithOverrides({\n name: 'form-decorators',\n inputs: {\n formDecorators: createExtensionInput([\n FormDecoratorBlueprint.dataRefs.formDecoratorLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formDecorators = inputs.formDecorators.map(e =>\n e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader),\n );\n\n return originalFactory({\n factory: createApiFactory({\n api: formDecoratorsApiRef,\n deps: {},\n factory: () =>\n DefaultScaffolderFormDecoratorsApi.create({\n decorators: formDecorators,\n }),\n }),\n });\n },\n});\n"],"names":[],"mappings":";;;;AA2BO,MAAM,kCAEb,CAAA;AAAA,EACU,YACW,OAGjB,EAAA;AAHiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA;AAGhB,EAEH,OAAO,OAAO,OAAqD,EAAA;AACjE,IAAA,OAAO,IAAI,kCAAA;AAAA,MACT,OAAW,IAAA,EAAE,UAAY,EAAA,EAAG;AAAA,KAC9B;AAAA;AACF,EAEA,MAAM,iBAAwD,GAAA;AAC5D,IAAA,OAAO,KAAK,OAAQ,CAAA,UAAA;AAAA;AAExB;AAGa,MAAA,iBAAA,GAAoB,aAAa,iBAAkB,CAAA;AAAA,EAC9D,IAAM,EAAA,iBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,gBAAgB,oBAAqB,CAAA;AAAA,MACnC,uBAAuB,QAAS,CAAA;AAAA,KACjC;AAAA,GACH;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAM,MAAA,cAAA,GAAiB,OAAO,cAAe,CAAA,GAAA;AAAA,MAAI,CAC/C,CAAA,KAAA,CAAA,CAAE,GAAI,CAAA,sBAAA,CAAuB,SAAS,mBAAmB;AAAA,KAC3D;AAEA,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,SAAS,gBAAiB,CAAA;AAAA,QACxB,GAAK,EAAA,oBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,OAAA,EAAS,MACP,kCAAA,CAAmC,MAAO,CAAA;AAAA,UACxC,UAAY,EAAA;AAAA,SACb;AAAA,OACJ;AAAA,KACF,CAAA;AAAA;AAEL,CAAC;;;;"}
1
+ {"version":3,"file":"FormDecoratorsApi.esm.js","sources":["../../../src/alpha/api/FormDecoratorsApi.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n ApiBlueprint,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { ScaffolderFormDecoratorsApi } from './types';\nimport { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApiRef } from './ref';\nimport { FormDecoratorBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\n\n/** @alpha */\nexport class DefaultScaffolderFormDecoratorsApi\n implements ScaffolderFormDecoratorsApi\n{\n private constructor(\n private readonly options: {\n decorators: Array<ScaffolderFormDecorator>;\n },\n ) {}\n\n static create(options?: { decorators: ScaffolderFormDecorator[] }) {\n return new DefaultScaffolderFormDecoratorsApi(\n options ?? { decorators: [] },\n );\n }\n\n async getFormDecorators(): Promise<ScaffolderFormDecorator[]> {\n return this.options.decorators;\n }\n}\n\n/** @alpha */\nexport const formDecoratorsApi = ApiBlueprint.makeWithOverrides({\n name: 'form-decorators',\n inputs: {\n formDecorators: createExtensionInput([\n FormDecoratorBlueprint.dataRefs.formDecoratorLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formDecorators = inputs.formDecorators.map(e =>\n e.get(FormDecoratorBlueprint.dataRefs.formDecoratorLoader),\n );\n\n return originalFactory(define =>\n define({\n api: formDecoratorsApiRef,\n deps: {},\n factory: () =>\n DefaultScaffolderFormDecoratorsApi.create({\n decorators: formDecorators,\n }),\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,kCAEb,CAAA;AAAA,EACU,YACW,OAGjB,EAAA;AAHiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA;AAGhB,EAEH,OAAO,OAAO,OAAqD,EAAA;AACjE,IAAA,OAAO,IAAI,kCAAA;AAAA,MACT,OAAW,IAAA,EAAE,UAAY,EAAA,EAAG;AAAA,KAC9B;AAAA;AACF,EAEA,MAAM,iBAAwD,GAAA;AAC5D,IAAA,OAAO,KAAK,OAAQ,CAAA,UAAA;AAAA;AAExB;AAGa,MAAA,iBAAA,GAAoB,aAAa,iBAAkB,CAAA;AAAA,EAC9D,IAAM,EAAA,iBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,gBAAgB,oBAAqB,CAAA;AAAA,MACnC,uBAAuB,QAAS,CAAA;AAAA,KACjC;AAAA,GACH;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAM,MAAA,cAAA,GAAiB,OAAO,cAAe,CAAA,GAAA;AAAA,MAAI,CAC/C,CAAA,KAAA,CAAA,CAAE,GAAI,CAAA,sBAAA,CAAuB,SAAS,mBAAmB;AAAA,KAC3D;AAEA,IAAO,OAAA,eAAA;AAAA,MAAgB,YACrB,MAAO,CAAA;AAAA,QACL,GAAK,EAAA,oBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,OAAA,EAAS,MACP,kCAAA,CAAmC,MAAO,CAAA;AAAA,UACxC,UAAY,EAAA;AAAA,SACb;AAAA,OACJ;AAAA,KACH;AAAA;AAEJ,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../../lib/download';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText\n primary={t('templateEditorPage.dryRunResultsList.title', {\n resultId: `${result.id}`,\n })}\n />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title={t(\n 'templateEditorPage.dryRunResultsList.downloadButtonTitle',\n )}\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title={t(\n 'templateEditorPage.dryRunResultsList.deleteButtonTitle',\n )}\n onClick={() => dryRun.deleteResult(result.id)}\n >\n <DeleteIcon />\n </IconButton>\n </ListItemSecondaryAction>\n </ListItem>\n );\n })}\n </List>\n );\n}\n\nasync function downloadDirectoryContents(\n directoryContents: {\n path: string;\n base64Content: string;\n executable: boolean;\n }[],\n name: string,\n) {\n const { default: JSZip } = await import('jszip');\n const zip = new JSZip();\n\n for (const d of directoryContents) {\n // Decode text content from base64 to ascii\n const converted = atob(d.base64Content);\n\n // add folder/file to zip\n await zip.file(d.path, converted);\n }\n\n const blob = await zip.generateAsync({ type: 'blob' });\n downloadBlob(blob, name);\n}\n"],"names":["CancelIcon"],"mappings":"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"}
1
+ {"version":3,"file":"DryRunResultsList.esm.js","sources":["../../../../../src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 IconButton from '@material-ui/core/IconButton';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport CheckIcon from '@material-ui/icons/Check';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport DownloadIcon from '@material-ui/icons/GetApp';\nimport { useDryRun } from '../DryRunContext';\nimport { downloadBlob } from '../../../../lib/download';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../../translation';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n overflowY: 'auto',\n background: theme.palette.background.default,\n },\n iconSuccess: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.ok,\n },\n iconFailure: {\n minWidth: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.status.error,\n },\n}));\n\nexport function DryRunResultsList() {\n const classes = useStyles();\n const dryRun = useDryRun();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n return (\n <List className={classes.root} dense>\n {dryRun.results.map(result => {\n const failed = result.log.some(l => l.body.status === 'failed');\n let isLoading = false;\n\n async function downloadResult() {\n isLoading = true;\n await downloadDirectoryContents(\n result.directoryContents,\n `dry-run-result-${result.id}.zip`,\n );\n isLoading = false;\n }\n\n return (\n <ListItem\n button\n key={result.id}\n selected={dryRun.selectedResult?.id === result.id}\n onClick={() => dryRun.selectResult(result.id)}\n >\n <ListItemIcon\n className={failed ? classes.iconFailure : classes.iconSuccess}\n >\n {failed ? <CancelIcon /> : <CheckIcon />}\n </ListItemIcon>\n <ListItemText\n primary={t('templateEditorPage.dryRunResultsList.title', {\n resultId: `${result.id}`,\n })}\n />\n <ListItemSecondaryAction>\n <IconButton\n edge=\"end\"\n aria-label=\"download\"\n title={t(\n 'templateEditorPage.dryRunResultsList.downloadButtonTitle',\n )}\n disabled={isLoading}\n onClick={() => downloadResult()}\n >\n <DownloadIcon />\n </IconButton>\n <IconButton\n edge=\"end\"\n aria-label=\"delete\"\n title={t(\n 'templateEditorPage.dryRunResultsList.deleteButtonTitle',\n )}\n onClick={() => dryRun.deleteResult(result.id)}\n >\n <DeleteIcon />\n </IconButton>\n </ListItemSecondaryAction>\n </ListItem>\n );\n })}\n </List>\n );\n}\n\nasync function downloadDirectoryContents(\n directoryContents: {\n path: string;\n base64Content: string;\n executable?: boolean;\n }[],\n name: string,\n) {\n const { default: JSZip } = await import('jszip');\n const zip = new JSZip();\n\n for (const d of directoryContents) {\n // Decode text content from base64 to ascii\n const converted = atob(d.base64Content);\n\n // add folder/file to zip\n await zip.file(d.path, converted);\n }\n\n const blob = await zip.generateAsync({ type: 'blob' });\n downloadBlob(blob, name);\n}\n"],"names":["CancelIcon"],"mappings":";;;;;;;;;;;;;;;;;AAgCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,SAAW,EAAA,MAAA;AAAA,IACX,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA;AAAA,GACvC;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,CAAA;AAAA,IACV,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5B,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA;AAAA,GAC9B;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,CAAA;AAAA,IACV,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5B,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA;AAAA;AAEhC,CAAE,CAAA,CAAA;AAEK,SAAS,iBAAoB,GAAA;AAClC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,SAAS,SAAU,EAAA;AACzB,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA;AAExD,EACE,uBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,IAAA,EAAM,OAAK,IACjC,EAAA,QAAA,EAAA,MAAA,CAAO,OAAQ,CAAA,GAAA,CAAI,CAAU,MAAA,KAAA;AAC5B,IAAM,MAAA,MAAA,GAAS,OAAO,GAAI,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,IAAA,CAAK,WAAW,QAAQ,CAAA;AAC9D,IAAA,IAAI,SAAY,GAAA,KAAA;AAEhB,IAAA,eAAe,cAAiB,GAAA;AAC9B,MAAY,SAAA,GAAA,IAAA;AACZ,MAAM,MAAA,yBAAA;AAAA,QACJ,MAAO,CAAA,iBAAA;AAAA,QACP,CAAA,eAAA,EAAkB,OAAO,EAAE,CAAA,IAAA;AAAA,OAC7B;AACA,MAAY,SAAA,GAAA,KAAA;AAAA;AAGd,IACE,uBAAA,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,MAAM,EAAA,IAAA;AAAA,QAEN,QAAU,EAAA,MAAA,CAAO,cAAgB,EAAA,EAAA,KAAO,MAAO,CAAA,EAAA;AAAA,QAC/C,OAAS,EAAA,MAAM,MAAO,CAAA,YAAA,CAAa,OAAO,EAAE,CAAA;AAAA,QAE5C,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,SAAW,EAAA,MAAA,GAAS,OAAQ,CAAA,WAAA,GAAc,OAAQ,CAAA,WAAA;AAAA,cAEjD,QAAS,EAAA,MAAA,mBAAA,GAAA,CAACA,MAAW,EAAA,EAAA,CAAA,uBAAM,SAAU,EAAA,EAAA;AAAA;AAAA,WACxC;AAAA,0BACA,GAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,EAAE,4CAA8C,EAAA;AAAA,gBACvD,QAAA,EAAU,CAAG,EAAA,MAAA,CAAO,EAAE,CAAA;AAAA,eACvB;AAAA;AAAA,WACH;AAAA,+BACC,uBACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAK,EAAA,KAAA;AAAA,gBACL,YAAW,EAAA,UAAA;AAAA,gBACX,KAAO,EAAA,CAAA;AAAA,kBACL;AAAA,iBACF;AAAA,gBACA,QAAU,EAAA,SAAA;AAAA,gBACV,OAAA,EAAS,MAAM,cAAe,EAAA;AAAA,gBAE9B,8BAAC,YAAa,EAAA,EAAA;AAAA;AAAA,aAChB;AAAA,4BACA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAK,EAAA,KAAA;AAAA,gBACL,YAAW,EAAA,QAAA;AAAA,gBACX,KAAO,EAAA,CAAA;AAAA,kBACL;AAAA,iBACF;AAAA,gBACA,OAAS,EAAA,MAAM,MAAO,CAAA,YAAA,CAAa,OAAO,EAAE,CAAA;AAAA,gBAE5C,8BAAC,UAAW,EAAA,EAAA;AAAA;AAAA;AACd,WACF,EAAA;AAAA;AAAA,OAAA;AAAA,MApCK,MAAO,CAAA;AAAA,KAqCd;AAAA,GAEH,CACH,EAAA,CAAA;AAEJ;AAEA,eAAe,yBAAA,CACb,mBAKA,IACA,EAAA;AACA,EAAA,MAAM,EAAE,OAAS,EAAA,KAAA,EAAU,GAAA,MAAM,OAAO,OAAO,CAAA;AAC/C,EAAM,MAAA,GAAA,GAAM,IAAI,KAAM,EAAA;AAEtB,EAAA,KAAA,MAAW,KAAK,iBAAmB,EAAA;AAEjC,IAAM,MAAA,SAAA,GAAY,IAAK,CAAA,CAAA,CAAE,aAAa,CAAA;AAGtC,IAAA,MAAM,GAAI,CAAA,IAAA,CAAK,CAAE,CAAA,IAAA,EAAM,SAAS,CAAA;AAAA;AAGlC,EAAA,MAAM,OAAO,MAAM,GAAA,CAAI,cAAc,EAAE,IAAA,EAAM,QAAQ,CAAA;AACrD,EAAA,YAAA,CAAa,MAAM,IAAI,CAAA;AACzB;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { convertLegacyRouteRef, compatWrapper } from '@backstage/core-compat-api';
3
- import { PageBlueprint, createExtensionInput, NavItemBlueprint, ApiBlueprint, createApiFactory, discoveryApiRef, fetchApiRef, identityApiRef } from '@backstage/frontend-plugin-api';
3
+ import { PageBlueprint, createExtensionInput, NavItemBlueprint, ApiBlueprint, discoveryApiRef, fetchApiRef, identityApiRef } from '@backstage/frontend-plugin-api';
4
4
  import { rootRouteRef } from '../routes.esm.js';
5
5
  import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
6
6
  import { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha';
@@ -43,23 +43,21 @@ const repoUrlPickerFormField = FormFieldBlueprint.make({
43
43
  }
44
44
  });
45
45
  const scaffolderApi = ApiBlueprint.make({
46
- params: {
47
- factory: createApiFactory({
48
- api: scaffolderApiRef,
49
- deps: {
50
- discoveryApi: discoveryApiRef,
51
- scmIntegrationsApi: scmIntegrationsApiRef,
52
- fetchApi: fetchApiRef,
53
- identityApi: identityApiRef
54
- },
55
- factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => new ScaffolderClient({
56
- discoveryApi,
57
- scmIntegrationsApi,
58
- fetchApi,
59
- identityApi
60
- })
46
+ params: (define) => define({
47
+ api: scaffolderApiRef,
48
+ deps: {
49
+ discoveryApi: discoveryApiRef,
50
+ scmIntegrationsApi: scmIntegrationsApiRef,
51
+ fetchApi: fetchApiRef,
52
+ identityApi: identityApiRef
53
+ },
54
+ factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => new ScaffolderClient({
55
+ discoveryApi,
56
+ scmIntegrationsApi,
57
+ fetchApi,
58
+ identityApi
61
59
  })
62
- }
60
+ })
63
61
  });
64
62
 
65
63
  export { repoUrlPickerFormField, scaffolderApi, scaffolderNavItem, scaffolderPage };
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.esm.js","sources":["../../src/alpha/extensions.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 {\n compatWrapper,\n convertLegacyRouteRef,\n} from '@backstage/core-compat-api';\nimport {\n NavItemBlueprint,\n PageBlueprint,\n ApiBlueprint,\n createApiFactory,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { rootRouteRef } from '../routes';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\nimport { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport { ScaffolderClient } from '../api';\n\nexport const scaffolderPage = PageBlueprint.makeWithOverrides({\n inputs: {\n formFields: createExtensionInput([\n FormFieldBlueprint.dataRefs.formFieldLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formFieldLoaders = inputs.formFields.map(i =>\n i.get(FormFieldBlueprint.dataRefs.formFieldLoader),\n );\n return originalFactory({\n routeRef: convertLegacyRouteRef(rootRouteRef),\n defaultPath: '/create',\n loader: () =>\n import('../components/Router/Router').then(m =>\n compatWrapper(\n <m.InternalRouter formFieldLoaders={formFieldLoaders} />,\n ),\n ),\n });\n },\n});\n\nexport const scaffolderNavItem = NavItemBlueprint.make({\n params: {\n routeRef: convertLegacyRouteRef(rootRouteRef),\n title: 'Create...',\n icon: CreateComponentIcon,\n },\n});\n\nexport const repoUrlPickerFormField = FormFieldBlueprint.make({\n name: 'repo-url-picker',\n params: {\n field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker),\n },\n});\n\nexport const scaffolderApi = ApiBlueprint.make({\n params: {\n factory: createApiFactory({\n api: scaffolderApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n scmIntegrationsApi: scmIntegrationsApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) =>\n new ScaffolderClient({\n discoveryApi,\n scmIntegrationsApi,\n fetchApi,\n identityApi,\n }),\n }),\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;AAqCa,MAAA,cAAA,GAAiB,cAAc,iBAAkB,CAAA;AAAA,EAC5D,MAAQ,EAAA;AAAA,IACN,YAAY,oBAAqB,CAAA;AAAA,MAC/B,mBAAmB,QAAS,CAAA;AAAA,KAC7B;AAAA,GACH;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAM,MAAA,gBAAA,GAAmB,OAAO,UAAW,CAAA,GAAA;AAAA,MAAI,CAC7C,CAAA,KAAA,CAAA,CAAE,GAAI,CAAA,kBAAA,CAAmB,SAAS,eAAe;AAAA,KACnD;AACA,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,MAC5C,WAAa,EAAA,SAAA;AAAA,MACb,MAAQ,EAAA,MACN,OAAO,oCAA6B,CAAE,CAAA,IAAA;AAAA,QAAK,CACzC,CAAA,KAAA,aAAA;AAAA,0BACG,GAAA,CAAA,CAAA,CAAE,cAAF,EAAA,EAAiB,gBAAoC,EAAA;AAAA;AACxD;AACF,KACH,CAAA;AAAA;AAEL,CAAC;AAEY,MAAA,iBAAA,GAAoB,iBAAiB,IAAK,CAAA;AAAA,EACrD,MAAQ,EAAA;AAAA,IACN,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,IAC5C,KAAO,EAAA,WAAA;AAAA,IACP,IAAM,EAAA;AAAA;AAEV,CAAC;AAEY,MAAA,sBAAA,GAAyB,mBAAmB,IAAK,CAAA;AAAA,EAC5D,IAAM,EAAA,iBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,KAAA,EAAO,MAAM,OAAO,+BAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,aAAa;AAAA;AAE3E,CAAC;AAEY,MAAA,aAAA,GAAgB,aAAa,IAAK,CAAA;AAAA,EAC7C,MAAQ,EAAA;AAAA,IACN,SAAS,gBAAiB,CAAA;AAAA,MACxB,GAAK,EAAA,gBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,kBAAoB,EAAA,qBAAA;AAAA,QACpB,QAAU,EAAA,WAAA;AAAA,QACV,WAAa,EAAA;AAAA,OACf;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,oBAAoB,QAAU,EAAA,WAAA,EACtD,KAAA,IAAI,gBAAiB,CAAA;AAAA,QACnB,YAAA;AAAA,QACA,kBAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACD;AAAA,KACJ;AAAA;AAEL,CAAC;;;;"}
1
+ {"version":3,"file":"extensions.esm.js","sources":["../../src/alpha/extensions.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 {\n compatWrapper,\n convertLegacyRouteRef,\n} from '@backstage/core-compat-api';\nimport {\n NavItemBlueprint,\n PageBlueprint,\n ApiBlueprint,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { rootRouteRef } from '../routes';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\nimport { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha';\nimport { scmIntegrationsApiRef } from '@backstage/integration-react';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport { ScaffolderClient } from '../api';\n\nexport const scaffolderPage = PageBlueprint.makeWithOverrides({\n inputs: {\n formFields: createExtensionInput([\n FormFieldBlueprint.dataRefs.formFieldLoader,\n ]),\n },\n factory(originalFactory, { inputs }) {\n const formFieldLoaders = inputs.formFields.map(i =>\n i.get(FormFieldBlueprint.dataRefs.formFieldLoader),\n );\n return originalFactory({\n routeRef: convertLegacyRouteRef(rootRouteRef),\n defaultPath: '/create',\n loader: () =>\n import('../components/Router/Router').then(m =>\n compatWrapper(\n <m.InternalRouter formFieldLoaders={formFieldLoaders} />,\n ),\n ),\n });\n },\n});\n\nexport const scaffolderNavItem = NavItemBlueprint.make({\n params: {\n routeRef: convertLegacyRouteRef(rootRouteRef),\n title: 'Create...',\n icon: CreateComponentIcon,\n },\n});\n\nexport const repoUrlPickerFormField = FormFieldBlueprint.make({\n name: 'repo-url-picker',\n params: {\n field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker),\n },\n});\n\nexport const scaffolderApi = ApiBlueprint.make({\n params: define =>\n define({\n api: scaffolderApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n scmIntegrationsApi: scmIntegrationsApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) =>\n new ScaffolderClient({\n discoveryApi,\n scmIntegrationsApi,\n fetchApi,\n identityApi,\n }),\n }),\n});\n"],"names":[],"mappings":";;;;;;;;;;AAoCa,MAAA,cAAA,GAAiB,cAAc,iBAAkB,CAAA;AAAA,EAC5D,MAAQ,EAAA;AAAA,IACN,YAAY,oBAAqB,CAAA;AAAA,MAC/B,mBAAmB,QAAS,CAAA;AAAA,KAC7B;AAAA,GACH;AAAA,EACA,OAAQ,CAAA,eAAA,EAAiB,EAAE,MAAA,EAAU,EAAA;AACnC,IAAM,MAAA,gBAAA,GAAmB,OAAO,UAAW,CAAA,GAAA;AAAA,MAAI,CAC7C,CAAA,KAAA,CAAA,CAAE,GAAI,CAAA,kBAAA,CAAmB,SAAS,eAAe;AAAA,KACnD;AACA,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,MAC5C,WAAa,EAAA,SAAA;AAAA,MACb,MAAQ,EAAA,MACN,OAAO,oCAA6B,CAAE,CAAA,IAAA;AAAA,QAAK,CACzC,CAAA,KAAA,aAAA;AAAA,0BACG,GAAA,CAAA,CAAA,CAAE,cAAF,EAAA,EAAiB,gBAAoC,EAAA;AAAA;AACxD;AACF,KACH,CAAA;AAAA;AAEL,CAAC;AAEY,MAAA,iBAAA,GAAoB,iBAAiB,IAAK,CAAA;AAAA,EACrD,MAAQ,EAAA;AAAA,IACN,QAAA,EAAU,sBAAsB,YAAY,CAAA;AAAA,IAC5C,KAAO,EAAA,WAAA;AAAA,IACP,IAAM,EAAA;AAAA;AAEV,CAAC;AAEY,MAAA,sBAAA,GAAyB,mBAAmB,IAAK,CAAA;AAAA,EAC5D,IAAM,EAAA,iBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,KAAA,EAAO,MAAM,OAAO,+BAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,aAAa;AAAA;AAE3E,CAAC;AAEY,MAAA,aAAA,GAAgB,aAAa,IAAK,CAAA;AAAA,EAC7C,MAAA,EAAQ,YACN,MAAO,CAAA;AAAA,IACL,GAAK,EAAA,gBAAA;AAAA,IACL,IAAM,EAAA;AAAA,MACJ,YAAc,EAAA,eAAA;AAAA,MACd,kBAAoB,EAAA,qBAAA;AAAA,MACpB,QAAU,EAAA,WAAA;AAAA,MACV,WAAa,EAAA;AAAA,KACf;AAAA,IACA,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,oBAAoB,QAAU,EAAA,WAAA,EACtD,KAAA,IAAI,gBAAiB,CAAA;AAAA,MACnB,YAAA;AAAA,MACA,kBAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACD;AAAA,GACJ;AACL,CAAC;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -285,34 +285,9 @@ declare const formDecoratorsApi: _backstage_frontend_plugin_api.ExtensionDefinit
285
285
  };
286
286
  kind: "api";
287
287
  name: "form-decorators";
288
- params: {
289
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
290
- };
288
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
291
289
  }>;
292
290
 
293
- /*
294
- * Copyright 2024 The Backstage Authors
295
- *
296
- * Licensed under the Apache License, Version 2.0 (the "License");
297
- * you may not use this file except in compliance with the License.
298
- * You may obtain a copy of the License at
299
- *
300
- * http://www.apache.org/licenses/LICENSE-2.0
301
- *
302
- * Unless required by applicable law or agreed to in writing, software
303
- * distributed under the License is distributed on an "AS IS" BASIS,
304
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
305
- * See the License for the specific language governing permissions and
306
- * limitations under the License.
307
- */
308
-
309
-
310
-
311
- /** @alpha */
312
- interface FormField {
313
- readonly $$type: '@backstage/scaffolder/FormField';
314
- }
315
-
316
291
  /** @alpha */
317
292
  declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
318
293
  root: _backstage_frontend_plugin_api.RouteRef<undefined>;
@@ -337,9 +312,7 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
337
312
  configInput: {};
338
313
  output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
339
314
  inputs: {};
340
- params: {
341
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
342
- };
315
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
343
316
  }>;
344
317
  "api:scaffolder/form-decorators": _backstage_frontend_plugin_api.ExtensionDefinition<{
345
318
  config: {};
@@ -353,25 +326,21 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
353
326
  };
354
327
  kind: "api";
355
328
  name: "form-decorators";
356
- params: {
357
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
358
- };
329
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
359
330
  }>;
360
331
  "api:scaffolder/form-fields": _backstage_frontend_plugin_api.ExtensionDefinition<{
361
332
  config: {};
362
333
  configInput: {};
363
334
  output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
364
335
  inputs: {
365
- formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>, {
336
+ formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<_backstage_plugin_scaffolder_react_alpha.FormField>, "scaffolder.form-field-loader", {}>, {
366
337
  singleton: false;
367
338
  optional: false;
368
339
  }>;
369
340
  };
370
341
  kind: "api";
371
342
  name: "form-fields";
372
- params: {
373
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
374
- };
343
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
375
344
  }>;
376
345
  "entity-icon-link:scaffolder/launch-template": _backstage_frontend_plugin_api.ExtensionDefinition<{
377
346
  kind: "entity-icon-link";
@@ -425,7 +394,7 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
425
394
  optional: true;
426
395
  }>;
427
396
  inputs: {
428
- formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>, {
397
+ formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<_backstage_plugin_scaffolder_react_alpha.FormField>, "scaffolder.form-field-loader", {}>, {
429
398
  singleton: false;
430
399
  optional: false;
431
400
  }>;
@@ -443,10 +412,10 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
443
412
  name: "repo-url-picker";
444
413
  config: {};
445
414
  configInput: {};
446
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>;
415
+ output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<_backstage_plugin_scaffolder_react_alpha.FormField>, "scaffolder.form-field-loader", {}>;
447
416
  inputs: {};
448
417
  params: {
449
- field: () => Promise<FormField>;
418
+ field: () => Promise<_backstage_plugin_scaffolder_react_alpha.FormField>;
450
419
  };
451
420
  }>;
452
421
  }>;
package/dist/api.esm.js CHANGED
@@ -1,272 +1,6 @@
1
- import { parseEntityRef } from '@backstage/catalog-model';
2
- import { ResponseError } from '@backstage/errors';
3
- import { fetchEventSource } from '@microsoft/fetch-event-source';
4
- import qs from 'qs';
5
- import ObservableImpl from 'zen-observable';
1
+ import { ScaffolderClient as ScaffolderClient$1 } from '@backstage/plugin-scaffolder-common';
6
2
 
7
- class ScaffolderClient {
8
- discoveryApi;
9
- scmIntegrationsApi;
10
- fetchApi;
11
- identityApi;
12
- useLongPollingLogs;
13
- constructor(options) {
14
- this.discoveryApi = options.discoveryApi;
15
- this.fetchApi = options.fetchApi ?? { fetch };
16
- this.scmIntegrationsApi = options.scmIntegrationsApi;
17
- this.useLongPollingLogs = options.useLongPollingLogs ?? false;
18
- this.identityApi = options.identityApi;
19
- }
20
- async listTasks(options) {
21
- if (!this.identityApi) {
22
- throw new Error(
23
- "IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method"
24
- );
25
- }
26
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
27
- const { userEntityRef } = await this.identityApi.getBackstageIdentity();
28
- const query = qs.stringify({
29
- createdBy: options.filterByOwnership === "owned" ? userEntityRef : void 0,
30
- limit: options.limit,
31
- offset: options.offset
32
- });
33
- const response = await this.fetchApi.fetch(`${baseUrl}/v2/tasks?${query}`);
34
- if (!response.ok) {
35
- throw await ResponseError.fromResponse(response);
36
- }
37
- return await response.json();
38
- }
39
- async getIntegrationsList(options) {
40
- const integrations = [
41
- ...this.scmIntegrationsApi.azure.list(),
42
- ...this.scmIntegrationsApi.bitbucket.list().filter(
43
- (item) => !this.scmIntegrationsApi.bitbucketCloud.byHost(item.config.host) && !this.scmIntegrationsApi.bitbucketServer.byHost(item.config.host)
44
- ),
45
- ...this.scmIntegrationsApi.bitbucketCloud.list(),
46
- ...this.scmIntegrationsApi.bitbucketServer.list(),
47
- ...this.scmIntegrationsApi.gerrit.list(),
48
- ...this.scmIntegrationsApi.gitea.list(),
49
- ...this.scmIntegrationsApi.github.list(),
50
- ...this.scmIntegrationsApi.gitlab.list()
51
- ].map((c) => ({ type: c.type, title: c.title, host: c.config.host })).filter((c) => options.allowedHosts.includes(c.host));
52
- return {
53
- integrations
54
- };
55
- }
56
- async getTemplateParameterSchema(templateRef) {
57
- const { namespace, kind, name } = parseEntityRef(templateRef, {
58
- defaultKind: "template"
59
- });
60
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
61
- const templatePath = [namespace, kind, name].map((s) => encodeURIComponent(s)).join("/");
62
- const url = `${baseUrl}/v2/templates/${templatePath}/parameter-schema`;
63
- const response = await this.fetchApi.fetch(url);
64
- if (!response.ok) {
65
- throw await ResponseError.fromResponse(response);
66
- }
67
- const schema = await response.json();
68
- return schema;
69
- }
70
- async scaffold(options) {
71
- const { templateRef, values, secrets = {} } = options;
72
- const url = `${await this.discoveryApi.getBaseUrl("scaffolder")}/v2/tasks`;
73
- const response = await this.fetchApi.fetch(url, {
74
- method: "POST",
75
- headers: {
76
- "Content-Type": "application/json"
77
- },
78
- body: JSON.stringify({
79
- templateRef,
80
- values: { ...values },
81
- secrets
82
- })
83
- });
84
- if (response.status !== 201) {
85
- const status = `${response.status} ${response.statusText}`;
86
- const body = await response.text();
87
- throw new Error(`Backend request failed, ${status} ${body.trim()}`);
88
- }
89
- const { id } = await response.json();
90
- return { taskId: id };
91
- }
92
- async getTask(taskId) {
93
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
94
- const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;
95
- const response = await this.fetchApi.fetch(url);
96
- if (!response.ok) {
97
- throw await ResponseError.fromResponse(response);
98
- }
99
- return await response.json();
100
- }
101
- streamLogs(options) {
102
- if (this.useLongPollingLogs) {
103
- return this.streamLogsPolling(options);
104
- }
105
- return this.streamLogsEventStream(options);
106
- }
107
- async dryRun(options) {
108
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
109
- const response = await this.fetchApi.fetch(`${baseUrl}/v2/dry-run`, {
110
- method: "POST",
111
- headers: {
112
- "Content-Type": "application/json"
113
- },
114
- body: JSON.stringify({
115
- template: options.template,
116
- values: options.values,
117
- secrets: options.secrets,
118
- directoryContents: options.directoryContents
119
- })
120
- });
121
- if (!response.ok) {
122
- throw await ResponseError.fromResponse(response);
123
- }
124
- return response.json();
125
- }
126
- streamLogsEventStream({
127
- isTaskRecoverable,
128
- taskId,
129
- after
130
- }) {
131
- return new ObservableImpl((subscriber) => {
132
- const params = new URLSearchParams();
133
- if (after !== void 0) {
134
- params.set("after", String(Number(after)));
135
- }
136
- this.discoveryApi.getBaseUrl("scaffolder").then(
137
- (baseUrl) => {
138
- const url = `${baseUrl}/v2/tasks/${encodeURIComponent(
139
- taskId
140
- )}/eventstream`;
141
- const processEvent = (event) => {
142
- if (event.data) {
143
- try {
144
- subscriber.next(JSON.parse(event.data));
145
- } catch (ex) {
146
- subscriber.error(ex);
147
- }
148
- }
149
- };
150
- const ctrl = new AbortController();
151
- void fetchEventSource(url, {
152
- fetch: this.fetchApi.fetch,
153
- signal: ctrl.signal,
154
- onmessage(e) {
155
- if (e.event === "log") {
156
- processEvent(e);
157
- return;
158
- } else if (e.event === "completion" && !isTaskRecoverable) {
159
- processEvent(e);
160
- subscriber.complete();
161
- ctrl.abort();
162
- return;
163
- }
164
- processEvent(e);
165
- },
166
- onerror(err) {
167
- subscriber.error(err);
168
- }
169
- });
170
- },
171
- (error) => {
172
- subscriber.error(error);
173
- }
174
- );
175
- });
176
- }
177
- streamLogsPolling({
178
- taskId,
179
- after: inputAfter
180
- }) {
181
- let after = inputAfter;
182
- return new ObservableImpl((subscriber) => {
183
- this.discoveryApi.getBaseUrl("scaffolder").then(async (baseUrl) => {
184
- while (!subscriber.closed) {
185
- const url = `${baseUrl}/v2/tasks/${encodeURIComponent(
186
- taskId
187
- )}/events?${qs.stringify({ after })}`;
188
- const response = await this.fetchApi.fetch(url);
189
- if (!response.ok) {
190
- await new Promise((resolve) => setTimeout(resolve, 1e3));
191
- continue;
192
- }
193
- const logs = await response.json();
194
- for (const event of logs) {
195
- after = Number(event.id);
196
- subscriber.next(event);
197
- if (event.type === "completion") {
198
- subscriber.complete();
199
- return;
200
- }
201
- }
202
- }
203
- });
204
- });
205
- }
206
- async listActions() {
207
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
208
- const response = await this.fetchApi.fetch(`${baseUrl}/v2/actions`);
209
- if (!response.ok) {
210
- throw await ResponseError.fromResponse(response);
211
- }
212
- return await response.json();
213
- }
214
- async listTemplatingExtensions() {
215
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
216
- const response = await this.fetchApi.fetch(
217
- `${baseUrl}/v2/templating-extensions`
218
- );
219
- if (!response.ok) {
220
- throw ResponseError.fromResponse(response);
221
- }
222
- return response.json();
223
- }
224
- async cancelTask(taskId) {
225
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
226
- const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/cancel`;
227
- const response = await this.fetchApi.fetch(url, {
228
- method: "POST"
229
- });
230
- if (!response.ok) {
231
- throw await ResponseError.fromResponse(response);
232
- }
233
- return await response.json();
234
- }
235
- async retry(taskId) {
236
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
237
- const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/retry`;
238
- const response = await this.fetchApi.fetch(url, {
239
- method: "POST"
240
- });
241
- if (!response.ok) {
242
- throw await ResponseError.fromResponse(response);
243
- }
244
- return await response.json();
245
- }
246
- async autocomplete({
247
- token,
248
- resource,
249
- provider,
250
- context
251
- }) {
252
- const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
253
- const url = `${baseUrl}/v2/autocomplete/${provider}/${resource}`;
254
- const response = await this.fetchApi.fetch(url, {
255
- method: "POST",
256
- headers: {
257
- "Content-Type": "application/json"
258
- },
259
- body: JSON.stringify({
260
- token,
261
- context: context ?? {}
262
- })
263
- });
264
- if (!response.ok) {
265
- throw await ResponseError.fromResponse(response);
266
- }
267
- const { results } = await response.json();
268
- return { results };
269
- }
3
+ class ScaffolderClient extends ScaffolderClient$1 {
270
4
  }
271
5
 
272
6
  export { ScaffolderClient };
@@ -1 +1 @@
1
- {"version":3,"file":"api.esm.js","sources":["../src/api.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport {\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n TemplateParameterSchema,\n} from '@backstage/plugin-scaffolder-react';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport { default as qs, default as queryString } from 'qs';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: FetchApi;\n private readonly identityApi?: IdentityApi;\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n identityApi?: IdentityApi;\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n async listTasks(options: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n }): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n const query = queryString.stringify({\n createdBy:\n options.filterByOwnership === 'owned' ? userEntityRef : undefined,\n limit: options.limit,\n offset: options.offset,\n });\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/tasks?${query}`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucket\n .list()\n .filter(\n item =>\n !this.scmIntegrationsApi.bitbucketCloud.byHost(item.config.host) &&\n !this.scmIntegrationsApi.bitbucketServer.byHost(item.config.host),\n ),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n async getTemplateParameterSchema(\n templateRef: string,\n ): Promise<TemplateParameterSchema> {\n const { namespace, kind, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const templatePath = [namespace, kind, name]\n .map(s => encodeURIComponent(s))\n .join('/');\n\n const url = `${baseUrl}/v2/templates/${templatePath}/parameter-schema`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const schema: TemplateParameterSchema = await response.json();\n return schema;\n }\n\n async scaffold(\n options: ScaffolderScaffoldOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const { templateRef, values, secrets = {} } = options;\n const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v2/tasks`;\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n templateRef,\n values: { ...values },\n secrets,\n }),\n });\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = (await response.json()) as { id: string };\n return { taskId: id };\n }\n\n async getTask(taskId: string): Promise<ScaffolderTask> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(options);\n }\n\n return this.streamLogsEventStream(options);\n }\n\n async dryRun(\n options: ScaffolderDryRunOptions,\n ): Promise<ScaffolderDryRunResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/dry-run`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n template: options.template,\n values: options.values,\n secrets: options.secrets,\n directoryContents: options.directoryContents,\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n const ctrl = new AbortController();\n void fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onerror(err) {\n subscriber.error(err);\n },\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n });\n }\n\n private streamLogsPolling({\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n }): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n this.discoveryApi.getBaseUrl('scaffolder').then(async baseUrl => {\n while (!subscriber.closed) {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/events?${qs.stringify({ after })}`;\n const response = await this.fetchApi.fetch(url);\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n });\n });\n }\n\n async listActions(): Promise<ListActionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/actions`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async listTemplatingExtensions(): Promise<ListTemplatingExtensionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/templating-extensions`,\n );\n if (!response.ok) {\n throw ResponseError.fromResponse(response);\n }\n return response.json();\n }\n\n async cancelTask(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/cancel`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async retry?(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/retry`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async autocomplete({\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context?: Record<string, string>;\n }): Promise<{ results: { title?: string; id: string }[] }> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n\n const url = `${baseUrl}/v2/autocomplete/${provider}/${resource}`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n token,\n context: context ?? {},\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { results } = await response.json();\n return { results };\n }\n}\n"],"names":["queryString"],"mappings":"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"}
1
+ {"version":3,"file":"api.esm.js","sources":["../src/api.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { ScaffolderClient as _ScaffolderClient } from '@backstage/plugin-scaffolder-common';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n * @deprecated use import from {@link @backstage/plugin-scaffolder-common#ScaffolderClient} instead as this has now been moved.\n */\nexport class ScaffolderClient extends _ScaffolderClient {}\n"],"names":["_ScaffolderClient"],"mappings":";;AAwBO,MAAM,yBAAyBA,kBAAkB,CAAA;AAAC;;;;"}
@@ -65,6 +65,9 @@ const getSubschemas = (schema) => {
65
65
  base[key] = value;
66
66
  }
67
67
  }
68
+ if (!(base?.type === "object" || "properties" in base)) {
69
+ return subschemas;
70
+ }
68
71
  return Object.fromEntries(
69
72
  Object.entries(subschemas).map(([key, sub]) => {
70
73
  const mergedSubschema = sub.map((alt) => {
@@ -256,13 +259,15 @@ const RenderSchema = ({
256
259
  let columns;
257
260
  let elements;
258
261
  if (strategy === "root") {
259
- elements = [{ schema }];
260
- columns = [typeColumn];
261
- if (schema.description) {
262
- columns.unshift(descriptionColumn);
263
- }
264
- if (schema.title) {
265
- columns.unshift(titleColumn);
262
+ if ("type" in schema || !Object.keys(subschemas).length) {
263
+ elements = [{ schema }];
264
+ columns = [typeColumn];
265
+ if (schema.description) {
266
+ columns.unshift(descriptionColumn);
267
+ }
268
+ if (schema.title) {
269
+ columns.unshift(titleColumn);
270
+ }
266
271
  }
267
272
  } else if (schema.properties) {
268
273
  columns = [nameColumn, titleColumn, descriptionColumn, typeColumn];