@backstage/plugin-scaffolder-react 1.5.6 → 1.6.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,21 +1,247 @@
1
1
  /// <reference types="react" />
2
- import React__default, { PropsWithChildren } from 'react';
3
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
3
  import { ApiHolder, Extension } from '@backstage/core-plugin-api';
5
- import { FieldValidation, FieldProps } from '@rjsf/core';
6
- import { JSONSchema7 } from 'json-schema';
4
+ import React__default, { HTMLAttributes, ReactNode, FormEvent, ElementType, Ref, ComponentType, PropsWithChildren } from 'react';
7
5
  import { JsonObject, JsonValue, Observable } from '@backstage/types';
8
- import { TaskSpec, TaskStep } from '@backstage/plugin-scaffolder-common';
9
- import { FormProps } from '@rjsf/core-v5';
6
+ import { JSONSchema7 } from 'json-schema';
7
+ import { StrictRJSFSchema, RJSFSchema, FormContextType, GenericObjectType, UiSchema, IdSchema, ErrorSchema, Registry, ValidatorType, TemplatesType, RegistryWidgetsType, RJSFValidationError, CustomValidator, ErrorTransformer, Experimental_DefaultFormStateBehavior, UIOptionsType, FieldValidation } from '@rjsf/utils';
8
+ import Form, { IChangeEvent, FormProps as FormProps$1 } from '@rjsf/core';
9
+ import { TemplateEntityV1beta3, TemplatePresentationV1beta3, TaskSpec, TaskStep } from '@backstage/plugin-scaffolder-common';
10
10
 
11
11
  /**
12
- * Field validation type for Custom Field Extensions.
12
+ * The props for the `Field` components
13
+ * @public
14
+ */
15
+ interface ScaffolderRJSFFieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends GenericObjectType, Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
16
+ /** The JSON subschema object for this field */
17
+ schema: S;
18
+ /** The uiSchema for this field */
19
+ uiSchema: UiSchema<T, S, F>;
20
+ /** The tree of unique ids for every child field */
21
+ idSchema: IdSchema<T>;
22
+ /** The data for this field */
23
+ formData: T;
24
+ /** The tree of errors for this field and its children */
25
+ errorSchema?: ErrorSchema<T>;
26
+ /** The field change event handler; called with the updated form data and an optional `ErrorSchema` */
27
+ onChange: (newFormData: T | undefined, es?: ErrorSchema<T>, id?: string) => any;
28
+ /** The input blur event handler; call it with the field id and value */
29
+ onBlur: (id: string, value: any) => void;
30
+ /** The input focus event handler; call it with the field id and value */
31
+ onFocus: (id: string, value: any) => void;
32
+ /** The `formContext` object that you passed to `Form` */
33
+ formContext?: F;
34
+ /** A boolean value stating if the field should autofocus */
35
+ autofocus?: boolean;
36
+ /** A boolean value stating if the field is disabled */
37
+ disabled: boolean;
38
+ /** A boolean value stating if the field is hiding its errors */
39
+ hideError?: boolean;
40
+ /** A boolean value stating if the field is read-only */
41
+ readonly: boolean;
42
+ /** The required status of this field */
43
+ required?: boolean;
44
+ /** The unique name of the field, usually derived from the name of the property in the JSONSchema */
45
+ name: string;
46
+ /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
47
+ * Default is `root`
48
+ */
49
+ idPrefix?: string;
50
+ /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
51
+ * ids (Default is `_`)
52
+ */
53
+ idSeparator?: string;
54
+ /** An array of strings listing all generated error messages from encountered errors for this field */
55
+ rawErrors: string[];
56
+ /** The `registry` object */
57
+ registry: Registry<T, S, F>;
58
+ }
59
+ /**
60
+ * The properties that are passed to the `Form`
61
+ * @public
62
+ */
63
+ interface ScaffolderRJSFFormProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
64
+ /** The JSON schema object for the form */
65
+ schema: S;
66
+ /** An implementation of the `ValidatorType` interface that is needed for form validation to work */
67
+ validator: ValidatorType<T, S, F>;
68
+ /** The optional children for the form, if provided, it will replace the default `SubmitButton` */
69
+ children?: ReactNode;
70
+ /** The uiSchema for the form */
71
+ uiSchema?: UiSchema<T, S, F>;
72
+ /** The data for the form, used to prefill a form with existing data */
73
+ formData?: T;
74
+ /** You can provide a `formContext` object to the form, which is passed down to all fields and widgets. Useful for
75
+ * implementing context aware fields and widgets.
76
+ *
77
+ * NOTE: Setting `{readonlyAsDisabled: false}` on the formContext will make the antd theme treat readOnly fields as
78
+ * disabled.
79
+ */
80
+ formContext?: F;
81
+ /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
82
+ * Default is `root`
83
+ */
84
+ idPrefix?: string;
85
+ /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
86
+ * ids (Default is `_`)
87
+ */
88
+ idSeparator?: string;
89
+ /** It's possible to disable the whole form by setting the `disabled` prop. The `disabled` prop is then forwarded down
90
+ * to each field of the form. If you just want to disable some fields, see the `ui:disabled` parameter in `uiSchema`
91
+ */
92
+ disabled?: boolean;
93
+ /** It's possible to make the whole form read-only by setting the `readonly` prop. The `readonly` prop is then
94
+ * forwarded down to each field of the form. If you just want to make some fields read-only, see the `ui:readonly`
95
+ * parameter in `uiSchema`
96
+ */
97
+ readonly?: boolean;
98
+ /** The dictionary of registered fields in the form */
99
+ fields?: ScaffolderRJSFRegistryFieldsType<T, S, F>;
100
+ /** The dictionary of registered templates in the form; Partial allows a subset to be provided beyond the defaults */
101
+ templates?: Partial<Omit<TemplatesType<T, S, F>, 'ButtonTemplates'>> & {
102
+ ButtonTemplates?: Partial<TemplatesType<T, S, F>['ButtonTemplates']>;
103
+ };
104
+ /** The dictionary of registered widgets in the form */
105
+ widgets?: RegistryWidgetsType<T, S, F>;
106
+ /** If you plan on being notified every time the form data are updated, you can pass an `onChange` handler, which will
107
+ * receive the same args as `onSubmit` any time a value is updated in the form. Can also return the `id` of the field
108
+ * that caused the change
109
+ */
110
+ onChange?: (data: IChangeEvent<T, S, F>, id?: string) => void;
111
+ /** To react when submitted form data are invalid, pass an `onError` handler. It will be passed the list of
112
+ * encountered errors
113
+ */
114
+ onError?: (errors: RJSFValidationError[]) => void;
115
+ /** You can pass a function as the `onSubmit` prop of your `Form` component to listen to when the form is submitted
116
+ * and its data are valid. It will be passed a result object having a `formData` attribute, which is the valid form
117
+ * data you're usually after. The original event will also be passed as a second parameter
118
+ */
119
+ onSubmit?: (data: IChangeEvent<T, S, F>, event: FormEvent<any>) => void;
120
+ /** Sometimes you may want to trigger events or modify external state when a field has been touched, so you can pass
121
+ * an `onBlur` handler, which will receive the id of the input that was blurred and the field value
122
+ */
123
+ onBlur?: (id: string, data: any) => void;
124
+ /** Sometimes you may want to trigger events or modify external state when a field has been focused, so you can pass
125
+ * an `onFocus` handler, which will receive the id of the input that is focused and the field value
126
+ */
127
+ onFocus?: (id: string, data: any) => void;
128
+ /** The value of this prop will be passed to the `accept-charset` HTML attribute on the form */
129
+ acceptcharset?: string;
130
+ /** The value of this prop will be passed to the `action` HTML attribute on the form
131
+ *
132
+ * NOTE: this just renders the `action` attribute in the HTML markup. There is no real network request being sent to
133
+ * this `action` on submit. Instead, react-jsonschema-form catches the submit event with `event.preventDefault()`
134
+ * and then calls the `onSubmit` function, where you could send a request programmatically with `fetch` or similar.
135
+ */
136
+ action?: string;
137
+ /** The value of this prop will be passed to the `autocomplete` HTML attribute on the form */
138
+ autoComplete?: string;
139
+ /** The value of this prop will be passed to the `class` HTML attribute on the form */
140
+ className?: string;
141
+ /** The value of this prop will be passed to the `enctype` HTML attribute on the form */
142
+ enctype?: string;
143
+ /** The value of this prop will be passed to the `id` HTML attribute on the form */
144
+ id?: string;
145
+ /** The value of this prop will be passed to the `name` HTML attribute on the form */
146
+ name?: string;
147
+ /** The value of this prop will be passed to the `method` HTML attribute on the form */
148
+ method?: string;
149
+ /** It's possible to change the default `form` tag name to a different HTML tag, which can be helpful if you are
150
+ * nesting forms. However, native browser form behaviour, such as submitting when the `Enter` key is pressed, may no
151
+ * longer work
152
+ */
153
+ tagName?: ElementType;
154
+ /** The value of this prop will be passed to the `target` HTML attribute on the form */
155
+ target?: string;
156
+ /** Formerly the `validate` prop; Takes a function that specifies custom validation rules for the form */
157
+ customValidate?: CustomValidator<T, S, F>;
158
+ /** This prop allows passing in custom errors that are augmented with the existing JSON Schema errors on the form; it
159
+ * can be used to implement asynchronous validation
160
+ */
161
+ extraErrors?: ErrorSchema<T>;
162
+ /** If set to true, turns off HTML5 validation on the form; Set to `false` by default */
163
+ noHtml5Validate?: boolean;
164
+ /** If set to true, turns off all validation. Set to `false` by default
165
+ *
166
+ * @deprecated - In a future release, this switch may be replaced by making `validator` prop optional
167
+ */
168
+ noValidate?: boolean;
169
+ /** If set to true, the form will perform validation and show any validation errors whenever the form data is changed,
170
+ * rather than just on submit
171
+ */
172
+ liveValidate?: boolean;
173
+ /** If `omitExtraData` and `liveOmit` are both set to true, then extra form data values that are not in any form field
174
+ * will be removed whenever `onChange` is called. Set to `false` by default
175
+ */
176
+ liveOmit?: boolean;
177
+ /** If set to true, then extra form data values that are not in any form field will be removed whenever `onSubmit` is
178
+ * called. Set to `false` by default.
179
+ */
180
+ omitExtraData?: boolean;
181
+ /** When this prop is set to `top` or 'bottom', a list of errors (or the custom error list defined in the `ErrorList`) will also
182
+ * show. When set to false, only inline input validation errors will be shown. Set to `top` by default
183
+ */
184
+ showErrorList?: false | 'top' | 'bottom';
185
+ /** A function can be passed to this prop in order to make modifications to the default errors resulting from JSON
186
+ * Schema validation
187
+ */
188
+ transformErrors?: ErrorTransformer<T, S, F>;
189
+ /** If set to true, then the first field with an error will receive the focus when the form is submitted with errors
190
+ */
191
+ focusOnFirstError?: boolean | ((error: RJSFValidationError) => void);
192
+ /** Optional string translation function, if provided, allows users to change the translation of the RJSF internal
193
+ * strings. Some strings contain replaceable parameter values as indicated by `%1`, `%2`, etc. The number after the
194
+ * `%` indicates the order of the parameter. The ordering of parameters is important because some languages may choose
195
+ * to put the second parameter before the first in its translation.
196
+ */
197
+ translateString?: Registry['translateString'];
198
+ /** Optional configuration object with flags, if provided, allows users to override default form state behavior
199
+ * Currently only affecting minItems on array fields and handling of setting defaults based on the value of
200
+ * `emptyObjectFields`
201
+ */
202
+ experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;
203
+ /**
204
+ * _internalFormWrapper is currently used by the semantic-ui theme to provide a custom wrapper around `<Form />`
205
+ * that supports the proper rendering of those themes. To use this prop, one must pass a component that takes two
206
+ * props: `children` and `as`. That component, at minimum, should render the `children` inside of a <form /> tag
207
+ * unless `as` is provided, in which case, use the `as` prop in place of `<form />`.
208
+ * i.e.:
209
+ * ```
210
+ * export default function InternalForm({ children, as }) {
211
+ * const FormTag = as || 'form';
212
+ * return <FormTag>{children}</FormTag>;
213
+ * }
214
+ * ```
215
+ *
216
+ * Use at your own risk as this prop is private and may change at any time without notice.
217
+ */
218
+ _internalFormWrapper?: ElementType;
219
+ /** Support receiving a React ref to the Form
220
+ */
221
+ ref?: Ref<Form<T, S, F>>;
222
+ }
223
+ /**
224
+ * The set of `Fields` stored in the `Registry`
225
+ * @public
226
+ */
227
+ type ScaffolderRJSFRegistryFieldsType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = {
228
+ /** A `Field` indexed by `name` */
229
+ [name: string]: ScaffolderRJSFField<T, S, F>;
230
+ };
231
+ /**
232
+ * The `Field` type for Field Extensions
233
+ * @public
234
+ */
235
+ type ScaffolderRJSFField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = ComponentType<ScaffolderRJSFFieldProps<T, S, F>>;
236
+
237
+ /**
238
+ * Type for Field Extension Props for RJSF v5
13
239
  *
14
240
  * @public
15
241
  */
16
- type CustomFieldValidator<TFieldReturnValue> = (data: TFieldReturnValue, field: FieldValidation, context: {
17
- apiHolder: ApiHolder;
18
- }) => void | Promise<void>;
242
+ interface FieldExtensionComponentProps<TFieldReturnValue, TUiOptions = {}> extends PropsWithChildren<ScaffolderRJSFFieldProps<TFieldReturnValue>> {
243
+ uiSchema: FieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
244
+ }
19
245
  /**
20
246
  * Type for the Custom Field Extension schema.
21
247
  *
@@ -25,48 +251,86 @@ type CustomFieldExtensionSchema = {
25
251
  returnValue: JSONSchema7;
26
252
  uiOptions?: JSONSchema7;
27
253
  };
254
+ /**
255
+ * Type for Field Extension UiSchema
256
+ *
257
+ * @public
258
+ */
259
+ interface FieldExtensionUiSchema<TFieldReturnValue, TUiOptions> extends UiSchema<TFieldReturnValue> {
260
+ 'ui:options'?: TUiOptions & UIOptionsType<TFieldReturnValue>;
261
+ }
262
+ /**
263
+ * Field validation type for Custom Field Extensions.
264
+ *
265
+ * @public
266
+ */
267
+ type CustomFieldValidator<TFieldReturnValue, TUiOptions = unknown> = (data: TFieldReturnValue, field: FieldValidation, context: {
268
+ apiHolder: ApiHolder;
269
+ formData: JsonObject;
270
+ schema: JsonObject;
271
+ uiSchema?: FieldExtensionUiSchema<TFieldReturnValue, TUiOptions>;
272
+ }) => void | Promise<void>;
28
273
  /**
29
274
  * Type for the Custom Field Extension with the
30
275
  * name and components and validation function.
31
276
  *
32
277
  * @public
33
278
  */
34
- type FieldExtensionOptions<TFieldReturnValue = unknown, TInputProps = unknown> = {
279
+ type FieldExtensionOptions<TFieldReturnValue = unknown, TUiOptions = unknown> = {
35
280
  name: string;
36
- component: (props: FieldExtensionComponentProps<TFieldReturnValue, TInputProps>) => JSX.Element | null;
37
- validation?: CustomFieldValidator<TFieldReturnValue>;
281
+ component: (props: FieldExtensionComponentProps<TFieldReturnValue, TUiOptions>) => JSX.Element | null;
282
+ validation?: CustomFieldValidator<TFieldReturnValue, TUiOptions>;
38
283
  schema?: CustomFieldExtensionSchema;
39
284
  };
285
+
286
+ /**
287
+ * Method for creating field extensions that can be used in the scaffolder
288
+ * frontend form.
289
+ * @public
290
+ */
291
+ declare function createScaffolderFieldExtension<TReturnValue = unknown, TInputProps extends UIOptionsType = {}>(options: FieldExtensionOptions<TReturnValue, TInputProps>): Extension<FieldExtensionComponent<TReturnValue, TInputProps>>;
40
292
  /**
41
- * Type for field extensions and being able to type
42
- * incoming props easier.
293
+ * The Wrapping component for defining fields extensions inside
43
294
  *
44
295
  * @public
45
296
  */
46
- interface FieldExtensionComponentProps<TFieldReturnValue, TUiOptions = unknown> extends FieldProps<TFieldReturnValue> {
47
- uiSchema: FieldProps['uiSchema'] & {
48
- 'ui:options'?: TUiOptions;
49
- };
50
- }
51
-
297
+ declare const ScaffolderFieldExtensions: React.ComponentType<React.PropsWithChildren<{}>>;
52
298
  /**
53
299
  * The type used to wrap up the Layout and embed the input props
54
300
  *
55
301
  * @public
56
302
  */
57
303
  type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
304
+
305
+ /** @public */
306
+ type TemplateGroupFilter = {
307
+ title?: React.ReactNode;
308
+ filter: (entity: TemplateEntityV1beta3) => boolean;
309
+ };
58
310
  /**
59
- * Method for creating field extensions that can be used in the scaffolder
60
- * frontend form.
311
+ * Any `@rjsf/core` form properties that are publicly exposed to the `ScaffolderPage`
312
+ *
61
313
  * @public
62
314
  */
63
- declare function createScaffolderFieldExtension<TReturnValue = unknown, TInputProps = unknown>(options: FieldExtensionOptions<TReturnValue, TInputProps>): Extension<FieldExtensionComponent<TReturnValue, TInputProps>>;
315
+ type FormProps = Pick<FormProps$1, 'transformErrors' | 'noHtml5Validate'>;
64
316
  /**
65
- * The Wrapping component for defining fields extensions inside
317
+ * The props for the Last Step in scaffolder template form.
318
+ * Which represents the summary of the input provided by the end user.
66
319
  *
67
320
  * @public
68
321
  */
69
- declare const ScaffolderFieldExtensions: React__default.ComponentType<React__default.PropsWithChildren<{}>>;
322
+ type ReviewStepProps = {
323
+ disableButtons: boolean;
324
+ formData: JsonObject;
325
+ handleBack: () => void;
326
+ handleReset: () => void;
327
+ handleCreate: () => void;
328
+ steps: {
329
+ uiSchema: UiSchema;
330
+ mergedSchema: JsonObject;
331
+ schema: JsonObject;
332
+ }[];
333
+ };
70
334
 
71
335
  /**
72
336
  * The shape of each entry of parameters which gets rendered
@@ -77,6 +341,7 @@ declare const ScaffolderFieldExtensions: React__default.ComponentType<React__def
77
341
  type TemplateParameterSchema = {
78
342
  title: string;
79
343
  description?: string;
344
+ presentation?: TemplatePresentationV1beta3;
80
345
  steps: Array<{
81
346
  title: string;
82
347
  description?: string;
@@ -304,7 +569,7 @@ declare const useCustomFieldExtensions: <TComponentDataType = FieldExtensionOpti
304
569
  *
305
570
  * @public
306
571
  */
307
- type LayoutTemplate<T = any> = NonNullable<FormProps<T>['uiSchema']>['ui:ObjectFieldTemplate'];
572
+ type LayoutTemplate<T = any> = NonNullable<FormProps$1<T>['uiSchema']>['ui:ObjectFieldTemplate'];
308
573
  /**
309
574
  * The type of layouts that is passed to the TemplateForms
310
575
  *
@@ -375,4 +640,4 @@ type TaskStream = {
375
640
  */
376
641
  declare const useTaskEventStream: (taskId: string) => TaskStream;
377
642
 
378
- export { Action, ActionExample, CustomFieldExtensionSchema, CustomFieldValidator, FieldExtensionComponent, FieldExtensionComponentProps, FieldExtensionOptions, LayoutComponent, LayoutOptions, LayoutTemplate, ListActionsResponse, LogEvent, ScaffolderApi, ScaffolderDryRunOptions, ScaffolderDryRunResponse, ScaffolderFieldExtensions, ScaffolderGetIntegrationsListOptions, ScaffolderGetIntegrationsListResponse, ScaffolderLayouts, ScaffolderOutputLink, ScaffolderOutputText, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderStep, ScaffolderStreamLogsOptions, ScaffolderTask, ScaffolderTaskOutput, ScaffolderTaskStatus, ScaffolderUseTemplateSecrets, SecretsContextProvider, TaskStream, TemplateParameterSchema, createScaffolderFieldExtension, createScaffolderLayout, scaffolderApiRef, useCustomFieldExtensions, useCustomLayouts, useTaskEventStream, useTemplateSecrets };
643
+ export { Action, ActionExample, CustomFieldExtensionSchema, CustomFieldValidator, FieldExtensionComponent, FieldExtensionComponentProps, FieldExtensionOptions, FieldExtensionUiSchema, FormProps, LayoutComponent, LayoutOptions, LayoutTemplate, ListActionsResponse, LogEvent, ReviewStepProps, ScaffolderApi, ScaffolderDryRunOptions, ScaffolderDryRunResponse, ScaffolderFieldExtensions, ScaffolderGetIntegrationsListOptions, ScaffolderGetIntegrationsListResponse, ScaffolderLayouts, ScaffolderOutputLink, ScaffolderOutputText, ScaffolderRJSFField, ScaffolderRJSFFieldProps, ScaffolderRJSFFormProps, ScaffolderRJSFRegistryFieldsType, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderStep, ScaffolderStreamLogsOptions, ScaffolderTask, ScaffolderTaskOutput, ScaffolderTaskStatus, ScaffolderUseTemplateSecrets, SecretsContextProvider, TaskStream, TemplateGroupFilter, TemplateParameterSchema, createScaffolderFieldExtension, createScaffolderLayout, scaffolderApiRef, useCustomFieldExtensions, useCustomLayouts, useTaskEventStream, useTemplateSecrets };
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/extensions/index.tsx","../src/hooks/useCustomFieldExtensions.ts","../src/layouts/keys.ts","../src/hooks/useCustomLayouts.ts","../src/hooks/useEventStream.ts","../src/layouts/createScaffolderLayout.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n CustomFieldExtensionSchema,\n CustomFieldValidator,\n FieldExtensionOptions,\n FieldExtensionComponentProps,\n} from './types';\nimport { Extension, attachComponentData } from '@backstage/core-plugin-api';\nimport { FIELD_EXTENSION_KEY, FIELD_EXTENSION_WRAPPER_KEY } from './keys';\n\n/**\n * The type used to wrap up the Layout and embed the input props\n *\n * @public\n */\nexport type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;\n\n/**\n * Method for creating field extensions that can be used in the scaffolder\n * frontend form.\n * @public\n */\nexport function createScaffolderFieldExtension<\n TReturnValue = unknown,\n TInputProps = unknown,\n>(\n options: FieldExtensionOptions<TReturnValue, TInputProps>,\n): Extension<FieldExtensionComponent<TReturnValue, TInputProps>> {\n return {\n expose() {\n const FieldExtensionDataHolder: any = () => null;\n\n attachComponentData(\n FieldExtensionDataHolder,\n FIELD_EXTENSION_KEY,\n options,\n );\n\n return FieldExtensionDataHolder;\n },\n };\n}\n\n/**\n * The Wrapping component for defining fields extensions inside\n *\n * @public\n */\nexport const ScaffolderFieldExtensions: React.ComponentType<\n React.PropsWithChildren<{}>\n> = (): JSX.Element | null => null;\n\nattachComponentData(\n ScaffolderFieldExtensions,\n FIELD_EXTENSION_WRAPPER_KEY,\n true,\n);\n\nexport type {\n CustomFieldExtensionSchema,\n CustomFieldValidator,\n FieldExtensionOptions,\n FieldExtensionComponentProps,\n};\n","/*\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 { useElementFilter } from '@backstage/core-plugin-api';\nimport { FieldExtensionOptions } from '../extensions';\nimport {\n FIELD_EXTENSION_KEY,\n FIELD_EXTENSION_WRAPPER_KEY,\n} from '../extensions/keys';\n\n/**\n * Hook that returns all custom field extensions from the current outlet.\n * @public\n */\nexport const useCustomFieldExtensions = <\n TComponentDataType = FieldExtensionOptions,\n>(\n outlet: React.ReactNode,\n) => {\n return useElementFilter(outlet, elements =>\n elements\n .selectByComponentData({\n key: FIELD_EXTENSION_WRAPPER_KEY,\n })\n .findComponentData<TComponentDataType>({\n key: FIELD_EXTENSION_KEY,\n }),\n );\n};\n","/*\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 */\nexport const LAYOUTS_KEY = 'scaffolder.layout.v1';\nexport const LAYOUTS_WRAPPER_KEY = 'scaffolder.layouts.wrapper.v1';\n","/*\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 { useElementFilter } from '@backstage/core-plugin-api';\nimport { LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from '../layouts/keys';\nimport { LayoutOptions } from '../layouts';\n\n/**\n * Hook that returns all custom field extensions from the current outlet.\n * @public\n */\nexport const useCustomLayouts = <TComponentDataType = LayoutOptions>(\n outlet: React.ReactNode,\n) => {\n return useElementFilter(outlet, elements =>\n elements\n .selectByComponentData({\n key: LAYOUTS_WRAPPER_KEY,\n })\n .findComponentData<TComponentDataType>({\n key: LAYOUTS_KEY,\n }),\n );\n};\n","/*\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 };\n};\n\ntype ReducerAction =\n | { type: 'INIT'; data: ScaffolderTask }\n | { type: 'CANCELLED' }\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 (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 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 '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 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 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 if (!error.message) {\n error.message = `We cannot connect at the moment, trying again in some seconds... Retrying (${retryCount}/3 retries)`;\n }\n\n if (retryCount <= 3) {\n setTimeout(() => {\n retryCount += 1;\n startStreamLogProcess();\n }, 15000);\n }\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 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","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from './keys';\nimport { attachComponentData, Extension } from '@backstage/core-plugin-api';\nimport type { FormProps as SchemaFormProps } from '@rjsf/core-v5';\nimport React from 'react';\n\n/**\n * The field template from `@rjsf/core` which is a react component that gets passed `@rjsf/core` field related props.\n *\n * @public\n */\nexport type LayoutTemplate<T = any> = NonNullable<\n SchemaFormProps<T>['uiSchema']\n>['ui:ObjectFieldTemplate'];\n\n/**\n * The type of layouts that is passed to the TemplateForms\n *\n * @public\n */\nexport interface LayoutOptions<P = any> {\n name: string;\n component: LayoutTemplate<P>;\n}\n\n/**\n * A type used to wrap up the FieldExtension to embed the ReturnValue and the InputProps\n * @public\n */\nexport type LayoutComponent<_TInputProps> = () => null;\n\n/**\n * Method for creating custom Layouts that can be used in the scaffolder frontend form\n *\n * @public\n */\nexport function createScaffolderLayout<TInputProps = unknown>(\n options: LayoutOptions,\n): Extension<LayoutComponent<TInputProps>> {\n return {\n expose() {\n const LayoutDataHolder: any = () => null;\n\n attachComponentData(LayoutDataHolder, LAYOUTS_KEY, options);\n\n return LayoutDataHolder;\n },\n };\n}\n\n/**\n * The wrapping component for defining scaffolder layouts as children\n *\n * @public\n */\nexport const ScaffolderLayouts: React.ComponentType<\n React.PropsWithChildren<{}>\n> = (): JSX.Element | null => null;\n\nattachComponentData(ScaffolderLayouts, LAYOUTS_WRAPPER_KEY, true);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/extensions/index.tsx","../src/hooks/useCustomFieldExtensions.ts","../src/layouts/keys.ts","../src/hooks/useCustomLayouts.ts","../src/hooks/useEventStream.ts","../src/layouts/createScaffolderLayout.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CustomFieldValidator,\n FieldExtensionOptions,\n FieldExtensionComponentProps,\n FieldExtensionUiSchema,\n CustomFieldExtensionSchema,\n} from './types';\nimport { Extension, attachComponentData } from '@backstage/core-plugin-api';\nimport { UIOptionsType } from '@rjsf/utils';\nimport { FIELD_EXTENSION_KEY, FIELD_EXTENSION_WRAPPER_KEY } from './keys';\n\n/**\n * Method for creating field extensions that can be used in the scaffolder\n * frontend form.\n * @public\n */\nexport function createScaffolderFieldExtension<\n TReturnValue = unknown,\n TInputProps extends UIOptionsType = {},\n>(\n options: FieldExtensionOptions<TReturnValue, TInputProps>,\n): Extension<FieldExtensionComponent<TReturnValue, TInputProps>> {\n return {\n expose() {\n const FieldExtensionDataHolder: any = () => null;\n\n attachComponentData(\n FieldExtensionDataHolder,\n FIELD_EXTENSION_KEY,\n options,\n );\n\n return FieldExtensionDataHolder;\n },\n };\n}\n\n/**\n * The Wrapping component for defining fields extensions inside\n *\n * @public\n */\nexport const ScaffolderFieldExtensions: React.ComponentType<\n React.PropsWithChildren<{}>\n> = (): JSX.Element | null => null;\n\nattachComponentData(\n ScaffolderFieldExtensions,\n FIELD_EXTENSION_WRAPPER_KEY,\n true,\n);\n\n/**\n * The type used to wrap up the Layout and embed the input props\n *\n * @public\n */\nexport type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;\n\nexport type {\n CustomFieldValidator,\n FieldExtensionOptions,\n FieldExtensionComponentProps,\n FieldExtensionUiSchema,\n CustomFieldExtensionSchema,\n};\n\nexport * from './rjsf';\n","/*\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 { useElementFilter } from '@backstage/core-plugin-api';\nimport { FieldExtensionOptions } from '../extensions';\nimport {\n FIELD_EXTENSION_KEY,\n FIELD_EXTENSION_WRAPPER_KEY,\n} from '../extensions/keys';\n\n/**\n * Hook that returns all custom field extensions from the current outlet.\n * @public\n */\nexport const useCustomFieldExtensions = <\n TComponentDataType = FieldExtensionOptions,\n>(\n outlet: React.ReactNode,\n) => {\n return useElementFilter(outlet, elements =>\n elements\n .selectByComponentData({\n key: FIELD_EXTENSION_WRAPPER_KEY,\n })\n .findComponentData<TComponentDataType>({\n key: FIELD_EXTENSION_KEY,\n }),\n );\n};\n","/*\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 */\nexport const LAYOUTS_KEY = 'scaffolder.layout.v1';\nexport const LAYOUTS_WRAPPER_KEY = 'scaffolder.layouts.wrapper.v1';\n","/*\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 { useElementFilter } from '@backstage/core-plugin-api';\nimport { LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from '../layouts/keys';\nimport { LayoutOptions } from '../layouts';\n\n/**\n * Hook that returns all custom field extensions from the current outlet.\n * @public\n */\nexport const useCustomLayouts = <TComponentDataType = LayoutOptions>(\n outlet: React.ReactNode,\n) => {\n return useElementFilter(outlet, elements =>\n elements\n .selectByComponentData({\n key: LAYOUTS_WRAPPER_KEY,\n })\n .findComponentData<TComponentDataType>({\n key: LAYOUTS_KEY,\n }),\n );\n};\n","/*\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 };\n};\n\ntype ReducerAction =\n | { type: 'INIT'; data: ScaffolderTask }\n | { type: 'CANCELLED' }\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 (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 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 '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 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 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 if (!error.message) {\n error.message = `We cannot connect at the moment, trying again in some seconds... Retrying (${retryCount}/3 retries)`;\n }\n\n if (retryCount <= 3) {\n setTimeout(() => {\n retryCount += 1;\n startStreamLogProcess();\n }, 15000);\n }\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 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","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from './keys';\nimport { attachComponentData, Extension } from '@backstage/core-plugin-api';\nimport type { FormProps as SchemaFormProps } from '@rjsf/core';\nimport React from 'react';\n\n/**\n * The field template from `@rjsf/core` which is a react component that gets passed `@rjsf/core` field related props.\n *\n * @public\n */\nexport type LayoutTemplate<T = any> = NonNullable<\n SchemaFormProps<T>['uiSchema']\n>['ui:ObjectFieldTemplate'];\n\n/**\n * The type of layouts that is passed to the TemplateForms\n *\n * @public\n */\nexport interface LayoutOptions<P = any> {\n name: string;\n component: LayoutTemplate<P>;\n}\n\n/**\n * A type used to wrap up the FieldExtension to embed the ReturnValue and the InputProps\n * @public\n */\nexport type LayoutComponent<_TInputProps> = () => null;\n\n/**\n * Method for creating custom Layouts that can be used in the scaffolder frontend form\n *\n * @public\n */\nexport function createScaffolderLayout<TInputProps = unknown>(\n options: LayoutOptions,\n): Extension<LayoutComponent<TInputProps>> {\n return {\n expose() {\n const LayoutDataHolder: any = () => null;\n\n attachComponentData(LayoutDataHolder, LAYOUTS_KEY, options);\n\n return LayoutDataHolder;\n },\n };\n}\n\n/**\n * The wrapping component for defining scaffolder layouts as children\n *\n * @public\n */\nexport const ScaffolderLayouts: React.ComponentType<\n React.PropsWithChildren<{}>\n> = (): JSX.Element | null => null;\n\nattachComponentData(ScaffolderLayouts, LAYOUTS_WRAPPER_KEY, true);\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-react",
3
3
  "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder",
4
- "version": "1.5.6",
4
+ "version": "1.6.0-next.1",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -46,22 +46,20 @@
46
46
  "dependencies": {
47
47
  "@backstage/catalog-client": "^1.4.5",
48
48
  "@backstage/catalog-model": "^1.4.3",
49
- "@backstage/core-components": "^0.13.6",
50
- "@backstage/core-plugin-api": "^1.7.0",
49
+ "@backstage/core-components": "^0.13.8-next.1",
50
+ "@backstage/core-plugin-api": "^1.8.0-next.0",
51
51
  "@backstage/errors": "^1.2.3",
52
- "@backstage/plugin-catalog-react": "^1.8.5",
53
- "@backstage/plugin-scaffolder-common": "^1.4.2",
54
- "@backstage/theme": "^0.4.3",
52
+ "@backstage/plugin-catalog-react": "^1.9.0-next.1",
53
+ "@backstage/plugin-scaffolder-common": "^1.4.3-next.1",
54
+ "@backstage/theme": "^0.4.4-next.0",
55
55
  "@backstage/types": "^1.1.1",
56
- "@backstage/version-bridge": "^1.0.6",
56
+ "@backstage/version-bridge": "^1.0.7-next.0",
57
57
  "@material-ui/core": "^4.12.2",
58
58
  "@material-ui/icons": "^4.9.1",
59
59
  "@material-ui/lab": "4.0.0-alpha.61",
60
60
  "@react-hookz/web": "^20.0.0",
61
- "@rjsf/core": "^3.2.1",
62
- "@rjsf/core-v5": "npm:@rjsf/core@5.13.0",
63
- "@rjsf/material-ui": "^3.2.1",
64
- "@rjsf/material-ui-v5": "npm:@rjsf/material-ui@5.13.0",
61
+ "@rjsf/core": "5.13.0",
62
+ "@rjsf/material-ui": "5.13.0",
65
63
  "@rjsf/utils": "5.13.0",
66
64
  "@rjsf/validator-ajv8": "5.13.0",
67
65
  "@types/json-schema": "^7.0.9",
@@ -81,20 +79,19 @@
81
79
  "zod-to-json-schema": "^3.20.4"
82
80
  },
83
81
  "peerDependencies": {
84
- "react": "^16.13.1 || ^17.0.0",
85
- "react-dom": "^16.13.1 || ^17.0.0",
82
+ "react": "^16.13.1 || ^17.0.0 || ^18.0.0",
83
+ "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
86
84
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
87
85
  },
88
86
  "devDependencies": {
89
- "@backstage/cli": "^0.23.0",
90
- "@backstage/core-app-api": "^1.11.0",
91
- "@backstage/plugin-catalog": "^1.14.0",
87
+ "@backstage/cli": "^0.24.0-next.1",
88
+ "@backstage/core-app-api": "^1.11.1-next.0",
89
+ "@backstage/plugin-catalog": "^1.15.0-next.1",
92
90
  "@backstage/plugin-catalog-common": "^1.0.17",
93
- "@backstage/test-utils": "^1.4.4",
91
+ "@backstage/test-utils": "^1.4.5-next.0",
94
92
  "@testing-library/dom": "^9.0.0",
95
93
  "@testing-library/jest-dom": "^6.0.0",
96
- "@testing-library/react": "^12.1.3",
97
- "@testing-library/react-hooks": "^8.0.0",
94
+ "@testing-library/react": "^14.0.0",
98
95
  "@testing-library/user-event": "^14.0.0",
99
96
  "@types/humanize-duration": "^3.18.1",
100
97
  "@types/luxon": "^3.0.0"