@backstage/plugin-scaffolder-react 1.18.1-next.0 → 1.19.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/alpha.d.ts +23 -46
  3. package/dist/api/ref.esm.js.map +1 -1
  4. package/dist/extensions/createScaffolderFieldExtension.esm.js.map +1 -1
  5. package/dist/extensions/keys.esm.js.map +1 -1
  6. package/dist/hooks/useCustomFieldExtensions.esm.js.map +1 -1
  7. package/dist/hooks/useCustomLayouts.esm.js.map +1 -1
  8. package/dist/hooks/useEventStream.esm.js.map +1 -1
  9. package/dist/index.d.ts +67 -201
  10. package/dist/layouts/createScaffolderLayout.esm.js.map +1 -1
  11. package/dist/layouts/keys.esm.js.map +1 -1
  12. package/dist/next/api/FormFieldsApi.esm.js +4 -4
  13. package/dist/next/api/FormFieldsApi.esm.js.map +1 -1
  14. package/dist/next/api/ref.esm.js.map +1 -1
  15. package/dist/next/blueprints/FormDecoratorBlueprint.esm.js.map +1 -1
  16. package/dist/next/blueprints/FormFieldBlueprint.esm.js.map +1 -1
  17. package/dist/next/components/Form/DescriptionFieldTemplate.esm.js.map +1 -1
  18. package/dist/next/components/Form/FieldTemplate.esm.js.map +1 -1
  19. package/dist/next/components/Form/Form.esm.js.map +1 -1
  20. package/dist/next/components/PasswordWidget/PasswordWidget.esm.js.map +1 -1
  21. package/dist/next/components/ReviewState/ReviewState.esm.js +1 -1
  22. package/dist/next/components/ReviewState/ReviewState.esm.js.map +1 -1
  23. package/dist/next/components/ReviewState/util.esm.js.map +1 -1
  24. package/dist/next/components/ScaffolderField/ScaffolderField.esm.js.map +1 -1
  25. package/dist/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.esm.js.map +1 -1
  26. package/dist/next/components/SecretWidget/SecretWidget.esm.js.map +1 -1
  27. package/dist/next/components/Stepper/ErrorListTemplate/errorListTemplate.esm.js.map +1 -1
  28. package/dist/next/components/Stepper/FieldOverrides/DescriptionField.esm.js.map +1 -1
  29. package/dist/next/components/Stepper/Stepper.esm.js.map +1 -1
  30. package/dist/next/components/Stepper/createAsyncValidators.esm.js.map +1 -1
  31. package/dist/next/components/Stepper/utils.esm.js.map +1 -1
  32. package/dist/next/components/TaskLogStream/TaskLogStream.esm.js.map +1 -1
  33. package/dist/next/components/TaskSteps/StepIcon.esm.js.map +1 -1
  34. package/dist/next/components/TaskSteps/StepTime.esm.js.map +1 -1
  35. package/dist/next/components/TaskSteps/TaskBorder.esm.js.map +1 -1
  36. package/dist/next/components/TaskSteps/TaskSteps.esm.js.map +1 -1
  37. package/dist/next/components/TemplateCard/CardHeader.esm.js.map +1 -1
  38. package/dist/next/components/TemplateCard/CardLink.esm.js.map +1 -1
  39. package/dist/next/components/TemplateCard/TemplateCard.esm.js.map +1 -1
  40. package/dist/next/components/TemplateCard/TemplateCardActions.esm.js.map +1 -1
  41. package/dist/next/components/TemplateCard/TemplateCardContent.esm.js.map +1 -1
  42. package/dist/next/components/TemplateCard/TemplateCardLinks.esm.js.map +1 -1
  43. package/dist/next/components/TemplateCard/TemplateCardTags.esm.js.map +1 -1
  44. package/dist/next/components/TemplateCard/TemplateDetailButton.esm.js.map +1 -1
  45. package/dist/next/components/TemplateCategoryPicker/TemplateCategoryPicker.esm.js.map +1 -1
  46. package/dist/next/components/TemplateGroup/TemplateGroup.esm.js.map +1 -1
  47. package/dist/next/components/TemplateGroups/TemplateGroups.esm.js.map +1 -1
  48. package/dist/next/components/TemplateOutputs/DefaultTemplateOutputs.esm.js.map +1 -1
  49. package/dist/next/components/TemplateOutputs/LinkOutputs.esm.js.map +1 -1
  50. package/dist/next/components/TemplateOutputs/TextOutputs.esm.js.map +1 -1
  51. package/dist/next/components/Workflow/Workflow.esm.js +1 -1
  52. package/dist/next/components/Workflow/Workflow.esm.js.map +1 -1
  53. package/dist/next/extensions/createScaffolderFormDecorator.esm.js.map +1 -1
  54. package/dist/next/hooks/useFilteredSchemaProperties.esm.js.map +1 -1
  55. package/dist/next/hooks/useFormDataFromQuery.esm.js.map +1 -1
  56. package/dist/next/hooks/useTemplateParameterSchema.esm.js.map +1 -1
  57. package/dist/next/hooks/useTemplateSchema.esm.js.map +1 -1
  58. package/dist/next/hooks/useTemplateTimeSaved.esm.js.map +1 -1
  59. package/dist/next/hooks/useTransformSchemaToProps.esm.js.map +1 -1
  60. package/dist/next/lib/schema.esm.js.map +1 -1
  61. package/dist/packages/opaque-internal/src/OpaqueType.esm.js.map +1 -1
  62. package/dist/packages/scaffolder-internal/src/wiring/InternalFormDecorator.esm.js.map +1 -1
  63. package/dist/packages/scaffolder-internal/src/wiring/InternalFormField.esm.js.map +1 -1
  64. package/dist/secrets/SecretsContext.esm.js +1 -1
  65. package/dist/secrets/SecretsContext.esm.js.map +1 -1
  66. package/dist/translation.esm.js.map +1 -1
  67. package/dist/utils.esm.js.map +1 -1
  68. package/package.json +18 -18
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # @backstage/plugin-scaffolder-react
2
2
 
3
+ ## 1.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4f99e10: **DEPRECATION**: The following types have been deprecated from this package and moved into `@backstage/plugin-scaffolder-common` and should be imported from there instead.
8
+
9
+ `Action`, `ListActionsResponse`, `LogEvent`, `ScaffolderApi`, `ScaffolderDryRunOptions`, `ScaffolderDryRunResponse`, `ScaffolderGetIntegrationsListOptions`, `ScaffolderGetIntegrationsListResponse`,
10
+ `ScaffolderOutputLink`, `ScaffolderOutputText`, `ScaffolderScaffoldOptions`, `ScaffolderScaffoldResponse`, `ScaffolderStreamLogsOptions`, `ScaffolderTask`, `ScaffolderTaskOutput`, `ScaffolderTaskStatus`,
11
+ `ScaffolderUsageExample`, `TemplateFilter`, `TemplateGlobalFunction`, `TemplateGlobalValue`, `TemplateParameterSchema`.
12
+
13
+ - c08cbc4: Move Scaffolder API to OpenAPI
14
+
15
+ ### Patch Changes
16
+
17
+ - f2f133c: Internal update to use the new variant of `ApiBlueprint`.
18
+ - c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor.
19
+ - Updated dependencies
20
+ - @backstage/core-components@0.17.5
21
+ - @backstage/frontend-plugin-api@0.11.0
22
+ - @backstage/plugin-scaffolder-common@1.7.0
23
+ - @backstage/plugin-catalog-react@1.20.0
24
+ - @backstage/theme@0.6.8
25
+ - @backstage/catalog-client@1.11.0
26
+
27
+ ## 1.19.0-next.1
28
+
29
+ ### Minor Changes
30
+
31
+ - 4f99e10: **DEPRECATION**: The following types have been deprecated from this package and moved into `@backstage/plugin-scaffolder-common` and should be imported from there instead.
32
+
33
+ `Action`, `ListActionsResponse`, `LogEvent`, `ScaffolderApi`, `ScaffolderDryRunOptions`, `ScaffolderDryRunResponse`, `ScaffolderGetIntegrationsListOptions`, `ScaffolderGetIntegrationsListResponse`,
34
+ `ScaffolderOutputLink`, `ScaffolderOutputText`, `ScaffolderScaffoldOptions`, `ScaffolderScaffoldResponse`, `ScaffolderStreamLogsOptions`, `ScaffolderTask`, `ScaffolderTaskOutput`, `ScaffolderTaskStatus`,
35
+ `ScaffolderUsageExample`, `TemplateFilter`, `TemplateGlobalFunction`, `TemplateGlobalValue`, `TemplateParameterSchema`.
36
+
37
+ - c08cbc4: Move Scaffolder API to OpenAPI
38
+
39
+ ### Patch Changes
40
+
41
+ - f2f133c: Internal update to use the new variant of `ApiBlueprint`.
42
+ - c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor.
43
+ - Updated dependencies
44
+ - @backstage/plugin-scaffolder-common@1.7.0-next.0
45
+ - @backstage/plugin-catalog-react@1.20.0-next.1
46
+ - @backstage/frontend-plugin-api@0.11.0-next.0
47
+ - @backstage/theme@0.6.8-next.0
48
+ - @backstage/catalog-client@1.11.0-next.0
49
+ - @backstage/core-components@0.17.5-next.0
50
+ - @backstage/catalog-model@1.7.5
51
+ - @backstage/core-plugin-api@1.10.9
52
+ - @backstage/types@1.2.1
53
+ - @backstage/version-bridge@1.0.11
54
+ - @backstage/plugin-permission-react@0.4.36
55
+
3
56
  ## 1.18.1-next.0
4
57
 
5
58
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -12,47 +12,6 @@ import { Overrides } from '@material-ui/core/styles/overrides';
12
12
  import { StyleRules } from '@material-ui/core/styles/withStyles';
13
13
  import * as _backstage_core_plugin_api_alpha from '@backstage/core-plugin-api/alpha';
14
14
 
15
- /*
16
- * Copyright 2024 The Backstage Authors
17
- *
18
- * Licensed under the Apache License, Version 2.0 (the "License");
19
- * you may not use this file except in compliance with the License.
20
- * You may obtain a copy of the License at
21
- *
22
- * http://www.apache.org/licenses/LICENSE-2.0
23
- *
24
- * Unless required by applicable law or agreed to in writing, software
25
- * distributed under the License is distributed on an "AS IS" BASIS,
26
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27
- * See the License for the specific language governing permissions and
28
- * limitations under the License.
29
- */
30
-
31
-
32
-
33
- /** @alpha */
34
- interface FormField {
35
- readonly $$type: '@backstage/scaffolder/FormField';
36
- }
37
-
38
- /** @alpha */
39
- declare const formFieldsApi: _backstage_frontend_plugin_api.ExtensionDefinition<{
40
- config: {};
41
- configInput: {};
42
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
43
- inputs: {
44
- formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>, {
45
- singleton: false;
46
- optional: false;
47
- }>;
48
- };
49
- kind: "api";
50
- name: "form-fields";
51
- params: {
52
- factory: _backstage_frontend_plugin_api.AnyApiFactory;
53
- };
54
- }>;
55
-
56
15
  /** @alpha */
57
16
  type ScaffolderFormDecoratorContext<TInput extends JsonObject = JsonObject> = {
58
17
  input: TInput;
@@ -100,11 +59,10 @@ declare function createScaffolderFormDecorator<TInputSchema extends {
100
59
  * */
101
60
  declare const FormDecoratorBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
102
61
  kind: "scaffolder-form-decorator";
103
- name: undefined;
104
62
  params: {
105
63
  decorator: ScaffolderFormDecorator;
106
64
  };
107
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<ScaffolderFormDecorator, "scaffolder.form-decorator-loader", {}>;
65
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<ScaffolderFormDecorator, "scaffolder.form-decorator-loader", {}>;
108
66
  inputs: {};
109
67
  config: {};
110
68
  configInput: {};
@@ -127,11 +85,10 @@ type FormFieldExtensionData<TReturnValue extends z.ZodType = z.ZodType, TUiOptio
127
85
  * */
128
86
  declare const FormFieldBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
129
87
  kind: "scaffolder-form-field";
130
- name: undefined;
131
88
  params: {
132
89
  field: () => Promise<FormField>;
133
90
  };
134
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>;
91
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>;
135
92
  inputs: {};
136
93
  config: {};
137
94
  configInput: {};
@@ -152,6 +109,26 @@ declare function createFormField<TReturnValue extends z.ZodType, TUiOptions exte
152
109
  interface ScaffolderFormFieldsApi {
153
110
  getFormFields(): Promise<FormFieldExtensionData[]>;
154
111
  }
112
+ /** @alpha */
113
+ interface FormField {
114
+ readonly $$type: '@backstage/scaffolder/FormField';
115
+ }
116
+
117
+ /** @alpha */
118
+ declare const formFieldsApi: _backstage_frontend_plugin_api.ExtensionDefinition<{
119
+ config: {};
120
+ configInput: {};
121
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
122
+ inputs: {
123
+ formFields: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<FormField>, "scaffolder.form-field-loader", {}>, {
124
+ singleton: false;
125
+ optional: false;
126
+ }>;
127
+ };
128
+ kind: "api";
129
+ name: "form-fields";
130
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
131
+ }>;
155
132
 
156
133
  /**
157
134
  * @alpha
@@ -490,4 +467,4 @@ declare const scaffolderReactTranslationRef: _backstage_core_plugin_api_alpha.Tr
490
467
  readonly "templateOutputs.title": "Text Output";
491
468
  }>;
492
469
 
493
- export { type BackstageOverrides, type BackstageTemplateStepperClassKey, DefaultTemplateOutputs, EmbeddableWorkflow, Form, FormDecoratorBlueprint, FormFieldBlueprint, type FormFieldExtensionData, type FormValidation, type ParsedTemplateSchema, ReviewState, type ReviewStateProps, ScaffolderField, type ScaffolderFieldProps, type ScaffolderFormDecorator, type ScaffolderFormDecoratorContext, type ScaffolderFormFieldsApi, 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, createScaffolderFormDecorator, extractSchemaFromStep, formFieldsApi, formFieldsApiRef, scaffolderReactTranslationRef, useFilteredSchemaProperties, useFormDataFromQuery, useTemplateParameterSchema, useTemplateSchema };
470
+ export { type BackstageOverrides, type BackstageTemplateStepperClassKey, DefaultTemplateOutputs, EmbeddableWorkflow, Form, FormDecoratorBlueprint, type FormField, FormFieldBlueprint, type FormFieldExtensionData, type FormValidation, type ParsedTemplateSchema, ReviewState, type ReviewStateProps, ScaffolderField, type ScaffolderFieldProps, type ScaffolderFormDecorator, type ScaffolderFormDecoratorContext, type ScaffolderFormFieldsApi, 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, createScaffolderFormDecorator, extractSchemaFromStep, formFieldsApi, formFieldsApiRef, scaffolderReactTranslationRef, useFilteredSchemaProperties, useFormDataFromQuery, useTemplateParameterSchema, useTemplateSchema };
@@ -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/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;AACN,CAAC;;;;"}
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,YAAA,CAA4B;AAAA,EAC1D,EAAA,EAAI;AACN,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createScaffolderFieldExtension.esm.js","sources":["../../src/extensions/createScaffolderFieldExtension.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\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"],"names":[],"mappings":";;;AAgCO,SAAS,+BAId,OAC+D,EAAA;AAC/D,EAAO,OAAA;AAAA,IACL,MAAS,GAAA;AACP,MAAA,MAAM,2BAAgC,MAAM,IAAA;AAE5C,MAAA,mBAAA;AAAA,QACE,wBAAA;AAAA,QACA,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAO,OAAA,wBAAA;AAAA;AACT,GACF;AACF;AAOO,MAAM,4BAET,MAA0B;AAE9B,mBAAA;AAAA,EACE,yBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"createScaffolderFieldExtension.esm.js","sources":["../../src/extensions/createScaffolderFieldExtension.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\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"],"names":[],"mappings":";;;AAgCO,SAAS,+BAId,OAAA,EAC+D;AAC/D,EAAA,OAAO;AAAA,IACL,MAAA,GAAS;AACP,MAAA,MAAM,2BAAgC,MAAM,IAAA;AAE5C,MAAA,mBAAA;AAAA,QACE,wBAAA;AAAA,QACA,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,OAAO,wBAAA;AAAA,IACT;AAAA,GACF;AACF;AAOO,MAAM,4BAET,MAA0B;AAE9B,mBAAA;AAAA,EACE,yBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"keys.esm.js","sources":["../../src/extensions/keys.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1';\n/**\n * The key used to store the field extension data for any `<FieldExtension />` component\n */\nexport const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1';\n"],"names":[],"mappings":"AAgBO,MAAM,2BAA8B,GAAA;AAIpC,MAAM,mBAAsB,GAAA;;;;"}
1
+ {"version":3,"file":"keys.esm.js","sources":["../../src/extensions/keys.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1';\n/**\n * The key used to store the field extension data for any `<FieldExtension />` component\n */\nexport const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1';\n"],"names":[],"mappings":"AAgBO,MAAM,2BAAA,GAA8B;AAIpC,MAAM,mBAAA,GAAsB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCustomFieldExtensions.esm.js","sources":["../../src/hooks/useCustomFieldExtensions.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useAsync, useMountEffect } from '@react-hookz/web';\nimport { useApi, useElementFilter } from '@backstage/core-plugin-api';\nimport { formFieldsApiRef } from '../next';\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 // todo(blam): this shouldn't be here, should remove this, but this is a breaking change to remove the generic.\n TComponentDataType = FieldExtensionOptions,\n>(\n outlet: React.ReactNode,\n) => {\n // Get custom fields created with FormFieldBlueprint\n const formFieldsApi = useApi(formFieldsApiRef);\n const [{ result: blueprintFields }, { execute }] = useAsync(\n () => formFieldsApi.getFormFields(),\n [],\n );\n useMountEffect(execute);\n\n // Get custom fields created with ScaffolderFieldExtensions\n const outletFields = 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 // This should really be a different type moving forward, but we do this to keep type compatibility.\n // should probably also move the defaults into the API eventually too, but that will come with the move\n // to the new frontend system.\n const blueprintsToLegacy: FieldExtensionOptions[] = blueprintFields?.map(\n field => ({\n component: field.component,\n name: field.name,\n validation: field.validation,\n schema: field.schema?.schema,\n }),\n );\n\n return [...blueprintsToLegacy, ...outletFields] as TComponentDataType[];\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4Ba,MAAA,wBAAA,GAA2B,CAItC,MACG,KAAA;AAEH,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAM,MAAA,CAAC,EAAE,MAAQ,EAAA,eAAA,IAAmB,EAAE,OAAA,EAAS,CAAI,GAAA,QAAA;AAAA,IACjD,MAAM,cAAc,aAAc,EAAA;AAAA,IAClC;AAAC,GACH;AACA,EAAA,cAAA,CAAe,OAAO,CAAA;AAGtB,EAAA,MAAM,YAAe,GAAA,gBAAA;AAAA,IAAiB,MAAA;AAAA,IAAQ,CAAA,QAAA,KAC5C,SACG,qBAAsB,CAAA;AAAA,MACrB,GAAK,EAAA;AAAA,KACN,EACA,iBAAsC,CAAA;AAAA,MACrC,GAAK,EAAA;AAAA,KACN;AAAA,GACL;AAKA,EAAA,MAAM,qBAA8C,eAAiB,EAAA,GAAA;AAAA,IACnE,CAAU,KAAA,MAAA;AAAA,MACR,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,MAAM,KAAM,CAAA,IAAA;AAAA,MACZ,YAAY,KAAM,CAAA,UAAA;AAAA,MAClB,MAAA,EAAQ,MAAM,MAAQ,EAAA;AAAA,KACxB;AAAA,GACF;AAEA,EAAA,OAAO,CAAC,GAAG,kBAAoB,EAAA,GAAG,YAAY,CAAA;AAChD;;;;"}
1
+ {"version":3,"file":"useCustomFieldExtensions.esm.js","sources":["../../src/hooks/useCustomFieldExtensions.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useAsync, useMountEffect } from '@react-hookz/web';\nimport { useApi, useElementFilter } from '@backstage/core-plugin-api';\nimport { formFieldsApiRef } from '../next';\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 // todo(blam): this shouldn't be here, should remove this, but this is a breaking change to remove the generic.\n TComponentDataType = FieldExtensionOptions,\n>(\n outlet: React.ReactNode,\n) => {\n // Get custom fields created with FormFieldBlueprint\n const formFieldsApi = useApi(formFieldsApiRef);\n const [{ result: blueprintFields }, { execute }] = useAsync(\n () => formFieldsApi.getFormFields(),\n [],\n );\n useMountEffect(execute);\n\n // Get custom fields created with ScaffolderFieldExtensions\n const outletFields = 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 // This should really be a different type moving forward, but we do this to keep type compatibility.\n // should probably also move the defaults into the API eventually too, but that will come with the move\n // to the new frontend system.\n const blueprintsToLegacy: FieldExtensionOptions[] = blueprintFields?.map(\n field => ({\n component: field.component,\n name: field.name,\n validation: field.validation,\n schema: field.schema?.schema,\n }),\n );\n\n return [...blueprintsToLegacy, ...outletFields] as TComponentDataType[];\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BO,MAAM,wBAAA,GAA2B,CAItC,MAAA,KACG;AAEH,EAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAA,MAAM,CAAC,EAAE,MAAA,EAAQ,eAAA,IAAmB,EAAE,OAAA,EAAS,CAAA,GAAI,QAAA;AAAA,IACjD,MAAM,cAAc,aAAA,EAAc;AAAA,IAClC;AAAC,GACH;AACA,EAAA,cAAA,CAAe,OAAO,CAAA;AAGtB,EAAA,MAAM,YAAA,GAAe,gBAAA;AAAA,IAAiB,MAAA;AAAA,IAAQ,CAAA,QAAA,KAC5C,SACG,qBAAA,CAAsB;AAAA,MACrB,GAAA,EAAK;AAAA,KACN,EACA,iBAAA,CAAsC;AAAA,MACrC,GAAA,EAAK;AAAA,KACN;AAAA,GACL;AAKA,EAAA,MAAM,qBAA8C,eAAA,EAAiB,GAAA;AAAA,IACnE,CAAA,KAAA,MAAU;AAAA,MACR,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,MAAA,EAAQ,MAAM,MAAA,EAAQ;AAAA,KACxB;AAAA,GACF;AAEA,EAAA,OAAO,CAAC,GAAG,kBAAA,EAAoB,GAAG,YAAY,CAAA;AAChD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCustomLayouts.esm.js","sources":["../../src/hooks/useCustomLayouts.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { 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"],"names":[],"mappings":";;;AAuBa,MAAA,gBAAA,GAAmB,CAC9B,MACG,KAAA;AACH,EAAO,OAAA,gBAAA;AAAA,IAAiB,MAAA;AAAA,IAAQ,CAAA,QAAA,KAC9B,SACG,qBAAsB,CAAA;AAAA,MACrB,GAAK,EAAA;AAAA,KACN,EACA,iBAAsC,CAAA;AAAA,MACrC,GAAK,EAAA;AAAA,KACN;AAAA,GACL;AACF;;;;"}
1
+ {"version":3,"file":"useCustomLayouts.esm.js","sources":["../../src/hooks/useCustomLayouts.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { 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"],"names":[],"mappings":";;;AAuBO,MAAM,gBAAA,GAAmB,CAC9B,MAAA,KACG;AACH,EAAA,OAAO,gBAAA;AAAA,IAAiB,MAAA;AAAA,IAAQ,CAAA,QAAA,KAC9B,SACG,qBAAA,CAAsB;AAAA,MACrB,GAAA,EAAK;AAAA,KACN,EACA,iBAAA,CAAsC;AAAA,MACrC,GAAA,EAAK;AAAA,KACN;AAAA,GACL;AACF;;;;"}
@@ -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 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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"}
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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"}