@backstage/plugin-scaffolder-react 1.12.0-next.2 → 1.13.0-next.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 +61 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.d.ts +59 -2
- package/dist/alpha.esm.js +1 -0
- package/dist/alpha.esm.js.map +1 -1
- package/dist/api/ref.esm.js +4 -8
- package/dist/api/ref.esm.js.map +1 -1
- package/dist/hooks/useEventStream.esm.js +18 -7
- package/dist/hooks/useEventStream.esm.js.map +1 -1
- package/dist/index.d.ts +30 -3
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/next/blueprints/FormFieldBlueprint.esm.js +23 -0
- package/dist/next/blueprints/FormFieldBlueprint.esm.js.map +1 -0
- package/dist/packages/opaque-internal/src/OpaqueType.esm.js +103 -0
- package/dist/packages/opaque-internal/src/OpaqueType.esm.js.map +1 -0
- package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js +6 -0
- package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js.map +1 -0
- package/dist/utils.esm.js +19 -0
- package/dist/utils.esm.js.map +1 -0
- package/package.json +20 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-react
|
|
2
2
|
|
|
3
|
+
## 1.13.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bf6eaf3: Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @backstage/frontend-plugin-api@0.9.0-next.0
|
|
14
|
+
- @backstage/core-components@0.15.1-next.0
|
|
15
|
+
- @backstage/core-plugin-api@1.10.0-next.0
|
|
16
|
+
- @backstage/plugin-catalog-react@1.13.1-next.0
|
|
17
|
+
- @backstage/catalog-client@1.7.0
|
|
18
|
+
- @backstage/catalog-model@1.7.0
|
|
19
|
+
- @backstage/theme@0.5.7
|
|
20
|
+
- @backstage/types@1.1.1
|
|
21
|
+
- @backstage/version-bridge@1.0.9
|
|
22
|
+
- @backstage/plugin-permission-react@0.4.27-next.0
|
|
23
|
+
- @backstage/plugin-scaffolder-common@1.5.6
|
|
24
|
+
|
|
25
|
+
## 1.12.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 4512f71: Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name.
|
|
30
|
+
- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- 1f3c5aa: Fix scaffolder review step issue where schema options are not handled for fields on multi-step templates.
|
|
35
|
+
- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`.
|
|
36
|
+
- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`.
|
|
37
|
+
Updated dependency `@rjsf/core` to `5.21.1`.
|
|
38
|
+
Updated dependency `@rjsf/material-ui` to `5.21.1`.
|
|
39
|
+
Updated dependency `@rjsf/validator-ajv8` to `5.21.1`.
|
|
40
|
+
- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`.
|
|
41
|
+
Updated dependency `@rjsf/core` to `5.20.1`.
|
|
42
|
+
Updated dependency `@rjsf/material-ui` to `5.20.1`.
|
|
43
|
+
Updated dependency `@rjsf/validator-ajv8` to `5.20.1`.
|
|
44
|
+
- c2cbe1e: Updated dependency `use-immer` to `^0.10.0`.
|
|
45
|
+
- b0f0118: Remove unnecessary singleton wrapping of `scaffolderApiRef`.
|
|
46
|
+
- 3ebb64f: - Fix secret widget field not displaying as required.
|
|
47
|
+
- Fix secret widget not able to be required inside nested objects.
|
|
48
|
+
- Fix secret widget not able to be disabled.
|
|
49
|
+
- Support `minLength` and `maxLength` properties for secret widget.
|
|
50
|
+
- 8dd6ef6: Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`.
|
|
51
|
+
- 9a0672a: Scaffolder review page shows static amount of asterisks for secret fields.
|
|
52
|
+
- Updated dependencies
|
|
53
|
+
- @backstage/core-components@0.15.0
|
|
54
|
+
- @backstage/plugin-catalog-react@1.13.0
|
|
55
|
+
- @backstage/catalog-model@1.7.0
|
|
56
|
+
- @backstage/catalog-client@1.7.0
|
|
57
|
+
- @backstage/core-plugin-api@1.9.4
|
|
58
|
+
- @backstage/theme@0.5.7
|
|
59
|
+
- @backstage/version-bridge@1.0.9
|
|
60
|
+
- @backstage/plugin-permission-react@0.4.26
|
|
61
|
+
- @backstage/types@1.1.1
|
|
62
|
+
- @backstage/plugin-scaffolder-common@1.5.6
|
|
63
|
+
|
|
3
64
|
## 1.12.0-next.2
|
|
4
65
|
|
|
5
66
|
### Minor Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ import * as React from 'react';
|
|
|
4
4
|
import React__default, { ComponentType, ReactNode, PropsWithChildren, ReactElement } from 'react';
|
|
5
5
|
import { TemplatePresentationV1beta3, TemplateEntityV1beta3, TaskStep } from '@backstage/plugin-scaffolder-common';
|
|
6
6
|
import { UiSchema, FieldValidation, WidgetProps } from '@rjsf/utils';
|
|
7
|
-
import { TemplateParameterSchema, FieldExtensionOptions, FormProps, ReviewStepProps, LayoutOptions, CustomFieldValidator, TemplateGroupFilter, ScaffolderTaskOutput, ScaffolderRJSFFormProps, ScaffolderStep } from '@backstage/plugin-scaffolder-react';
|
|
7
|
+
import { TemplateParameterSchema, FieldExtensionOptions, FormProps, ReviewStepProps, LayoutOptions, CustomFieldValidator, TemplateGroupFilter, ScaffolderTaskOutput, ScaffolderRJSFFormProps, ScaffolderStep, FieldExtensionComponentProps, FieldSchema } from '@backstage/plugin-scaffolder-react';
|
|
8
8
|
import { ApiHolder, IconComponent } from '@backstage/core-plugin-api';
|
|
9
9
|
import { Overrides } from '@material-ui/core/styles/overrides';
|
|
10
10
|
import { StyleRules } from '@material-ui/core/styles/withStyles';
|
|
11
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
12
|
+
import { z } from 'zod';
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* This is the parsed template schema that is returned from the {@link useTemplateSchema} hook.
|
|
@@ -314,4 +316,59 @@ declare module '@backstage/theme' {
|
|
|
314
316
|
}
|
|
315
317
|
}
|
|
316
318
|
|
|
317
|
-
|
|
319
|
+
/*
|
|
320
|
+
* Copyright 2024 The Backstage Authors
|
|
321
|
+
*
|
|
322
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
323
|
+
* you may not use this file except in compliance with the License.
|
|
324
|
+
* You may obtain a copy of the License at
|
|
325
|
+
*
|
|
326
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
327
|
+
*
|
|
328
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
329
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
330
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
331
|
+
* See the License for the specific language governing permissions and
|
|
332
|
+
* limitations under the License.
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
/** @alpha */
|
|
338
|
+
interface FormField {
|
|
339
|
+
readonly $$type: '@backstage/scaffolder/FormField';
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** @alpha */
|
|
343
|
+
type FormFieldExtensionData<TReturnValue extends z.ZodType = z.ZodType, TUiOptions extends z.ZodType = z.ZodType> = {
|
|
344
|
+
name: string;
|
|
345
|
+
component: (props: FieldExtensionComponentProps<z.output<TReturnValue>, z.output<TUiOptions>>) => JSX.Element | null;
|
|
346
|
+
validation?: CustomFieldValidator<z.output<TReturnValue>, z.output<TUiOptions>>;
|
|
347
|
+
schema?: FieldSchema<z.output<TReturnValue>, z.output<TUiOptions>>;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @alpha
|
|
352
|
+
* Creates extensions that are Field Extensions for the Scaffolder
|
|
353
|
+
* */
|
|
354
|
+
declare const FormFieldBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
355
|
+
kind: "scaffolder-form-field";
|
|
356
|
+
name: undefined;
|
|
357
|
+
params: {
|
|
358
|
+
field: () => Promise<FormField>;
|
|
359
|
+
};
|
|
360
|
+
output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>;
|
|
361
|
+
inputs: {};
|
|
362
|
+
config: {};
|
|
363
|
+
configInput: {};
|
|
364
|
+
dataRefs: {
|
|
365
|
+
formFieldLoader: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>;
|
|
366
|
+
};
|
|
367
|
+
}>;
|
|
368
|
+
/**
|
|
369
|
+
* @alpha
|
|
370
|
+
* Used to create a form field binding with typechecking for compliance
|
|
371
|
+
*/
|
|
372
|
+
declare function createFormField<TReturnValue extends z.ZodType, TUiOptions extends z.ZodType>(opts: FormFieldExtensionData<TReturnValue, TUiOptions>): FormField;
|
|
373
|
+
|
|
374
|
+
export { type BackstageOverrides, DefaultTemplateOutputs, EmbeddableWorkflow, Form, FormFieldBlueprint, type FormFieldExtensionData, type FormValidation, type ParsedTemplateSchema, ReviewState, type ReviewStateProps, ScaffolderField, type ScaffolderFieldProps, ScaffolderPageContextMenu, type ScaffolderPageContextMenuProps, type ScaffolderReactComponentsNameToClassKey, type ScaffolderReactTemplateCategoryPickerClassKey, SecretWidget, Stepper, type StepperProps, TaskLogStream, TaskSteps, type TaskStepsProps, TemplateCard, type TemplateCardProps, TemplateCategoryPicker, TemplateGroup, type TemplateGroupProps, TemplateGroups, type TemplateGroupsProps, Workflow, type WorkflowProps, createAsyncValidators, createFieldValidation, createFormField, extractSchemaFromStep, useFilteredSchemaProperties, useFormDataFromQuery, useTemplateParameterSchema, useTemplateSchema };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -18,4 +18,5 @@ export { useFormDataFromQuery } from './next/hooks/useFormDataFromQuery.esm.js';
|
|
|
18
18
|
export { useTemplateSchema } from './next/hooks/useTemplateSchema.esm.js';
|
|
19
19
|
export { useTemplateParameterSchema } from './next/hooks/useTemplateParameterSchema.esm.js';
|
|
20
20
|
export { useFilteredSchemaProperties } from './next/hooks/useFilteredSchemaProperties.esm.js';
|
|
21
|
+
export { FormFieldBlueprint, createFormField } from './next/blueprints/FormFieldBlueprint.esm.js';
|
|
21
22
|
//# sourceMappingURL=alpha.esm.js.map
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
|
package/dist/api/ref.esm.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { createApiRef } from '@backstage/
|
|
2
|
-
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
1
|
+
import { createApiRef } from '@backstage/frontend-plugin-api';
|
|
3
2
|
|
|
4
|
-
const scaffolderApiRef =
|
|
5
|
-
"scaffolder
|
|
6
|
-
|
|
7
|
-
id: "plugin.scaffolder.service"
|
|
8
|
-
})
|
|
9
|
-
);
|
|
3
|
+
const scaffolderApiRef = createApiRef({
|
|
4
|
+
id: "plugin.scaffolder.service"
|
|
5
|
+
});
|
|
10
6
|
|
|
11
7
|
export { scaffolderApiRef };
|
|
12
8
|
//# sourceMappingURL=ref.esm.js.map
|
package/dist/api/ref.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ref.esm.js","sources":["../../src/api/ref.ts"],"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 { createApiRef } from '@backstage/
|
|
1
|
+
{"version":3,"file":"ref.esm.js","sources":["../../src/api/ref.ts"],"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 { createApiRef } from '@backstage/frontend-plugin-api';\nimport { ScaffolderApi } from './types';\n\n/** @public */\nexport const scaffolderApiRef = createApiRef<ScaffolderApi>({\n id: 'plugin.scaffolder.service',\n});\n"],"names":[],"mappings":";;AAoBO,MAAM,mBAAmB,YAA4B,CAAA;AAAA,EAC1D,EAAI,EAAA,2BAAA;AACN,CAAC;;;;"}
|
|
@@ -55,6 +55,10 @@ function reducer(draft, action) {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
case "RECOVERED": {
|
|
58
|
+
draft.cancelled = false;
|
|
59
|
+
draft.completed = false;
|
|
60
|
+
draft.output = void 0;
|
|
61
|
+
draft.error = void 0;
|
|
58
62
|
for (const stepId in draft.steps) {
|
|
59
63
|
if (draft.steps.hasOwnProperty(stepId)) {
|
|
60
64
|
draft.steps[stepId].startedAt = void 0;
|
|
@@ -88,13 +92,18 @@ const useTaskEventStream = (taskId) => {
|
|
|
88
92
|
let subscription;
|
|
89
93
|
let logPusher;
|
|
90
94
|
let retryCount = 1;
|
|
95
|
+
let isTaskRecoverable = false;
|
|
91
96
|
const startStreamLogProcess = () => scaffolderApi.getTask(taskId).then(
|
|
92
97
|
(task) => {
|
|
93
98
|
if (didCancel) {
|
|
94
99
|
return;
|
|
95
100
|
}
|
|
101
|
+
isTaskRecoverable = task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy === "startOver";
|
|
96
102
|
dispatch({ type: "INIT", data: task });
|
|
97
|
-
const observable = scaffolderApi.streamLogs({
|
|
103
|
+
const observable = scaffolderApi.streamLogs({
|
|
104
|
+
isTaskRecoverable,
|
|
105
|
+
taskId
|
|
106
|
+
});
|
|
98
107
|
const collectedLogEvents = new Array();
|
|
99
108
|
function emitLogs() {
|
|
100
109
|
if (collectedLogEvents.length) {
|
|
@@ -150,12 +159,14 @@ const useTaskEventStream = (taskId) => {
|
|
|
150
159
|
);
|
|
151
160
|
void startStreamLogProcess();
|
|
152
161
|
return () => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
subscription
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
if (!isTaskRecoverable) {
|
|
163
|
+
didCancel = true;
|
|
164
|
+
if (subscription) {
|
|
165
|
+
subscription.unsubscribe();
|
|
166
|
+
}
|
|
167
|
+
if (logPusher) {
|
|
168
|
+
clearInterval(logPusher);
|
|
169
|
+
}
|
|
159
170
|
}
|
|
160
171
|
};
|
|
161
172
|
}, [scaffolderApi, dispatch, taskId]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEventStream.esm.js","sources":["../../src/hooks/useEventStream.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useImmerReducer } from 'use-immer';\nimport { useEffect } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Subscription } from '@backstage/types';\nimport {\n LogEvent,\n scaffolderApiRef,\n ScaffolderTask,\n ScaffolderTaskOutput,\n ScaffolderTaskStatus,\n} from '../api';\n\n/**\n * The status of the step being processed\n *\n * @public\n */\nexport type ScaffolderStep = {\n id: string;\n status: ScaffolderTaskStatus;\n endedAt?: string;\n startedAt?: string;\n};\n\n/**\n * A task event from the event stream\n *\n * @public\n */\nexport type TaskStream = {\n cancelled: boolean;\n loading: boolean;\n error?: Error;\n stepLogs: { [stepId in string]: string[] };\n completed: boolean;\n task?: ScaffolderTask;\n steps: { [stepId in string]: ScaffolderStep };\n output?: ScaffolderTaskOutput;\n};\n\ntype ReducerLogEntry = {\n createdAt: string;\n body: {\n stepId?: string;\n status?: ScaffolderTaskStatus;\n message: string;\n output?: ScaffolderTaskOutput;\n error?: Error;\n recoverStrategy?: 'none' | 'startOver';\n };\n};\n\ntype ReducerAction =\n | { type: 'INIT'; data: ScaffolderTask }\n | { type: 'CANCELLED' }\n | { type: 'RECOVERED'; data: ReducerLogEntry }\n | { type: 'LOGS'; data: ReducerLogEntry[] }\n | { type: 'COMPLETED'; data: ReducerLogEntry }\n | { type: 'ERROR'; data: Error };\n\nfunction reducer(draft: TaskStream, action: ReducerAction) {\n switch (action.type) {\n case 'INIT': {\n draft.steps = action.data.spec.steps.reduce((current, next) => {\n current[next.id] = { status: 'open', id: next.id };\n return current;\n }, {} as { [stepId in string]: ScaffolderStep });\n draft.stepLogs = action.data.spec.steps.reduce((current, next) => {\n current[next.id] = [];\n return current;\n }, {} as { [stepId in string]: string[] });\n draft.loading = false;\n draft.error = undefined;\n draft.completed = false;\n draft.task = action.data;\n return;\n }\n\n case 'LOGS': {\n const entries = action.data;\n const logLines = [];\n\n for (const entry of entries) {\n const logLine = `${entry.createdAt} ${entry.body.message}`;\n logLines.push(logLine);\n\n if (!entry.body.stepId || !draft.steps?.[entry.body.stepId]) {\n continue;\n }\n\n const currentStepLog = draft.stepLogs?.[entry.body.stepId];\n const currentStep = draft.steps?.[entry.body.stepId];\n\n if (currentStep) {\n if (entry.body.status && entry.body.status !== currentStep.status) {\n currentStep.status = entry.body.status;\n\n if (currentStep.status === 'processing') {\n currentStep.startedAt = entry.createdAt;\n }\n\n if (\n ['cancelled', 'completed', 'failed'].includes(currentStep.status)\n ) {\n currentStep.endedAt = entry.createdAt;\n }\n }\n }\n\n currentStepLog?.push(logLine);\n }\n\n return;\n }\n\n case 'COMPLETED': {\n draft.completed = true;\n draft.output = action.data.body.output;\n draft.error = action.data.body.error;\n\n return;\n }\n\n case 'CANCELLED': {\n draft.cancelled = true;\n return;\n }\n\n case 'RECOVERED': {\n for (const stepId in draft.steps) {\n if (draft.steps.hasOwnProperty(stepId)) {\n draft.steps[stepId].startedAt = undefined;\n draft.steps[stepId].endedAt = undefined;\n draft.steps[stepId].status = 'open';\n }\n }\n return;\n }\n\n case 'ERROR': {\n draft.error = action.data;\n draft.loading = false;\n draft.completed = true;\n return;\n }\n\n default:\n return;\n }\n}\n\n/**\n * A hook to stream the logs of a task being processed\n *\n * @public\n */\nexport const useTaskEventStream = (taskId: string): TaskStream => {\n const scaffolderApi = useApi(scaffolderApiRef);\n const [state, dispatch] = useImmerReducer(reducer, {\n cancelled: false,\n loading: true,\n completed: false,\n stepLogs: {} as { [stepId in string]: string[] },\n steps: {} as { [stepId in string]: ScaffolderStep },\n });\n\n useEffect(() => {\n let didCancel = false;\n let subscription: Subscription | undefined;\n let logPusher: NodeJS.Timeout | undefined;\n let retryCount = 1;\n const startStreamLogProcess = () =>\n scaffolderApi.getTask(taskId).then(\n task => {\n if (didCancel) {\n return;\n }\n dispatch({ type: 'INIT', data: task });\n\n // TODO(blam): Use a normal fetch to fetch the current log for the event stream\n // and use that for an INIT_EVENTs dispatch event, and then\n // use the last event ID to subscribe using after option to\n // stream logs. Without this, if you have a lot of logs, it can look like the\n // task is being rebuilt on load as it progresses through the steps at a slower\n // rate whilst it builds the status from the event logs\n const observable = scaffolderApi.streamLogs({ taskId });\n\n const collectedLogEvents = new Array<LogEvent>();\n\n function emitLogs() {\n if (collectedLogEvents.length) {\n const logs = collectedLogEvents.splice(\n 0,\n collectedLogEvents.length,\n );\n dispatch({ type: 'LOGS', data: logs });\n }\n }\n\n logPusher = setInterval(emitLogs, 500);\n\n subscription = observable.subscribe({\n next: event => {\n retryCount = 1;\n switch (event.type) {\n case 'log':\n return collectedLogEvents.push(event);\n case 'cancelled':\n dispatch({ type: 'CANCELLED' });\n return undefined;\n case 'completion':\n emitLogs();\n dispatch({ type: 'COMPLETED', data: event });\n return undefined;\n case 'recovered':\n dispatch({ type: 'RECOVERED', data: event });\n return undefined;\n default:\n throw new Error(\n `Unhandled event type ${event.type} in observer`,\n );\n }\n },\n error: error => {\n emitLogs();\n // in some cases the error is a refused connection from backend\n // this can happen from internet issues or proxy problems\n // so we try to reconnect again after some time\n // just to restart the fetch process\n // details here https://github.com/backstage/backstage/issues/15002\n\n const maxRetries = 3;\n\n if (!error.message) {\n error.message = `We cannot connect at the moment, trying again in some seconds... Retrying (${\n retryCount > maxRetries ? maxRetries : retryCount\n }/${maxRetries} retries)`;\n }\n\n setTimeout(() => {\n retryCount += 1;\n void startStreamLogProcess();\n }, 15000);\n\n dispatch({ type: 'ERROR', data: error });\n },\n });\n },\n error => {\n if (!didCancel) {\n dispatch({ type: 'ERROR', data: error });\n }\n },\n );\n void startStreamLogProcess();\n return () => {\n didCancel = true;\n if (subscription) {\n subscription.unsubscribe();\n }\n if (logPusher) {\n clearInterval(logPusher);\n }\n };\n }, [scaffolderApi, dispatch, taskId]);\n\n return state;\n};\n"],"names":[],"mappings":";;;;;AA4EA,SAAS,OAAA,CAAQ,OAAmB,MAAuB,EAAA;AACzD,EAAA,QAAQ,OAAO,IAAM;AAAA,IACnB,KAAK,MAAQ,EAAA;AACX,MAAM,KAAA,CAAA,KAAA,GAAQ,OAAO,IAAK,CAAA,IAAA,CAAK,MAAM,MAAO,CAAA,CAAC,SAAS,IAAS,KAAA;AAC7D,QAAQ,OAAA,CAAA,IAAA,CAAK,EAAE,CAAI,GAAA,EAAE,QAAQ,MAAQ,EAAA,EAAA,EAAI,KAAK,EAAG,EAAA,CAAA;AACjD,QAAO,OAAA,OAAA,CAAA;AAAA,OACT,EAAG,EAA4C,CAAA,CAAA;AAC/C,MAAM,KAAA,CAAA,QAAA,GAAW,OAAO,IAAK,CAAA,IAAA,CAAK,MAAM,MAAO,CAAA,CAAC,SAAS,IAAS,KAAA;AAChE,QAAQ,OAAA,CAAA,IAAA,CAAK,EAAE,CAAA,GAAI,EAAC,CAAA;AACpB,QAAO,OAAA,OAAA,CAAA;AAAA,OACT,EAAG,EAAsC,CAAA,CAAA;AACzC,MAAA,KAAA,CAAM,OAAU,GAAA,KAAA,CAAA;AAChB,MAAA,KAAA,CAAM,KAAQ,GAAA,KAAA,CAAA,CAAA;AACd,MAAA,KAAA,CAAM,SAAY,GAAA,KAAA,CAAA;AAClB,MAAA,KAAA,CAAM,OAAO,MAAO,CAAA,IAAA,CAAA;AACpB,MAAA,OAAA;AAAA,KACF;AAAA,IAEA,KAAK,MAAQ,EAAA;AACX,MAAA,MAAM,UAAU,MAAO,CAAA,IAAA,CAAA;AAGvB,MAAA,KAAA,MAAW,SAAS,OAAS,EAAA;AAC3B,QAAA,MAAM,UAAU,CAAG,EAAA,KAAA,CAAM,SAAS,CAAI,CAAA,EAAA,KAAA,CAAM,KAAK,OAAO,CAAA,CAAA,CAAA;AAGxD,QAAI,IAAA,CAAC,KAAM,CAAA,IAAA,CAAK,MAAU,IAAA,CAAC,MAAM,KAAQ,GAAA,KAAA,CAAM,IAAK,CAAA,MAAM,CAAG,EAAA;AAC3D,UAAA,SAAA;AAAA,SACF;AAEA,QAAA,MAAM,cAAiB,GAAA,KAAA,CAAM,QAAW,GAAA,KAAA,CAAM,KAAK,MAAM,CAAA,CAAA;AACzD,QAAA,MAAM,WAAc,GAAA,KAAA,CAAM,KAAQ,GAAA,KAAA,CAAM,KAAK,MAAM,CAAA,CAAA;AAEnD,QAAA,IAAI,WAAa,EAAA;AACf,UAAA,IAAI,MAAM,IAAK,CAAA,MAAA,IAAU,MAAM,IAAK,CAAA,MAAA,KAAW,YAAY,MAAQ,EAAA;AACjE,YAAY,WAAA,CAAA,MAAA,GAAS,MAAM,IAAK,CAAA,MAAA,CAAA;AAEhC,YAAI,IAAA,WAAA,CAAY,WAAW,YAAc,EAAA;AACvC,cAAA,WAAA,CAAY,YAAY,KAAM,CAAA,SAAA,CAAA;AAAA,aAChC;AAEA,YACE,IAAA,CAAC,aAAa,WAAa,EAAA,QAAQ,EAAE,QAAS,CAAA,WAAA,CAAY,MAAM,CAChE,EAAA;AACA,cAAA,WAAA,CAAY,UAAU,KAAM,CAAA,SAAA,CAAA;AAAA,aAC9B;AAAA,WACF;AAAA,SACF;AAEA,QAAA,cAAA,EAAgB,KAAK,OAAO,CAAA,CAAA;AAAA,OAC9B;AAEA,MAAA,OAAA;AAAA,KACF;AAAA,IAEA,KAAK,WAAa,EAAA;AAChB,MAAA,KAAA,CAAM,SAAY,GAAA,IAAA,CAAA;AAClB,MAAM,KAAA,CAAA,MAAA,GAAS,MAAO,CAAA,IAAA,CAAK,IAAK,CAAA,MAAA,CAAA;AAChC,MAAM,KAAA,CAAA,KAAA,GAAQ,MAAO,CAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAA;AAE/B,MAAA,OAAA;AAAA,KACF;AAAA,IAEA,KAAK,WAAa,EAAA;AAChB,MAAA,KAAA,CAAM,SAAY,GAAA,IAAA,CAAA;AAClB,MAAA,OAAA;AAAA,KACF;AAAA,IAEA,KAAK,WAAa,EAAA;AAChB,MAAW,KAAA,MAAA,MAAA,IAAU,MAAM,KAAO,EAAA;AAChC,QAAA,IAAI,KAAM,CAAA,KAAA,CAAM,cAAe,CAAA,MAAM,CAAG,EAAA;AACtC,UAAM,KAAA,CAAA,KAAA,CAAM,MAAM,CAAA,CAAE,SAAY,GAAA,KAAA,CAAA,CAAA;AAChC,UAAM,KAAA,CAAA,KAAA,CAAM,MAAM,CAAA,CAAE,OAAU,GAAA,KAAA,CAAA,CAAA;AAC9B,UAAM,KAAA,CAAA,KAAA,CAAM,MAAM,CAAA,CAAE,MAAS,GAAA,MAAA,CAAA;AAAA,SAC/B;AAAA,OACF;AACA,MAAA,OAAA;AAAA,KACF;AAAA,IAEA,KAAK,OAAS,EAAA;AACZ,MAAA,KAAA,CAAM,QAAQ,MAAO,CAAA,IAAA,CAAA;AACrB,MAAA,KAAA,CAAM,OAAU,GAAA,KAAA,CAAA;AAChB,MAAA,KAAA,CAAM,SAAY,GAAA,IAAA,CAAA;AAClB,MAAA,OAAA;AAAA,KACF;AAAA,IAEA;AACE,MAAA,OAAA;AAAA,GACJ;AACF,CAAA;AAOa,MAAA,kBAAA,GAAqB,CAAC,MAA+B,KAAA;AAChE,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA,CAAA;AAC7C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,gBAAgB,OAAS,EAAA;AAAA,IACjD,SAAW,EAAA,KAAA;AAAA,IACX,OAAS,EAAA,IAAA;AAAA,IACT,SAAW,EAAA,KAAA;AAAA,IACX,UAAU,EAAC;AAAA,IACX,OAAO,EAAC;AAAA,GACT,CAAA,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAY,GAAA,KAAA,CAAA;AAChB,IAAI,IAAA,YAAA,CAAA;AACJ,IAAI,IAAA,SAAA,CAAA;AACJ,IAAA,IAAI,UAAa,GAAA,CAAA,CAAA;AACjB,IAAA,MAAM,qBAAwB,GAAA,MAC5B,aAAc,CAAA,OAAA,CAAQ,MAAM,CAAE,CAAA,IAAA;AAAA,MAC5B,CAAQ,IAAA,KAAA;AACN,QAAA,IAAI,SAAW,EAAA;AACb,UAAA,OAAA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,EAAE,IAAA,EAAM,MAAQ,EAAA,IAAA,EAAM,MAAM,CAAA,CAAA;AAQrC,QAAA,MAAM,UAAa,GAAA,aAAA,CAAc,UAAW,CAAA,EAAE,QAAQ,CAAA,CAAA;AAEtD,QAAM,MAAA,kBAAA,GAAqB,IAAI,KAAgB,EAAA,CAAA;AAE/C,QAAA,SAAS,QAAW,GAAA;AAClB,UAAA,IAAI,mBAAmB,MAAQ,EAAA;AAC7B,YAAA,MAAM,OAAO,kBAAmB,CAAA,MAAA;AAAA,cAC9B,CAAA;AAAA,cACA,kBAAmB,CAAA,MAAA;AAAA,aACrB,CAAA;AACA,YAAA,QAAA,CAAS,EAAE,IAAA,EAAM,MAAQ,EAAA,IAAA,EAAM,MAAM,CAAA,CAAA;AAAA,WACvC;AAAA,SACF;AAEA,QAAY,SAAA,GAAA,WAAA,CAAY,UAAU,GAAG,CAAA,CAAA;AAErC,QAAA,YAAA,GAAe,WAAW,SAAU,CAAA;AAAA,UAClC,MAAM,CAAS,KAAA,KAAA;AACb,YAAa,UAAA,GAAA,CAAA,CAAA;AACb,YAAA,QAAQ,MAAM,IAAM;AAAA,cAClB,KAAK,KAAA;AACH,gBAAO,OAAA,kBAAA,CAAmB,KAAK,KAAK,CAAA,CAAA;AAAA,cACtC,KAAK,WAAA;AACH,gBAAS,QAAA,CAAA,EAAE,IAAM,EAAA,WAAA,EAAa,CAAA,CAAA;AAC9B,gBAAO,OAAA,KAAA,CAAA,CAAA;AAAA,cACT,KAAK,YAAA;AACH,gBAAS,QAAA,EAAA,CAAA;AACT,gBAAA,QAAA,CAAS,EAAE,IAAA,EAAM,WAAa,EAAA,IAAA,EAAM,OAAO,CAAA,CAAA;AAC3C,gBAAO,OAAA,KAAA,CAAA,CAAA;AAAA,cACT,KAAK,WAAA;AACH,gBAAA,QAAA,CAAS,EAAE,IAAA,EAAM,WAAa,EAAA,IAAA,EAAM,OAAO,CAAA,CAAA;AAC3C,gBAAO,OAAA,KAAA,CAAA,CAAA;AAAA,cACT;AACE,gBAAA,MAAM,IAAI,KAAA;AAAA,kBACR,CAAA,qBAAA,EAAwB,MAAM,IAAI,CAAA,YAAA,CAAA;AAAA,iBACpC,CAAA;AAAA,aACJ;AAAA,WACF;AAAA,UACA,OAAO,CAAS,KAAA,KAAA;AACd,YAAS,QAAA,EAAA,CAAA;AAOT,YAAA,MAAM,UAAa,GAAA,CAAA,CAAA;AAEnB,YAAI,IAAA,CAAC,MAAM,OAAS,EAAA;AAClB,cAAA,KAAA,CAAM,UAAU,CACd,2EAAA,EAAA,UAAA,GAAa,aAAa,UAAa,GAAA,UACzC,IAAI,UAAU,CAAA,SAAA,CAAA,CAAA;AAAA,aAChB;AAEA,YAAA,UAAA,CAAW,MAAM;AACf,cAAc,UAAA,IAAA,CAAA,CAAA;AACd,cAAA,KAAK,qBAAsB,EAAA,CAAA;AAAA,eAC1B,IAAK,CAAA,CAAA;AAER,YAAA,QAAA,CAAS,EAAE,IAAA,EAAM,OAAS,EAAA,IAAA,EAAM,OAAO,CAAA,CAAA;AAAA,WACzC;AAAA,SACD,CAAA,CAAA;AAAA,OACH;AAAA,MACA,CAAS,KAAA,KAAA;AACP,QAAA,IAAI,CAAC,SAAW,EAAA;AACd,UAAA,QAAA,CAAS,EAAE,IAAA,EAAM,OAAS,EAAA,IAAA,EAAM,OAAO,CAAA,CAAA;AAAA,SACzC;AAAA,OACF;AAAA,KACF,CAAA;AACF,IAAA,KAAK,qBAAsB,EAAA,CAAA;AAC3B,IAAA,OAAO,MAAM;AACX,MAAY,SAAA,GAAA,IAAA,CAAA;AACZ,MAAA,IAAI,YAAc,EAAA;AAChB,QAAA,YAAA,CAAa,WAAY,EAAA,CAAA;AAAA,OAC3B;AACA,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,aAAA,CAAc,SAAS,CAAA,CAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACC,EAAA,CAAC,aAAe,EAAA,QAAA,EAAU,MAAM,CAAC,CAAA,CAAA;AAEpC,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
|
|
1
|
+
{"version":3,"file":"useEventStream.esm.js","sources":["../../src/hooks/useEventStream.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useImmerReducer } from 'use-immer';\nimport { useEffect } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Subscription } from '@backstage/types';\nimport {\n LogEvent,\n scaffolderApiRef,\n ScaffolderTask,\n ScaffolderTaskOutput,\n ScaffolderTaskStatus,\n} from '../api';\n\n/**\n * The status of the step being processed\n *\n * @public\n */\nexport type ScaffolderStep = {\n id: string;\n status: ScaffolderTaskStatus;\n endedAt?: string;\n startedAt?: string;\n};\n\n/**\n * A task event from the event stream\n *\n * @public\n */\nexport type TaskStream = {\n cancelled: boolean;\n loading: boolean;\n error?: Error;\n stepLogs: { [stepId in string]: string[] };\n completed: boolean;\n task?: ScaffolderTask;\n steps: { [stepId in string]: ScaffolderStep };\n output?: ScaffolderTaskOutput;\n};\n\ntype ReducerLogEntry = {\n createdAt: string;\n body: {\n stepId?: string;\n status?: ScaffolderTaskStatus;\n message: string;\n output?: ScaffolderTaskOutput;\n error?: Error;\n recoverStrategy?: 'none' | 'startOver';\n };\n};\n\ntype ReducerAction =\n | { type: 'INIT'; data: ScaffolderTask }\n | { type: 'CANCELLED' }\n | { type: 'RECOVERED'; data: ReducerLogEntry }\n | { type: 'LOGS'; data: ReducerLogEntry[] }\n | { type: 'COMPLETED'; data: ReducerLogEntry }\n | { type: 'ERROR'; data: Error };\n\nfunction reducer(draft: TaskStream, action: ReducerAction) {\n switch (action.type) {\n case 'INIT': {\n draft.steps = action.data.spec.steps.reduce((current, next) => {\n current[next.id] = { status: 'open', id: next.id };\n return current;\n }, {} as { [stepId in string]: ScaffolderStep });\n draft.stepLogs = action.data.spec.steps.reduce((current, next) => {\n current[next.id] = [];\n return current;\n }, {} as { [stepId in string]: string[] });\n draft.loading = false;\n draft.error = undefined;\n draft.completed = false;\n draft.task = action.data;\n return;\n }\n\n case 'LOGS': {\n const entries = action.data;\n const logLines = [];\n\n for (const entry of entries) {\n const logLine = `${entry.createdAt} ${entry.body.message}`;\n logLines.push(logLine);\n\n if (!entry.body.stepId || !draft.steps?.[entry.body.stepId]) {\n continue;\n }\n\n const currentStepLog = draft.stepLogs?.[entry.body.stepId];\n const currentStep = draft.steps?.[entry.body.stepId];\n\n if (currentStep) {\n if (entry.body.status && entry.body.status !== currentStep.status) {\n currentStep.status = entry.body.status;\n\n if (currentStep.status === 'processing') {\n currentStep.startedAt = entry.createdAt;\n }\n\n if (\n ['cancelled', 'completed', 'failed'].includes(currentStep.status)\n ) {\n currentStep.endedAt = entry.createdAt;\n }\n }\n }\n\n currentStepLog?.push(logLine);\n }\n\n return;\n }\n\n case 'COMPLETED': {\n draft.completed = true;\n draft.output = action.data.body.output;\n draft.error = action.data.body.error;\n\n return;\n }\n\n case 'CANCELLED': {\n draft.cancelled = true;\n return;\n }\n\n case 'RECOVERED': {\n draft.cancelled = false;\n draft.completed = false;\n draft.output = undefined;\n draft.error = undefined;\n\n for (const stepId in draft.steps) {\n if (draft.steps.hasOwnProperty(stepId)) {\n draft.steps[stepId].startedAt = undefined;\n draft.steps[stepId].endedAt = undefined;\n draft.steps[stepId].status = 'open';\n }\n }\n return;\n }\n\n case 'ERROR': {\n draft.error = action.data;\n draft.loading = false;\n draft.completed = true;\n return;\n }\n\n default:\n return;\n }\n}\n\n/**\n * A hook to stream the logs of a task being processed\n *\n * @public\n */\nexport const useTaskEventStream = (taskId: string): TaskStream => {\n const scaffolderApi = useApi(scaffolderApiRef);\n const [state, dispatch] = useImmerReducer(reducer, {\n cancelled: false,\n loading: true,\n completed: false,\n stepLogs: {} as { [stepId in string]: string[] },\n steps: {} as { [stepId in string]: ScaffolderStep },\n });\n\n useEffect(() => {\n let didCancel = false;\n let subscription: Subscription | undefined;\n let logPusher: NodeJS.Timeout | undefined;\n let retryCount = 1;\n let isTaskRecoverable = false;\n const startStreamLogProcess = () =>\n scaffolderApi.getTask(taskId).then(\n task => {\n if (didCancel) {\n return;\n }\n isTaskRecoverable =\n task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ===\n 'startOver';\n dispatch({ type: 'INIT', data: task });\n\n // TODO(blam): Use a normal fetch to fetch the current log for the event stream\n // and use that for an INIT_EVENTs dispatch event, and then\n // use the last event ID to subscribe using after option to\n // stream logs. Without this, if you have a lot of logs, it can look like the\n // task is being rebuilt on load as it progresses through the steps at a slower\n // rate whilst it builds the status from the event logs\n const observable = scaffolderApi.streamLogs({\n isTaskRecoverable,\n taskId,\n });\n\n const collectedLogEvents = new Array<LogEvent>();\n\n function emitLogs() {\n if (collectedLogEvents.length) {\n const logs = collectedLogEvents.splice(\n 0,\n collectedLogEvents.length,\n );\n dispatch({ type: 'LOGS', data: logs });\n }\n }\n\n logPusher = setInterval(emitLogs, 500);\n\n subscription = observable.subscribe({\n next: event => {\n retryCount = 1;\n switch (event.type) {\n case 'log':\n return collectedLogEvents.push(event);\n case 'cancelled':\n dispatch({ type: 'CANCELLED' });\n return undefined;\n case 'completion':\n emitLogs();\n dispatch({ type: 'COMPLETED', data: event });\n return undefined;\n case 'recovered':\n dispatch({ type: 'RECOVERED', data: event });\n return undefined;\n default:\n throw new Error(\n `Unhandled event type ${event.type} in observer`,\n );\n }\n },\n error: error => {\n emitLogs();\n // in some cases the error is a refused connection from backend\n // this can happen from internet issues or proxy problems\n // so we try to reconnect again after some time\n // just to restart the fetch process\n // details here https://github.com/backstage/backstage/issues/15002\n\n const maxRetries = 3;\n\n if (!error.message) {\n error.message = `We cannot connect at the moment, trying again in some seconds... Retrying (${\n retryCount > maxRetries ? maxRetries : retryCount\n }/${maxRetries} retries)`;\n }\n\n setTimeout(() => {\n retryCount += 1;\n void startStreamLogProcess();\n }, 15000);\n\n dispatch({ type: 'ERROR', data: error });\n },\n });\n },\n error => {\n if (!didCancel) {\n dispatch({ type: 'ERROR', data: error });\n }\n },\n );\n void startStreamLogProcess();\n return () => {\n if (!isTaskRecoverable) {\n didCancel = true;\n if (subscription) {\n subscription.unsubscribe();\n }\n if (logPusher) {\n clearInterval(logPusher);\n }\n }\n };\n }, [scaffolderApi, dispatch, taskId]);\n\n return state;\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
2
|
import { ApiHolder, Extension } from '@backstage/core-plugin-api';
|
|
4
3
|
import React__default, { HTMLAttributes, ReactNode, FormEvent, ElementType, Ref, ComponentType, PropsWithChildren } from 'react';
|
|
5
4
|
import { JsonObject, JsonValue, Observable } from '@backstage/types';
|
|
@@ -7,6 +6,8 @@ import { JSONSchema7 } from 'json-schema';
|
|
|
7
6
|
import { StrictRJSFSchema, RJSFSchema, FormContextType, GenericObjectType, UiSchema, IdSchema, ErrorSchema, Registry, ValidatorType, TemplatesType, RegistryWidgetsType, RJSFValidationError, CustomValidator, ErrorTransformer, Experimental_DefaultFormStateBehavior, UIOptionsType, FieldValidation } from '@rjsf/utils';
|
|
8
7
|
import Form, { IChangeEvent, FormProps as FormProps$1 } from '@rjsf/core';
|
|
9
8
|
import { TemplateEntityV1beta3, TemplatePresentationV1beta3, TaskSpec, TaskStep } from '@backstage/plugin-scaffolder-common';
|
|
9
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
10
|
+
import { z } from 'zod';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* The props for the `Field` components
|
|
@@ -499,6 +500,7 @@ interface ScaffolderGetIntegrationsListResponse {
|
|
|
499
500
|
* @public
|
|
500
501
|
*/
|
|
501
502
|
interface ScaffolderStreamLogsOptions {
|
|
503
|
+
isTaskRecoverable?: boolean;
|
|
502
504
|
taskId: string;
|
|
503
505
|
after?: number;
|
|
504
506
|
}
|
|
@@ -544,6 +546,12 @@ interface ScaffolderApi {
|
|
|
544
546
|
* @param taskId - the id of the task
|
|
545
547
|
*/
|
|
546
548
|
cancelTask(taskId: string): Promise<void>;
|
|
549
|
+
/**
|
|
550
|
+
* Starts the task again from the point where it failed.
|
|
551
|
+
*
|
|
552
|
+
* @param taskId - the id of the task
|
|
553
|
+
*/
|
|
554
|
+
retry?(taskId: string): Promise<void>;
|
|
547
555
|
listTasks?(options: {
|
|
548
556
|
filterByOwnership: 'owned' | 'all';
|
|
549
557
|
}): Promise<{
|
|
@@ -569,7 +577,7 @@ interface ScaffolderApi {
|
|
|
569
577
|
}
|
|
570
578
|
|
|
571
579
|
/** @public */
|
|
572
|
-
declare const scaffolderApiRef:
|
|
580
|
+
declare const scaffolderApiRef: _backstage_frontend_plugin_api.ApiRef<ScaffolderApi>;
|
|
573
581
|
|
|
574
582
|
/**
|
|
575
583
|
* Hook that returns all custom field extensions from the current outlet.
|
|
@@ -653,4 +661,23 @@ type TaskStream = {
|
|
|
653
661
|
*/
|
|
654
662
|
declare const useTaskEventStream: (taskId: string) => TaskStream;
|
|
655
663
|
|
|
656
|
-
|
|
664
|
+
/** @public */
|
|
665
|
+
declare function makeFieldSchema<TReturnType extends z.ZodType, TUiOptions extends z.ZodType>(options: {
|
|
666
|
+
output: (zImpl: typeof z) => TReturnType;
|
|
667
|
+
uiOptions?: (zImpl: typeof z) => TUiOptions;
|
|
668
|
+
}): FieldSchema<z.output<TReturnType>, z.output<TUiOptions>>;
|
|
669
|
+
/**
|
|
670
|
+
* @public
|
|
671
|
+
* FieldSchema encapsulates a JSONSchema7 along with the
|
|
672
|
+
* matching FieldExtensionComponentProps type for a field extension.
|
|
673
|
+
*/
|
|
674
|
+
interface FieldSchema<TReturn, TUiOptions> {
|
|
675
|
+
/** @deprecated use TProps instead */
|
|
676
|
+
readonly type: FieldExtensionComponentProps<TReturn, TUiOptions>;
|
|
677
|
+
/** @deprecated will be removed */
|
|
678
|
+
readonly uiOptionsType: TUiOptions;
|
|
679
|
+
readonly schema: CustomFieldExtensionSchema;
|
|
680
|
+
readonly TProps: FieldExtensionComponentProps<TReturn, TUiOptions>;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export { type Action, type ActionExample, type CustomFieldExtensionSchema, type CustomFieldValidator, type FieldExtensionComponent, type FieldExtensionComponentProps, type FieldExtensionOptions, type FieldExtensionUiSchema, type FieldSchema, type FormProps, type LayoutComponent, type LayoutOptions, type LayoutTemplate, type ListActionsResponse, type LogEvent, type ReviewStepProps, type ScaffolderApi, type ScaffolderDryRunOptions, type ScaffolderDryRunResponse, ScaffolderFieldExtensions, type ScaffolderGetIntegrationsListOptions, type ScaffolderGetIntegrationsListResponse, ScaffolderLayouts, type ScaffolderOutputLink, type ScaffolderOutputText, type ScaffolderRJSFField, type ScaffolderRJSFFieldProps, type ScaffolderRJSFFormProps, type ScaffolderRJSFRegistryFieldsType, type ScaffolderScaffoldOptions, type ScaffolderScaffoldResponse, type ScaffolderStep, type ScaffolderStreamLogsOptions, type ScaffolderTask, type ScaffolderTaskOutput, type ScaffolderTaskStatus, type ScaffolderUseTemplateSecrets, SecretsContextProvider, type TaskStream, type TemplateGroupFilter, type TemplateParameterSchema, createScaffolderFieldExtension, createScaffolderLayout, makeFieldSchema, scaffolderApiRef, useCustomFieldExtensions, useCustomLayouts, useTaskEventStream, useTemplateSecrets };
|
package/dist/index.esm.js
CHANGED
|
@@ -5,4 +5,5 @@ export { useCustomFieldExtensions } from './hooks/useCustomFieldExtensions.esm.j
|
|
|
5
5
|
export { useCustomLayouts } from './hooks/useCustomLayouts.esm.js';
|
|
6
6
|
export { useTaskEventStream } from './hooks/useEventStream.esm.js';
|
|
7
7
|
export { ScaffolderLayouts, createScaffolderLayout } from './layouts/createScaffolderLayout.esm.js';
|
|
8
|
+
export { makeFieldSchema } from './utils.esm.js';
|
|
8
9
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createExtensionDataRef, createExtensionBlueprint } from '@backstage/frontend-plugin-api';
|
|
2
|
+
import { OpaqueFormField } from '../../packages/scaffolder-internal/src/wiring/InternalFormField.esm.js';
|
|
3
|
+
|
|
4
|
+
const formFieldExtensionDataRef = createExtensionDataRef().with({
|
|
5
|
+
id: "scaffolder.form-field-loader"
|
|
6
|
+
});
|
|
7
|
+
const FormFieldBlueprint = createExtensionBlueprint({
|
|
8
|
+
kind: "scaffolder-form-field",
|
|
9
|
+
attachTo: { id: "api:scaffolder/form-fields", input: "formFields" },
|
|
10
|
+
dataRefs: {
|
|
11
|
+
formFieldLoader: formFieldExtensionDataRef
|
|
12
|
+
},
|
|
13
|
+
output: [formFieldExtensionDataRef],
|
|
14
|
+
*factory(params) {
|
|
15
|
+
yield formFieldExtensionDataRef(params.field);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
function createFormField(opts) {
|
|
19
|
+
return OpaqueFormField.createInstance("v1", opts);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { FormFieldBlueprint, createFormField };
|
|
23
|
+
//# sourceMappingURL=FormFieldBlueprint.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormFieldBlueprint.esm.js","sources":["../../../src/next/blueprints/FormFieldBlueprint.tsx"],"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 */\nimport {\n createExtensionBlueprint,\n createExtensionDataRef,\n} from '@backstage/frontend-plugin-api';\nimport { z } from 'zod';\n\nimport { OpaqueFormField, FormField } from '@internal/scaffolder';\nimport { FormFieldExtensionData } from './types';\n\nconst formFieldExtensionDataRef = createExtensionDataRef<\n () => Promise<FormField>\n>().with({\n id: 'scaffolder.form-field-loader',\n});\n\n/**\n * @alpha\n * Creates extensions that are Field Extensions for the Scaffolder\n * */\nexport const FormFieldBlueprint = createExtensionBlueprint({\n kind: 'scaffolder-form-field',\n attachTo: { id: 'api:scaffolder/form-fields', input: 'formFields' },\n dataRefs: {\n formFieldLoader: formFieldExtensionDataRef,\n },\n output: [formFieldExtensionDataRef],\n *factory(params: { field: () => Promise<FormField> }) {\n yield formFieldExtensionDataRef(params.field);\n },\n});\n\n/**\n * @alpha\n * Used to create a form field binding with typechecking for compliance\n */\nexport function createFormField<\n TReturnValue extends z.ZodType,\n TUiOptions extends z.ZodType,\n>(opts: FormFieldExtensionData<TReturnValue, TUiOptions>): FormField {\n return OpaqueFormField.createInstance('v1', opts);\n}\n"],"names":[],"mappings":";;;AAwBA,MAAM,yBAAA,GAA4B,sBAEhC,EAAA,CAAE,IAAK,CAAA;AAAA,EACP,EAAI,EAAA,8BAAA;AACN,CAAC,CAAA,CAAA;AAMM,MAAM,qBAAqB,wBAAyB,CAAA;AAAA,EACzD,IAAM,EAAA,uBAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,4BAAA,EAA8B,OAAO,YAAa,EAAA;AAAA,EAClE,QAAU,EAAA;AAAA,IACR,eAAiB,EAAA,yBAAA;AAAA,GACnB;AAAA,EACA,MAAA,EAAQ,CAAC,yBAAyB,CAAA;AAAA,EAClC,CAAC,QAAQ,MAA6C,EAAA;AACpD,IAAM,MAAA,yBAAA,CAA0B,OAAO,KAAK,CAAA,CAAA;AAAA,GAC9C;AACF,CAAC,EAAA;AAMM,SAAS,gBAGd,IAAmE,EAAA;AACnE,EAAO,OAAA,eAAA,CAAgB,cAAe,CAAA,IAAA,EAAM,IAAI,CAAA,CAAA;AAClD;;;;"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
class OpaqueType {
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new opaque type.
|
|
4
|
+
*
|
|
5
|
+
* @param options.type The type identifier of the opaque type
|
|
6
|
+
* @param options.versions The available versions of the opaque type
|
|
7
|
+
* @returns A new opaque type helper
|
|
8
|
+
*/
|
|
9
|
+
static create(options) {
|
|
10
|
+
return new OpaqueType(options.type, new Set(options.versions));
|
|
11
|
+
}
|
|
12
|
+
#type;
|
|
13
|
+
#versions;
|
|
14
|
+
constructor(type, versions) {
|
|
15
|
+
this.#type = type;
|
|
16
|
+
this.#versions = versions;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
*
|
|
23
|
+
* This property is only useful for type checking, its runtime value is `undefined`.
|
|
24
|
+
*/
|
|
25
|
+
TPublic = void 0;
|
|
26
|
+
/**
|
|
27
|
+
* The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
*
|
|
31
|
+
* This property is only useful for type checking, its runtime value is `undefined`.
|
|
32
|
+
*/
|
|
33
|
+
TInternal = void 0;
|
|
34
|
+
/**
|
|
35
|
+
* @param value Input value expected to be an instance of this opaque type
|
|
36
|
+
* @returns True if the value matches this opaque type
|
|
37
|
+
*/
|
|
38
|
+
isType = (value) => {
|
|
39
|
+
return this.#isThisInternalType(value);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* @param value Input value expected to be an instance of this opaque type
|
|
43
|
+
* @throws If the value is not an instance of this opaque type or is of an unsupported version
|
|
44
|
+
* @returns The internal version of the opaque type
|
|
45
|
+
*/
|
|
46
|
+
toInternal = (value) => {
|
|
47
|
+
if (!this.#isThisInternalType(value)) {
|
|
48
|
+
throw new TypeError(
|
|
49
|
+
`Invalid opaque type, expected '${this.#type}', but got '${this.#stringifyUnknown(value)}'`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (!this.#versions.has(value.version)) {
|
|
53
|
+
const versions = Array.from(this.#versions).map(this.#stringifyVersion);
|
|
54
|
+
if (versions.length > 1) {
|
|
55
|
+
versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;
|
|
56
|
+
}
|
|
57
|
+
const expected = versions.length > 2 ? versions.join(", ") : versions.join(" ");
|
|
58
|
+
throw new TypeError(
|
|
59
|
+
`Invalid opaque type instance, got version ${this.#stringifyVersion(
|
|
60
|
+
value.version
|
|
61
|
+
)}, expected ${expected}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Creates an instance of the opaque type, returning the public type.
|
|
68
|
+
*
|
|
69
|
+
* @param version The version of the instance to create
|
|
70
|
+
* @param value The remaining public and internal properties of the instance
|
|
71
|
+
* @returns An instance of the opaque type
|
|
72
|
+
*/
|
|
73
|
+
createInstance(version, props) {
|
|
74
|
+
return Object.assign(props, {
|
|
75
|
+
$$type: this.#type,
|
|
76
|
+
...version && { version }
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
#isThisInternalType(value) {
|
|
80
|
+
if (value === null || typeof value !== "object") {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return value.$$type === this.#type;
|
|
84
|
+
}
|
|
85
|
+
#stringifyUnknown(value) {
|
|
86
|
+
if (typeof value !== "object") {
|
|
87
|
+
return `<${typeof value}>`;
|
|
88
|
+
}
|
|
89
|
+
if (value === null) {
|
|
90
|
+
return "<null>";
|
|
91
|
+
}
|
|
92
|
+
if ("$$type" in value) {
|
|
93
|
+
return String(value.$$type);
|
|
94
|
+
}
|
|
95
|
+
return String(value);
|
|
96
|
+
}
|
|
97
|
+
#stringifyVersion = (version) => {
|
|
98
|
+
return version ? `'${version}'` : "undefined";
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { OpaqueType };
|
|
103
|
+
//# sourceMappingURL=OpaqueType.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpaqueType.esm.js","sources":["../../../../../../packages/opaque-internal/src/OpaqueType.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\n// TODO(Rugvip): This lives here temporarily, but should be moved to a more\n// central location. It's useful for backend packages too so we'll need to have\n// it in a common package, but it might also be that we want to make it\n// available publicly too in which case it would make sense to have this be part\n// of @backstage/version-bridge. The problem with exporting it from there is\n// that it would need to be very stable at that point, so it might be a bit\n// early to put it there already.\n\n/**\n * A helper for working with opaque types.\n */\nexport class OpaqueType<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n> {\n /**\n * Creates a new opaque type.\n *\n * @param options.type The type identifier of the opaque type\n * @param options.versions The available versions of the opaque type\n * @returns A new opaque type helper\n */\n static create<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n >(options: {\n type: T['public']['$$type'];\n versions: Array<T['versions']['version']>;\n }) {\n return new OpaqueType<T>(options.type, new Set(options.versions));\n }\n\n #type: string;\n #versions: Set<string | undefined>;\n\n private constructor(type: string, versions: Set<string | undefined>) {\n this.#type = type;\n this.#versions = versions;\n }\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TPublic: T['public'] = undefined as any;\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TInternal: T['public'] & T['versions'] = undefined as any;\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @returns True if the value matches this opaque type\n */\n isType = (value: unknown): value is T['public'] => {\n return this.#isThisInternalType(value);\n };\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @throws If the value is not an instance of this opaque type or is of an unsupported version\n * @returns The internal version of the opaque type\n */\n toInternal = (value: unknown): T['public'] & T['versions'] => {\n if (!this.#isThisInternalType(value)) {\n throw new TypeError(\n `Invalid opaque type, expected '${\n this.#type\n }', but got '${this.#stringifyUnknown(value)}'`,\n );\n }\n\n if (!this.#versions.has(value.version)) {\n const versions = Array.from(this.#versions).map(this.#stringifyVersion);\n if (versions.length > 1) {\n versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;\n }\n const expected =\n versions.length > 2 ? versions.join(', ') : versions.join(' ');\n throw new TypeError(\n `Invalid opaque type instance, got version ${this.#stringifyVersion(\n value.version,\n )}, expected ${expected}`,\n );\n }\n\n return value;\n };\n\n /**\n * Creates an instance of the opaque type, returning the public type.\n *\n * @param version The version of the instance to create\n * @param value The remaining public and internal properties of the instance\n * @returns An instance of the opaque type\n */\n createInstance<\n TVersion extends T['versions']['version'],\n TPublic extends T['public'],\n >(\n version: TVersion,\n props: Omit<T['public'], '$$type'> &\n (T['versions'] extends infer UVersion\n ? UVersion extends { version: TVersion }\n ? Omit<UVersion, 'version'>\n : never\n : never) &\n Object, // & Object to allow for object properties too, e.g. toString()\n ): TPublic {\n return Object.assign(props as object, {\n $$type: this.#type,\n ...(version && { version }),\n }) as unknown as TPublic;\n }\n\n #isThisInternalType(value: unknown): value is T['public'] & T['versions'] {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n return (value as T['public']).$$type === this.#type;\n }\n\n #stringifyUnknown(value: unknown) {\n if (typeof value !== 'object') {\n return `<${typeof value}>`;\n }\n if (value === null) {\n return '<null>';\n }\n if ('$$type' in value) {\n return String(value.$$type);\n }\n return String(value);\n }\n\n #stringifyVersion = (version: string | undefined) => {\n return version ? `'${version}'` : 'undefined';\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
|
|
2
|
+
|
|
3
|
+
const OpaqueFormField = OpaqueType.create({ type: "@backstage/scaffolder/FormField", versions: ["v1"] });
|
|
4
|
+
|
|
5
|
+
export { OpaqueFormField };
|
|
6
|
+
//# sourceMappingURL=InternalFormField.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InternalFormField.esm.js","sources":["../../../../../../../packages/scaffolder-internal/src/wiring/InternalFormField.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 { OpaqueType } from '@internal/opaque';\nimport { z } from 'zod';\n\nimport { FormFieldExtensionData } from '@backstage/plugin-scaffolder-react/alpha';\n\n/** @alpha */\nexport interface FormField {\n readonly $$type: '@backstage/scaffolder/FormField';\n}\n\n/** @alpha */\nexport const OpaqueFormField = OpaqueType.create<{\n public: FormField;\n versions: FormFieldExtensionData<z.ZodType, z.ZodType> & {\n readonly version: 'v1';\n };\n}>({ type: '@backstage/scaffolder/FormField', versions: ['v1'] });\n"],"names":[],"mappings":";;AA2Ba,MAAA,eAAA,GAAkB,UAAW,CAAA,MAAA,CAKvC,EAAE,IAAA,EAAM,mCAAmC,QAAU,EAAA,CAAC,IAAI,CAAA,EAAG;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import zodToJsonSchema from 'zod-to-json-schema';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
function makeFieldSchema(options) {
|
|
5
|
+
const { output, uiOptions } = options;
|
|
6
|
+
return {
|
|
7
|
+
TProps: void 0,
|
|
8
|
+
schema: {
|
|
9
|
+
returnValue: zodToJsonSchema(output(z)),
|
|
10
|
+
uiOptions: uiOptions && zodToJsonSchema(uiOptions(z))
|
|
11
|
+
},
|
|
12
|
+
// These will be removed - just here for backwards compat whilst we're moving across
|
|
13
|
+
type: void 0,
|
|
14
|
+
uiOptionsType: void 0
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { makeFieldSchema };
|
|
19
|
+
//# sourceMappingURL=utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.esm.js","sources":["../src/utils.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 zodToJsonSchema from 'zod-to-json-schema';\nimport { JSONSchema7 } from 'json-schema';\nimport { z } from 'zod';\nimport {\n CustomFieldExtensionSchema,\n FieldExtensionComponentProps,\n} from './extensions';\n\n/** @public */\nexport function makeFieldSchema<\n TReturnType extends z.ZodType,\n TUiOptions extends z.ZodType,\n>(options: {\n output: (zImpl: typeof z) => TReturnType;\n uiOptions?: (zImpl: typeof z) => TUiOptions;\n}): FieldSchema<z.output<TReturnType>, z.output<TUiOptions>> {\n const { output, uiOptions } = options;\n return {\n TProps: undefined as any,\n schema: {\n returnValue: zodToJsonSchema(output(z)) as JSONSchema7,\n uiOptions: uiOptions && (zodToJsonSchema(uiOptions(z)) as JSONSchema7),\n },\n\n // These will be removed - just here for backwards compat whilst we're moving across\n type: undefined as any,\n uiOptionsType: undefined as any,\n };\n}\n\n/**\n * @public\n * FieldSchema encapsulates a JSONSchema7 along with the\n * matching FieldExtensionComponentProps type for a field extension.\n */\nexport interface FieldSchema<TReturn, TUiOptions> {\n /** @deprecated use TProps instead */\n readonly type: FieldExtensionComponentProps<TReturn, TUiOptions>;\n /** @deprecated will be removed */\n readonly uiOptionsType: TUiOptions;\n\n readonly schema: CustomFieldExtensionSchema;\n readonly TProps: FieldExtensionComponentProps<TReturn, TUiOptions>;\n}\n"],"names":[],"mappings":";;;AAyBO,SAAS,gBAGd,OAG2D,EAAA;AAC3D,EAAM,MAAA,EAAE,MAAQ,EAAA,SAAA,EAAc,GAAA,OAAA,CAAA;AAC9B,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,KAAA,CAAA;AAAA,IACR,MAAQ,EAAA;AAAA,MACN,WAAa,EAAA,eAAA,CAAgB,MAAO,CAAA,CAAC,CAAC,CAAA;AAAA,MACtC,SAAW,EAAA,SAAA,IAAc,eAAgB,CAAA,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,KACvD;AAAA;AAAA,IAGA,IAAM,EAAA,KAAA,CAAA;AAAA,IACN,aAAe,EAAA,KAAA,CAAA;AAAA,GACjB,CAAA;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0-next.0",
|
|
4
4
|
"description": "A frontend library that helps other Backstage plugins interact with the Scaffolder",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "web-library",
|
|
@@ -57,24 +57,25 @@
|
|
|
57
57
|
"test": "backstage-cli package test"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@backstage/catalog-client": "^1.7.0
|
|
61
|
-
"@backstage/catalog-model": "^1.
|
|
62
|
-
"@backstage/core-components": "^0.
|
|
63
|
-
"@backstage/core-plugin-api": "^1.
|
|
64
|
-
"@backstage/plugin-
|
|
65
|
-
"@backstage/plugin-
|
|
66
|
-
"@backstage/plugin-
|
|
67
|
-
"@backstage/
|
|
60
|
+
"@backstage/catalog-client": "^1.7.0",
|
|
61
|
+
"@backstage/catalog-model": "^1.7.0",
|
|
62
|
+
"@backstage/core-components": "^0.15.1-next.0",
|
|
63
|
+
"@backstage/core-plugin-api": "^1.10.0-next.0",
|
|
64
|
+
"@backstage/frontend-plugin-api": "^0.9.0-next.0",
|
|
65
|
+
"@backstage/plugin-catalog-react": "^1.13.1-next.0",
|
|
66
|
+
"@backstage/plugin-permission-react": "^0.4.27-next.0",
|
|
67
|
+
"@backstage/plugin-scaffolder-common": "^1.5.6",
|
|
68
|
+
"@backstage/theme": "^0.5.7",
|
|
68
69
|
"@backstage/types": "^1.1.1",
|
|
69
|
-
"@backstage/version-bridge": "^1.0.9
|
|
70
|
+
"@backstage/version-bridge": "^1.0.9",
|
|
70
71
|
"@material-ui/core": "^4.12.2",
|
|
71
72
|
"@material-ui/icons": "^4.9.1",
|
|
72
73
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
73
74
|
"@react-hookz/web": "^24.0.0",
|
|
74
|
-
"@rjsf/core": "5.
|
|
75
|
-
"@rjsf/material-ui": "5.
|
|
76
|
-
"@rjsf/utils": "5.
|
|
77
|
-
"@rjsf/validator-ajv8": "5.
|
|
75
|
+
"@rjsf/core": "5.21.1",
|
|
76
|
+
"@rjsf/material-ui": "5.21.1",
|
|
77
|
+
"@rjsf/utils": "5.21.1",
|
|
78
|
+
"@rjsf/validator-ajv8": "5.21.1",
|
|
78
79
|
"@types/json-schema": "^7.0.9",
|
|
79
80
|
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
80
81
|
"ajv-errors": "^3.0.0",
|
|
@@ -93,12 +94,12 @@
|
|
|
93
94
|
"zod-to-json-schema": "^3.20.4"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
|
-
"@backstage/cli": "^0.
|
|
97
|
-
"@backstage/core-app-api": "^1.
|
|
98
|
-
"@backstage/plugin-catalog": "^1.
|
|
99
|
-
"@backstage/plugin-catalog-common": "^1.0
|
|
97
|
+
"@backstage/cli": "^0.28.0-next.0",
|
|
98
|
+
"@backstage/core-app-api": "^1.15.1-next.0",
|
|
99
|
+
"@backstage/plugin-catalog": "^1.24.0-next.0",
|
|
100
|
+
"@backstage/plugin-catalog-common": "^1.1.0",
|
|
100
101
|
"@backstage/plugin-permission-common": "^0.8.1",
|
|
101
|
-
"@backstage/test-utils": "^1.6.
|
|
102
|
+
"@backstage/test-utils": "^1.6.1-next.0",
|
|
102
103
|
"@testing-library/dom": "^10.0.0",
|
|
103
104
|
"@testing-library/jest-dom": "^6.0.0",
|
|
104
105
|
"@testing-library/react": "^16.0.0",
|