@backstage/plugin-scaffolder 1.21.0-next.2 → 1.21.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 +100 -0
- package/alpha/package.json +1 -1
- package/dist/components/fields/EntityPicker/EntityPicker.esm.js +37 -21
- package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
- package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js +2 -6
- package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
- package/dist/components/fields/SecretInput/SecretInput.esm.js +3 -23
- package/dist/components/fields/SecretInput/SecretInput.esm.js.map +1 -1
- package/package.json +32 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,105 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder
|
|
2
2
|
|
|
3
|
+
## 1.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d57ebbc: Changed the way to display entities in EntityPicker to use entityPresentationApi instead of humanizeEntityRef
|
|
8
|
+
- 62bd9eb: Replace `ui:widget: password` with the a warning message stating that it's not secure and to use the build in `SecretField`.
|
|
9
|
+
|
|
10
|
+
You can do this by updating your `template.yaml` files that have the reference `ui:widget: password` to `ui:field: Secret` instead.
|
|
11
|
+
|
|
12
|
+
```diff
|
|
13
|
+
apiVersion: backstage.io/v1alpha1
|
|
14
|
+
kind: Template
|
|
15
|
+
metadata:
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
spec:
|
|
19
|
+
parameters:
|
|
20
|
+
- title: collect some information
|
|
21
|
+
schema:
|
|
22
|
+
type: object
|
|
23
|
+
properties:
|
|
24
|
+
password:
|
|
25
|
+
title: Password
|
|
26
|
+
type: string
|
|
27
|
+
- ui:widget: password
|
|
28
|
+
+ ui:field: Secret
|
|
29
|
+
steps:
|
|
30
|
+
- id: collect-info
|
|
31
|
+
name: Collect some information
|
|
32
|
+
action: acme:do:something
|
|
33
|
+
input:
|
|
34
|
+
- password: ${{ parameters.password }}
|
|
35
|
+
+ password: ${{ secrets.password }}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- 60085dd: Added the following default targets for external routes:
|
|
39
|
+
|
|
40
|
+
- `registerComponent` binds to the catalog import page.
|
|
41
|
+
- `viewTechDoc` binds to the TechDocs entity documentation page.
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- cbebad1: Internal updates to allow reusing Backstage's `fetchApi` implementation for event source requests. This allows you to for example, override the `Authorization` header.
|
|
46
|
+
- 1ea7679: Removed waiting for the workspace and repository fields to be filled in before requesting user credentials
|
|
47
|
+
- d44a20a: Added additional plugin metadata to `package.json`.
|
|
48
|
+
- 6cb4886: Updated dependency `@rjsf/utils` to `5.18.4`.
|
|
49
|
+
Updated dependency `@rjsf/core` to `5.18.4`.
|
|
50
|
+
Updated dependency `@rjsf/material-ui` to `5.18.4`.
|
|
51
|
+
Updated dependency `@rjsf/validator-ajv8` to `5.18.4`.
|
|
52
|
+
- 75dcd7e: Fixing bug in `formData` type as it should be `optional` as it's possibly undefined
|
|
53
|
+
- bcec60f: updated the ContextMenu, ActionsPage, OngoingTask and TemplateCard frontend components to support the new scaffolder permissions:
|
|
54
|
+
|
|
55
|
+
- `scaffolder.task.create`
|
|
56
|
+
- `scaffolder.task.cancel`
|
|
57
|
+
- `scaffolder.task.read`
|
|
58
|
+
|
|
59
|
+
- 612a453: Change owner to project for azure host
|
|
60
|
+
- Updated dependencies
|
|
61
|
+
- @backstage/core-components@0.14.8
|
|
62
|
+
- @backstage/core-compat-api@0.2.6
|
|
63
|
+
- @backstage/integration@1.12.0
|
|
64
|
+
- @backstage/core-plugin-api@1.9.3
|
|
65
|
+
- @backstage/plugin-scaffolder-react@1.9.0
|
|
66
|
+
- @backstage/plugin-scaffolder-common@1.5.3
|
|
67
|
+
- @backstage/plugin-permission-react@0.4.23
|
|
68
|
+
- @backstage/plugin-catalog-common@1.0.24
|
|
69
|
+
- @backstage/plugin-catalog-react@1.12.1
|
|
70
|
+
- @backstage/integration-react@1.1.28
|
|
71
|
+
- @backstage/frontend-plugin-api@0.6.6
|
|
72
|
+
- @backstage/catalog-client@1.6.5
|
|
73
|
+
- @backstage/catalog-model@1.5.0
|
|
74
|
+
- @backstage/errors@1.2.4
|
|
75
|
+
- @backstage/types@1.1.1
|
|
76
|
+
|
|
77
|
+
## 1.21.0-next.3
|
|
78
|
+
|
|
79
|
+
### Minor Changes
|
|
80
|
+
|
|
81
|
+
- d57ebbc: Changed the way to display entities in EntityPicker to use entityPresentationApi instead of humanizeEntityRef
|
|
82
|
+
|
|
83
|
+
### Patch Changes
|
|
84
|
+
|
|
85
|
+
- d44a20a: Added additional plugin metadata to `package.json`.
|
|
86
|
+
- Updated dependencies
|
|
87
|
+
- @backstage/core-components@0.14.8-next.2
|
|
88
|
+
- @backstage/integration@1.12.0-next.1
|
|
89
|
+
- @backstage/plugin-scaffolder-common@1.5.3-next.1
|
|
90
|
+
- @backstage/plugin-permission-react@0.4.23-next.1
|
|
91
|
+
- @backstage/plugin-scaffolder-react@1.8.7-next.3
|
|
92
|
+
- @backstage/plugin-catalog-common@1.0.24-next.0
|
|
93
|
+
- @backstage/plugin-catalog-react@1.12.1-next.2
|
|
94
|
+
- @backstage/integration-react@1.1.28-next.1
|
|
95
|
+
- @backstage/frontend-plugin-api@0.6.6-next.2
|
|
96
|
+
- @backstage/core-compat-api@0.2.6-next.2
|
|
97
|
+
- @backstage/catalog-client@1.6.5
|
|
98
|
+
- @backstage/catalog-model@1.5.0
|
|
99
|
+
- @backstage/core-plugin-api@1.9.3-next.0
|
|
100
|
+
- @backstage/errors@1.2.4
|
|
101
|
+
- @backstage/types@1.1.1
|
|
102
|
+
|
|
3
103
|
## 1.21.0-next.2
|
|
4
104
|
|
|
5
105
|
### Minor Changes
|
package/alpha/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
|
|
2
|
-
import {
|
|
2
|
+
import { stringifyEntityRef, parseEntityRef } from '@backstage/catalog-model';
|
|
3
3
|
import { useApi } from '@backstage/core-plugin-api';
|
|
4
|
-
import { catalogApiRef,
|
|
4
|
+
import { catalogApiRef, entityPresentationApiRef, EntityDisplayName } from '@backstage/plugin-catalog-react';
|
|
5
5
|
import TextField from '@material-ui/core/TextField';
|
|
6
6
|
import FormControl from '@material-ui/core/FormControl';
|
|
7
|
-
import Autocomplete from '@material-ui/lab/Autocomplete';
|
|
7
|
+
import Autocomplete, { createFilterOptions } from '@material-ui/lab/Autocomplete';
|
|
8
8
|
import React, { useCallback, useEffect } from 'react';
|
|
9
9
|
import useAsync from 'react-use/esm/useAsync';
|
|
10
10
|
export { EntityPickerSchema } from './schema.esm.js';
|
|
@@ -23,26 +23,38 @@ const EntityPicker = (props) => {
|
|
|
23
23
|
const defaultKind = uiSchema["ui:options"]?.defaultKind;
|
|
24
24
|
const defaultNamespace = uiSchema["ui:options"]?.defaultNamespace || void 0;
|
|
25
25
|
const catalogApi = useApi(catalogApiRef);
|
|
26
|
+
const entityPresentationApi = useApi(entityPresentationApiRef);
|
|
26
27
|
const { value: entities, loading } = useAsync(async () => {
|
|
27
|
-
const fields = [
|
|
28
|
+
const fields = [
|
|
29
|
+
"metadata.name",
|
|
30
|
+
"metadata.namespace",
|
|
31
|
+
"metadata.title",
|
|
32
|
+
"kind"
|
|
33
|
+
];
|
|
28
34
|
const { items } = await catalogApi.getEntities(
|
|
29
35
|
catalogFilter ? { filter: catalogFilter, fields } : { filter: void 0, fields }
|
|
30
36
|
);
|
|
31
|
-
|
|
37
|
+
const entityRefToPresentation = new Map(
|
|
38
|
+
await Promise.all(
|
|
39
|
+
items.map(async (item) => {
|
|
40
|
+
const presentation = await entityPresentationApi.forEntity(item).promise;
|
|
41
|
+
return [stringifyEntityRef(item), presentation];
|
|
42
|
+
})
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
return { catalogEntities: items, entityRefToPresentation };
|
|
32
46
|
});
|
|
33
47
|
const allowArbitraryValues = uiSchema["ui:options"]?.allowArbitraryValues ?? true;
|
|
34
48
|
const getLabel = useCallback(
|
|
35
|
-
(
|
|
49
|
+
(freeSoloValue) => {
|
|
36
50
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
);
|
|
51
|
+
const parsedRef = parseEntityRef(freeSoloValue, {
|
|
52
|
+
defaultKind,
|
|
53
|
+
defaultNamespace
|
|
54
|
+
});
|
|
55
|
+
return stringifyEntityRef(parsedRef);
|
|
44
56
|
} catch (err) {
|
|
45
|
-
return
|
|
57
|
+
return freeSoloValue;
|
|
46
58
|
}
|
|
47
59
|
},
|
|
48
60
|
[defaultKind, defaultNamespace]
|
|
@@ -71,10 +83,10 @@ const EntityPicker = (props) => {
|
|
|
71
83
|
},
|
|
72
84
|
[onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues]
|
|
73
85
|
);
|
|
74
|
-
const selectedEntity = entities?.find((e) => stringifyEntityRef(e) === formData) ?? (allowArbitraryValues && formData ? getLabel(formData) : "");
|
|
86
|
+
const selectedEntity = entities?.catalogEntities.find((e) => stringifyEntityRef(e) === formData) ?? (allowArbitraryValues && formData ? getLabel(formData) : "");
|
|
75
87
|
useEffect(() => {
|
|
76
|
-
if (entities?.length === 1 && selectedEntity === "") {
|
|
77
|
-
onChange(stringifyEntityRef(entities[0]));
|
|
88
|
+
if (entities?.catalogEntities.length === 1 && selectedEntity === "") {
|
|
89
|
+
onChange(stringifyEntityRef(entities.catalogEntities[0]));
|
|
78
90
|
}
|
|
79
91
|
}, [entities, onChange, selectedEntity]);
|
|
80
92
|
return /* @__PURE__ */ React.createElement(
|
|
@@ -87,15 +99,15 @@ const EntityPicker = (props) => {
|
|
|
87
99
|
/* @__PURE__ */ React.createElement(
|
|
88
100
|
Autocomplete,
|
|
89
101
|
{
|
|
90
|
-
disabled: entities?.length === 1,
|
|
102
|
+
disabled: entities?.catalogEntities.length === 1,
|
|
91
103
|
id: idSchema?.$id,
|
|
92
104
|
value: selectedEntity,
|
|
93
105
|
loading,
|
|
94
106
|
onChange: onSelect,
|
|
95
|
-
options: entities || [],
|
|
107
|
+
options: entities?.catalogEntities || [],
|
|
96
108
|
getOptionLabel: (option) => (
|
|
97
109
|
// option can be a string due to freeSolo.
|
|
98
|
-
typeof option === "string" ? option :
|
|
110
|
+
typeof option === "string" ? option : entities?.entityRefToPresentation.get(stringifyEntityRef(option))?.entityRef
|
|
99
111
|
),
|
|
100
112
|
autoSelect: true,
|
|
101
113
|
freeSolo: allowArbitraryValues,
|
|
@@ -111,7 +123,11 @@ const EntityPicker = (props) => {
|
|
|
111
123
|
required,
|
|
112
124
|
InputProps: params.InputProps
|
|
113
125
|
}
|
|
114
|
-
)
|
|
126
|
+
),
|
|
127
|
+
renderOption: (option) => /* @__PURE__ */ React.createElement(EntityDisplayName, { entityRef: option }),
|
|
128
|
+
filterOptions: createFilterOptions({
|
|
129
|
+
stringify: (option) => entities?.entityRefToPresentation.get(stringifyEntityRef(option))?.primaryTitle
|
|
130
|
+
})
|
|
115
131
|
}
|
|
116
132
|
)
|
|
117
133
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"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 */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport FormControl from '@material-ui/core/FormControl';\nimport Autocomplete, {\n AutocompleteChangeReason,\n} from '@material-ui/lab/Autocomplete';\nimport React, { useCallback, useEffect } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const {\n onChange,\n schema: { title = 'Entity', description = 'An entity from the catalog' },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = ['metadata.name', 'metadata.namespace', 'kind'];\n const { items } = await catalogApi.getEntities(\n catalogFilter\n ? { filter: catalogFilter, fields }\n : { filter: undefined, fields },\n );\n return items;\n });\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (ref: string) => {\n try {\n return humanizeEntityRef(\n parseEntityRef(ref, { defaultKind, defaultNamespace }),\n {\n defaultKind,\n defaultNamespace,\n },\n );\n } catch (err) {\n return ref;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall\n // back to the given value.\n const selectedEntity =\n entities?.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n useEffect(() => {\n if (entities?.length === 1 && selectedEntity === '') {\n onChange(stringifyEntityRef(entities[0]));\n }\n }, [entities, onChange, selectedEntity]);\n\n return (\n <FormControl\n margin=\"normal\"\n required={required}\n error={rawErrors?.length > 0 && !formData}\n >\n <Autocomplete\n disabled={entities?.length === 1}\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : humanizeEntityRef(option, { defaultKind, defaultNamespace })!\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n helperText={description}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n />\n </FormControl>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"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 */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n EntityDisplayName,\n EntityRefPresentationSnapshot,\n catalogApiRef,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport FormControl from '@material-ui/core/FormControl';\nimport Autocomplete, {\n AutocompleteChangeReason,\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport React, { useCallback, useEffect } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const {\n onChange,\n schema: { title = 'Entity', description = 'An entity from the catalog' },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = [\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n 'kind',\n ];\n const { items } = await catalogApi.getEntities(\n catalogFilter\n ? { filter: catalogFilter, fields }\n : { filter: undefined, fields },\n );\n\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n\n return { catalogEntities: items, entityRefToPresentation };\n });\n\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (freeSoloValue: string) => {\n try {\n // Will throw if defaultKind or defaultNamespace are not set\n const parsedRef = parseEntityRef(freeSoloValue, {\n defaultKind,\n defaultNamespace,\n });\n\n return stringifyEntityRef(parsedRef);\n } catch (err) {\n return freeSoloValue;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall\n // back to the given value.\n const selectedEntity =\n entities?.catalogEntities.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n useEffect(() => {\n if (entities?.catalogEntities.length === 1 && selectedEntity === '') {\n onChange(stringifyEntityRef(entities.catalogEntities[0]));\n }\n }, [entities, onChange, selectedEntity]);\n\n return (\n <FormControl\n margin=\"normal\"\n required={required}\n error={rawErrors?.length > 0 && !formData}\n >\n <Autocomplete\n disabled={entities?.catalogEntities.length === 1}\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities?.catalogEntities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.entityRef!\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n helperText={description}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n />\n </FormControl>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -87,18 +87,14 @@ const RepoUrlPicker = (props) => {
|
|
|
87
87
|
useDebounce(
|
|
88
88
|
async () => {
|
|
89
89
|
const { requestUserCredentials } = uiSchema?.["ui:options"] ?? {};
|
|
90
|
-
|
|
91
|
-
if (!requestUserCredentials || !(state.host && workspace && state.repoName)) {
|
|
90
|
+
if (!requestUserCredentials || !state.host) {
|
|
92
91
|
return;
|
|
93
92
|
}
|
|
94
93
|
if (secrets[requestUserCredentials.secretsKey]) {
|
|
95
94
|
return;
|
|
96
95
|
}
|
|
97
|
-
const [encodedHost, encodedRepoName] = [state.host, state.repoName].map(
|
|
98
|
-
encodeURIComponent
|
|
99
|
-
);
|
|
100
96
|
const { token } = await scmAuthApi.getCredentials({
|
|
101
|
-
url: `https://${
|
|
97
|
+
url: `https://${state.host}`,
|
|
102
98
|
additionalScope: {
|
|
103
99
|
repoWrite: true,
|
|
104
100
|
customScopes: requestUserCredentials.additionalScopes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RepoUrlPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx"],"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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n scmIntegrationsApiRef,\n scmAuthApiRef,\n} from '@backstage/integration-react';\nimport React, { useEffect, useState, useMemo, useCallback } from 'react';\nimport { GithubRepoPicker } from './GithubRepoPicker';\nimport { GiteaRepoPicker } from './GiteaRepoPicker';\nimport { GitlabRepoPicker } from './GitlabRepoPicker';\nimport { AzureRepoPicker } from './AzureRepoPicker';\nimport { BitbucketRepoPicker } from './BitbucketRepoPicker';\nimport { GerritRepoPicker } from './GerritRepoPicker';\nimport { RepoUrlPickerHost } from './RepoUrlPickerHost';\nimport { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName';\nimport { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils';\nimport { RepoUrlPickerProps } from './schema';\nimport { RepoUrlPickerState } from './types';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport { useTemplateSecrets } from '@backstage/plugin-scaffolder-react';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport Typography from '@material-ui/core/Typography';\n\nexport { RepoUrlPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `RepoUrlPicker`\n * field extension.\n *\n * @public\n */\nexport const RepoUrlPicker = (props: RepoUrlPickerProps) => {\n const { uiSchema, onChange, rawErrors, formData, schema } = props;\n const [state, setState] = useState<RepoUrlPickerState>(\n parseRepoPickerUrl(formData),\n );\n const integrationApi = useApi(scmIntegrationsApiRef);\n const scmAuthApi = useApi(scmAuthApiRef);\n const { secrets, setSecrets } = useTemplateSecrets();\n const allowedHosts = useMemo(\n () => uiSchema?.['ui:options']?.allowedHosts ?? [],\n [uiSchema],\n );\n const allowedOrganizations = useMemo(\n () => uiSchema?.['ui:options']?.allowedOrganizations ?? [],\n [uiSchema],\n );\n const allowedOwners = useMemo(\n () => uiSchema?.['ui:options']?.allowedOwners ?? [],\n [uiSchema],\n );\n const allowedProjects = useMemo(\n () => uiSchema?.['ui:options']?.allowedProjects ?? [],\n [uiSchema],\n );\n const allowedRepos = useMemo(\n () => uiSchema?.['ui:options']?.allowedRepos ?? [],\n [uiSchema],\n );\n\n const { owner, organization, project, repoName } = state;\n\n useEffect(() => {\n onChange(serializeRepoPickerUrl(state));\n }, [state, onChange]);\n\n /* we deal with calling the repo setting here instead of in each components for ease */\n useEffect(() => {\n if (allowedOrganizations.length > 0 && !organization) {\n setState(prevState => ({\n ...prevState,\n organization: allowedOrganizations[0],\n }));\n }\n }, [setState, allowedOrganizations, organization]);\n\n useEffect(() => {\n if (allowedOwners.length > 0 && !owner) {\n setState(prevState => ({\n ...prevState,\n owner: allowedOwners[0],\n }));\n }\n }, [setState, allowedOwners, owner]);\n\n useEffect(() => {\n if (allowedProjects.length > 0 && !project) {\n setState(prevState => ({\n ...prevState,\n project: allowedProjects[0],\n }));\n }\n }, [setState, allowedProjects, project]);\n\n useEffect(() => {\n if (allowedRepos.length > 0 && !repoName) {\n setState(prevState => ({ ...prevState, repoName: allowedRepos[0] }));\n }\n }, [setState, allowedRepos, repoName]);\n\n const updateLocalState = useCallback(\n (newState: RepoUrlPickerState) => {\n setState(prevState => ({ ...prevState, ...newState }));\n },\n [setState],\n );\n\n useDebounce(\n async () => {\n const { requestUserCredentials } = uiSchema?.['ui:options'] ?? {};\n\n const workspace = state.owner ? state.owner : state.project;\n if (\n !requestUserCredentials ||\n !(state.host && workspace && state.repoName)\n ) {\n return;\n }\n\n // don't show login prompt if secret value is already in state\n if (secrets[requestUserCredentials.secretsKey]) {\n return;\n }\n\n // previously, we were encodeURI for state.host, workspace and state.repoName separately.\n // That created an issue where GitLab workspace can be nested like groupA/subgroupB\n // when we encodeURi separately and then join, the URL will be malformed and\n // resulting in 400 request error from GitLab API\n const [encodedHost, encodedRepoName] = [state.host, state.repoName].map(\n encodeURIComponent,\n );\n\n // user has requested that we use the users credentials\n // so lets grab them using the scmAuthApi and pass through\n // any additional scopes from the ui:options\n const { token } = await scmAuthApi.getCredentials({\n url: `https://${encodedHost}/${workspace}/${encodedRepoName}`,\n additionalScope: {\n repoWrite: true,\n customScopes: requestUserCredentials.additionalScopes,\n },\n });\n\n // set the secret using the key provided in the ui:options for use\n // in the templating the manifest with ${{ secrets[secretsKey] }}\n setSecrets({ [requestUserCredentials.secretsKey]: token });\n },\n 500,\n [state, uiSchema],\n );\n\n const hostType =\n (state.host && integrationApi.byHost(state.host)?.type) ?? null;\n return (\n <>\n {schema.title && (\n <Box my={1}>\n <Typography variant=\"h5\">{schema.title}</Typography>\n <Divider />\n </Box>\n )}\n {schema.description && (\n <Typography variant=\"body1\">{schema.description}</Typography>\n )}\n <RepoUrlPickerHost\n host={state.host}\n hosts={allowedHosts}\n onChange={host => setState(prevState => ({ ...prevState, host }))}\n rawErrors={rawErrors}\n />\n {hostType === 'github' && (\n <GithubRepoPicker\n allowedOwners={allowedOwners}\n onChange={updateLocalState}\n rawErrors={rawErrors}\n state={state}\n />\n )}\n {hostType === 'gitea' && (\n <GiteaRepoPicker\n allowedOwners={allowedOwners}\n allowedRepos={allowedRepos}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'gitlab' && (\n <GitlabRepoPicker\n allowedOwners={allowedOwners}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'bitbucket' && (\n <BitbucketRepoPicker\n allowedOwners={allowedOwners}\n allowedProjects={allowedProjects}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'azure' && (\n <AzureRepoPicker\n allowedOrganizations={allowedOrganizations}\n allowedProject={allowedProjects}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'gerrit' && (\n <GerritRepoPicker\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n <RepoUrlPickerRepoName\n repoName={state.repoName}\n allowedRepos={allowedRepos}\n onChange={repo =>\n setState(prevState => ({ ...prevState, repoName: repo }))\n }\n rawErrors={rawErrors}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RepoUrlPicker.esm.js","sources":["../../../../src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx"],"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 */\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n scmIntegrationsApiRef,\n scmAuthApiRef,\n} from '@backstage/integration-react';\nimport React, { useEffect, useState, useMemo, useCallback } from 'react';\nimport { GithubRepoPicker } from './GithubRepoPicker';\nimport { GiteaRepoPicker } from './GiteaRepoPicker';\nimport { GitlabRepoPicker } from './GitlabRepoPicker';\nimport { AzureRepoPicker } from './AzureRepoPicker';\nimport { BitbucketRepoPicker } from './BitbucketRepoPicker';\nimport { GerritRepoPicker } from './GerritRepoPicker';\nimport { RepoUrlPickerHost } from './RepoUrlPickerHost';\nimport { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName';\nimport { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils';\nimport { RepoUrlPickerProps } from './schema';\nimport { RepoUrlPickerState } from './types';\nimport useDebounce from 'react-use/esm/useDebounce';\nimport { useTemplateSecrets } from '@backstage/plugin-scaffolder-react';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport Typography from '@material-ui/core/Typography';\n\nexport { RepoUrlPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `RepoUrlPicker`\n * field extension.\n *\n * @public\n */\nexport const RepoUrlPicker = (props: RepoUrlPickerProps) => {\n const { uiSchema, onChange, rawErrors, formData, schema } = props;\n const [state, setState] = useState<RepoUrlPickerState>(\n parseRepoPickerUrl(formData),\n );\n const integrationApi = useApi(scmIntegrationsApiRef);\n const scmAuthApi = useApi(scmAuthApiRef);\n const { secrets, setSecrets } = useTemplateSecrets();\n const allowedHosts = useMemo(\n () => uiSchema?.['ui:options']?.allowedHosts ?? [],\n [uiSchema],\n );\n const allowedOrganizations = useMemo(\n () => uiSchema?.['ui:options']?.allowedOrganizations ?? [],\n [uiSchema],\n );\n const allowedOwners = useMemo(\n () => uiSchema?.['ui:options']?.allowedOwners ?? [],\n [uiSchema],\n );\n const allowedProjects = useMemo(\n () => uiSchema?.['ui:options']?.allowedProjects ?? [],\n [uiSchema],\n );\n const allowedRepos = useMemo(\n () => uiSchema?.['ui:options']?.allowedRepos ?? [],\n [uiSchema],\n );\n\n const { owner, organization, project, repoName } = state;\n\n useEffect(() => {\n onChange(serializeRepoPickerUrl(state));\n }, [state, onChange]);\n\n /* we deal with calling the repo setting here instead of in each components for ease */\n useEffect(() => {\n if (allowedOrganizations.length > 0 && !organization) {\n setState(prevState => ({\n ...prevState,\n organization: allowedOrganizations[0],\n }));\n }\n }, [setState, allowedOrganizations, organization]);\n\n useEffect(() => {\n if (allowedOwners.length > 0 && !owner) {\n setState(prevState => ({\n ...prevState,\n owner: allowedOwners[0],\n }));\n }\n }, [setState, allowedOwners, owner]);\n\n useEffect(() => {\n if (allowedProjects.length > 0 && !project) {\n setState(prevState => ({\n ...prevState,\n project: allowedProjects[0],\n }));\n }\n }, [setState, allowedProjects, project]);\n\n useEffect(() => {\n if (allowedRepos.length > 0 && !repoName) {\n setState(prevState => ({ ...prevState, repoName: allowedRepos[0] }));\n }\n }, [setState, allowedRepos, repoName]);\n\n const updateLocalState = useCallback(\n (newState: RepoUrlPickerState) => {\n setState(prevState => ({ ...prevState, ...newState }));\n },\n [setState],\n );\n\n useDebounce(\n async () => {\n const { requestUserCredentials } = uiSchema?.['ui:options'] ?? {};\n\n if (!requestUserCredentials || !state.host) {\n return;\n }\n\n // don't show login prompt if secret value is already in state\n if (secrets[requestUserCredentials.secretsKey]) {\n return;\n }\n\n // user has requested that we use the users credentials\n // so lets grab them using the scmAuthApi and pass through\n // any additional scopes from the ui:options\n const { token } = await scmAuthApi.getCredentials({\n url: `https://${state.host}`,\n additionalScope: {\n repoWrite: true,\n customScopes: requestUserCredentials.additionalScopes,\n },\n });\n\n // set the secret using the key provided in the ui:options for use\n // in the templating the manifest with ${{ secrets[secretsKey] }}\n setSecrets({ [requestUserCredentials.secretsKey]: token });\n },\n 500,\n [state, uiSchema],\n );\n\n const hostType =\n (state.host && integrationApi.byHost(state.host)?.type) ?? null;\n return (\n <>\n {schema.title && (\n <Box my={1}>\n <Typography variant=\"h5\">{schema.title}</Typography>\n <Divider />\n </Box>\n )}\n {schema.description && (\n <Typography variant=\"body1\">{schema.description}</Typography>\n )}\n <RepoUrlPickerHost\n host={state.host}\n hosts={allowedHosts}\n onChange={host => setState(prevState => ({ ...prevState, host }))}\n rawErrors={rawErrors}\n />\n {hostType === 'github' && (\n <GithubRepoPicker\n allowedOwners={allowedOwners}\n onChange={updateLocalState}\n rawErrors={rawErrors}\n state={state}\n />\n )}\n {hostType === 'gitea' && (\n <GiteaRepoPicker\n allowedOwners={allowedOwners}\n allowedRepos={allowedRepos}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'gitlab' && (\n <GitlabRepoPicker\n allowedOwners={allowedOwners}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'bitbucket' && (\n <BitbucketRepoPicker\n allowedOwners={allowedOwners}\n allowedProjects={allowedProjects}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'azure' && (\n <AzureRepoPicker\n allowedOrganizations={allowedOrganizations}\n allowedProject={allowedProjects}\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n {hostType === 'gerrit' && (\n <GerritRepoPicker\n rawErrors={rawErrors}\n state={state}\n onChange={updateLocalState}\n />\n )}\n <RepoUrlPickerRepoName\n repoName={state.repoName}\n allowedRepos={allowedRepos}\n onChange={repo =>\n setState(prevState => ({ ...prevState, repoName: repo }))\n }\n rawErrors={rawErrors}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha';
|
|
4
|
-
import Input from '@material-ui/core/Input';
|
|
5
|
-
import InputLabel from '@material-ui/core/InputLabel';
|
|
2
|
+
import { ScaffolderField, SecretWidget } from '@backstage/plugin-scaffolder-react/alpha';
|
|
6
3
|
|
|
7
4
|
const SecretInput = (props) => {
|
|
8
|
-
const { setSecrets, secrets } = useTemplateSecrets();
|
|
9
5
|
const {
|
|
10
|
-
|
|
11
|
-
onChange,
|
|
12
|
-
schema: { title, description },
|
|
6
|
+
schema: { description },
|
|
13
7
|
rawErrors,
|
|
14
8
|
disabled,
|
|
15
9
|
errors,
|
|
@@ -24,21 +18,7 @@ const SecretInput = (props) => {
|
|
|
24
18
|
errors,
|
|
25
19
|
required
|
|
26
20
|
},
|
|
27
|
-
/* @__PURE__ */ React.createElement(
|
|
28
|
-
/* @__PURE__ */ React.createElement(
|
|
29
|
-
Input,
|
|
30
|
-
{
|
|
31
|
-
id: title,
|
|
32
|
-
"aria-describedby": title,
|
|
33
|
-
onChange: (e) => {
|
|
34
|
-
onChange(Array(e.target?.value.length).fill("*").join(""));
|
|
35
|
-
setSecrets({ [name]: e.target?.value });
|
|
36
|
-
},
|
|
37
|
-
value: secrets[name] ?? "",
|
|
38
|
-
type: "password",
|
|
39
|
-
autoComplete: "off"
|
|
40
|
-
}
|
|
41
|
-
)
|
|
21
|
+
/* @__PURE__ */ React.createElement(SecretWidget, { ...props })
|
|
42
22
|
);
|
|
43
23
|
};
|
|
44
24
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecretInput.esm.js","sources":["../../../../src/components/fields/SecretInput/SecretInput.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 */\nimport React from 'react';\nimport {
|
|
1
|
+
{"version":3,"file":"SecretInput.esm.js","sources":["../../../../src/components/fields/SecretInput/SecretInput.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 */\nimport React from 'react';\nimport { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react';\nimport {\n ScaffolderField,\n SecretWidget,\n} from '@backstage/plugin-scaffolder-react/alpha';\n\nexport const SecretInput = (props: ScaffolderRJSFFieldProps) => {\n const {\n schema: { description },\n rawErrors,\n disabled,\n errors,\n required,\n } = props;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={description}\n disabled={disabled}\n errors={errors}\n required={required}\n >\n <SecretWidget {...props} />\n </ScaffolderField>\n );\n};\n"],"names":[],"mappings":";;;AAsBa,MAAA,WAAA,GAAc,CAAC,KAAoC,KAAA;AAC9D,EAAM,MAAA;AAAA,IACJ,MAAA,EAAQ,EAAE,WAAY,EAAA;AAAA,IACtB,SAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,GACE,GAAA,KAAA,CAAA;AAEJ,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,cAAgB,EAAA,WAAA;AAAA,MAChB,QAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA,CAAC,YAAc,EAAA,EAAA,GAAG,KAAO,EAAA,CAAA;AAAA,GAC3B,CAAA;AAEJ;;;;"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder",
|
|
3
|
-
"version": "1.21.0
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "The Backstage plugin that helps you create new things",
|
|
5
5
|
"backstage": {
|
|
6
|
-
"role": "frontend-plugin"
|
|
6
|
+
"role": "frontend-plugin",
|
|
7
|
+
"pluginId": "scaffolder",
|
|
8
|
+
"pluginPackages": [
|
|
9
|
+
"@backstage/plugin-scaffolder",
|
|
10
|
+
"@backstage/plugin-scaffolder-backend",
|
|
11
|
+
"@backstage/plugin-scaffolder-common",
|
|
12
|
+
"@backstage/plugin-scaffolder-node",
|
|
13
|
+
"@backstage/plugin-scaffolder-node-test-utils",
|
|
14
|
+
"@backstage/plugin-scaffolder-react"
|
|
15
|
+
]
|
|
7
16
|
},
|
|
8
17
|
"publishConfig": {
|
|
9
18
|
"access": "public"
|
|
@@ -50,18 +59,18 @@
|
|
|
50
59
|
"dependencies": {
|
|
51
60
|
"@backstage/catalog-client": "^1.6.5",
|
|
52
61
|
"@backstage/catalog-model": "^1.5.0",
|
|
53
|
-
"@backstage/core-compat-api": "^0.2.6
|
|
54
|
-
"@backstage/core-components": "^0.14.8
|
|
55
|
-
"@backstage/core-plugin-api": "^1.9.3
|
|
62
|
+
"@backstage/core-compat-api": "^0.2.6",
|
|
63
|
+
"@backstage/core-components": "^0.14.8",
|
|
64
|
+
"@backstage/core-plugin-api": "^1.9.3",
|
|
56
65
|
"@backstage/errors": "^1.2.4",
|
|
57
|
-
"@backstage/frontend-plugin-api": "^0.6.6
|
|
58
|
-
"@backstage/integration": "^1.12.0
|
|
59
|
-
"@backstage/integration-react": "^1.1.28
|
|
60
|
-
"@backstage/plugin-catalog-common": "^1.0.
|
|
61
|
-
"@backstage/plugin-catalog-react": "^1.12.1
|
|
62
|
-
"@backstage/plugin-permission-react": "^0.4.23
|
|
63
|
-
"@backstage/plugin-scaffolder-common": "^1.5.3
|
|
64
|
-
"@backstage/plugin-scaffolder-react": "^1.
|
|
66
|
+
"@backstage/frontend-plugin-api": "^0.6.6",
|
|
67
|
+
"@backstage/integration": "^1.12.0",
|
|
68
|
+
"@backstage/integration-react": "^1.1.28",
|
|
69
|
+
"@backstage/plugin-catalog-common": "^1.0.24",
|
|
70
|
+
"@backstage/plugin-catalog-react": "^1.12.1",
|
|
71
|
+
"@backstage/plugin-permission-react": "^0.4.23",
|
|
72
|
+
"@backstage/plugin-scaffolder-common": "^1.5.3",
|
|
73
|
+
"@backstage/plugin-scaffolder-react": "^1.9.0",
|
|
65
74
|
"@backstage/types": "^1.1.1",
|
|
66
75
|
"@codemirror/language": "^6.0.0",
|
|
67
76
|
"@codemirror/legacy-modes": "^6.1.0",
|
|
@@ -71,10 +80,10 @@
|
|
|
71
80
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
72
81
|
"@microsoft/fetch-event-source": "^2.0.1",
|
|
73
82
|
"@react-hookz/web": "^24.0.0",
|
|
74
|
-
"@rjsf/core": "5.18.
|
|
75
|
-
"@rjsf/material-ui": "5.18.
|
|
76
|
-
"@rjsf/utils": "5.18.
|
|
77
|
-
"@rjsf/validator-ajv8": "5.18.
|
|
83
|
+
"@rjsf/core": "5.18.4",
|
|
84
|
+
"@rjsf/material-ui": "5.18.4",
|
|
85
|
+
"@rjsf/utils": "5.18.4",
|
|
86
|
+
"@rjsf/validator-ajv8": "5.18.4",
|
|
78
87
|
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
79
88
|
"@uiw/react-codemirror": "^4.9.3",
|
|
80
89
|
"classnames": "^2.2.6",
|
|
@@ -93,12 +102,12 @@
|
|
|
93
102
|
"zod-to-json-schema": "^3.20.4"
|
|
94
103
|
},
|
|
95
104
|
"devDependencies": {
|
|
96
|
-
"@backstage/cli": "^0.26.7
|
|
97
|
-
"@backstage/core-app-api": "^1.12.6
|
|
98
|
-
"@backstage/dev-utils": "^1.0.33
|
|
99
|
-
"@backstage/plugin-catalog": "^1.21.0
|
|
100
|
-
"@backstage/plugin-permission-common": "^0.7.
|
|
101
|
-
"@backstage/test-utils": "^1.5.6
|
|
105
|
+
"@backstage/cli": "^0.26.7",
|
|
106
|
+
"@backstage/core-app-api": "^1.12.6",
|
|
107
|
+
"@backstage/dev-utils": "^1.0.33",
|
|
108
|
+
"@backstage/plugin-catalog": "^1.21.0",
|
|
109
|
+
"@backstage/plugin-permission-common": "^0.7.14",
|
|
110
|
+
"@backstage/test-utils": "^1.5.6",
|
|
102
111
|
"@testing-library/dom": "^10.0.0",
|
|
103
112
|
"@testing-library/jest-dom": "^6.0.0",
|
|
104
113
|
"@testing-library/react": "^15.0.0",
|