@tduniec/plugin-template-designer 0.1.7

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 (69) hide show
  1. package/README.md +120 -0
  2. package/dist/api/scaffolderActions.esm.js +42 -0
  3. package/dist/api/scaffolderActions.esm.js.map +1 -0
  4. package/dist/components/DesignerFlow/DesignerFlow.esm.js +370 -0
  5. package/dist/components/DesignerFlow/DesignerFlow.esm.js.map +1 -0
  6. package/dist/components/DesignerFlow/flowConfig.esm.js +21 -0
  7. package/dist/components/DesignerFlow/flowConfig.esm.js.map +1 -0
  8. package/dist/components/DesignerFlow/handlers.esm.js +288 -0
  9. package/dist/components/DesignerFlow/handlers.esm.js.map +1 -0
  10. package/dist/components/DesignerFlow/model.esm.js +181 -0
  11. package/dist/components/DesignerFlow/model.esm.js.map +1 -0
  12. package/dist/components/DesignerFlow/nodeLayout.esm.js +138 -0
  13. package/dist/components/DesignerFlow/nodeLayout.esm.js.map +1 -0
  14. package/dist/components/DesignerFlow/parameterTransforms.esm.js +184 -0
  15. package/dist/components/DesignerFlow/parameterTransforms.esm.js.map +1 -0
  16. package/dist/components/Nodes/ActionNode.esm.js +437 -0
  17. package/dist/components/Nodes/ActionNode.esm.js.map +1 -0
  18. package/dist/components/Nodes/OutputNode.esm.js +368 -0
  19. package/dist/components/Nodes/OutputNode.esm.js.map +1 -0
  20. package/dist/components/Nodes/ParameterInputNode.esm.js +310 -0
  21. package/dist/components/Nodes/ParameterInputNode.esm.js.map +1 -0
  22. package/dist/components/Nodes/ParameterTitlesNode.esm.js +251 -0
  23. package/dist/components/Nodes/ParameterTitlesNode.esm.js.map +1 -0
  24. package/dist/components/Nodes/ParametersNode.esm.js +142 -0
  25. package/dist/components/Nodes/ParametersNode.esm.js.map +1 -0
  26. package/dist/components/Nodes/action/schema.esm.js +117 -0
  27. package/dist/components/Nodes/action/schema.esm.js.map +1 -0
  28. package/dist/components/Nodes/action/useActionInputs.esm.js +66 -0
  29. package/dist/components/Nodes/action/useActionInputs.esm.js.map +1 -0
  30. package/dist/components/Nodes/common/AutoWidthPopper.esm.js +22 -0
  31. package/dist/components/Nodes/common/AutoWidthPopper.esm.js.map +1 -0
  32. package/dist/components/Nodes/common/nodeInteraction.esm.js +9 -0
  33. package/dist/components/Nodes/common/nodeInteraction.esm.js.map +1 -0
  34. package/dist/components/Nodes/output/useOutputController.esm.js +191 -0
  35. package/dist/components/Nodes/output/useOutputController.esm.js.map +1 -0
  36. package/dist/components/Nodes/parameters/useParameterSections.esm.js +162 -0
  37. package/dist/components/Nodes/parameters/useParameterSections.esm.js.map +1 -0
  38. package/dist/components/Nodes/types.esm.js +8 -0
  39. package/dist/components/Nodes/types.esm.js.map +1 -0
  40. package/dist/components/TemplateDesigner/TemplateDesigner.esm.js +115 -0
  41. package/dist/components/TemplateDesigner/TemplateDesigner.esm.js.map +1 -0
  42. package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js +32 -0
  43. package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js.map +1 -0
  44. package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js +102 -0
  45. package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js.map +1 -0
  46. package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js +200 -0
  47. package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js.map +1 -0
  48. package/dist/components/TemplateDesigner/index.esm.js +2 -0
  49. package/dist/components/TemplateDesigner/index.esm.js.map +1 -0
  50. package/dist/components/TemplateDesigner/useFieldEditor.esm.js +96 -0
  51. package/dist/components/TemplateDesigner/useFieldEditor.esm.js.map +1 -0
  52. package/dist/components/TemplateDesigner/useTemplateState.esm.js +391 -0
  53. package/dist/components/TemplateDesigner/useTemplateState.esm.js.map +1 -0
  54. package/dist/components/TemplateDesigner/utils.esm.js +46 -0
  55. package/dist/components/TemplateDesigner/utils.esm.js.map +1 -0
  56. package/dist/index.d.ts +9 -0
  57. package/dist/index.esm.js +2 -0
  58. package/dist/index.esm.js.map +1 -0
  59. package/dist/plugin.esm.js +19 -0
  60. package/dist/plugin.esm.js.map +1 -0
  61. package/dist/routes.esm.js +8 -0
  62. package/dist/routes.esm.js.map +1 -0
  63. package/dist/utils/createSequentialEdges.esm.js +15 -0
  64. package/dist/utils/createSequentialEdges.esm.js.map +1 -0
  65. package/dist/utils/sampleTemplate.esm.js +40 -0
  66. package/dist/utils/sampleTemplate.esm.js.map +1 -0
  67. package/dist/utils/yamlJsonConversion.esm.js +47 -0
  68. package/dist/utils/yamlJsonConversion.esm.js.map +1 -0
  69. package/package.json +116 -0
@@ -0,0 +1,391 @@
1
+ import { useState, useRef, useCallback, useMemo } from 'react';
2
+ import { convertJsonToYaml, convertYamlToJson } from '../../utils/yamlJsonConversion.esm.js';
3
+ import { SAMPLE_TEMPLATE_BLUEPRINT } from '../../utils/sampleTemplate.esm.js';
4
+ import { cloneDeep, FILE_PICKER_TYPES, asRecord, isTaskStep, cloneSteps, downloadString, DEFAULT_FILE_NAME } from './utils.esm.js';
5
+
6
+ const parseTemplateYaml = (value) => {
7
+ const parsed = JSON.parse(convertYamlToJson(value));
8
+ if (!parsed || typeof parsed !== "object") {
9
+ throw new Error("Template YAML must describe an object");
10
+ }
11
+ return parsed;
12
+ };
13
+ const useTemplateState = () => {
14
+ const [templateObject, setTemplateObject] = useState(null);
15
+ const [templateYaml, setTemplateYaml] = useState("");
16
+ const [yamlError, setYamlError] = useState();
17
+ const [loadError, setLoadError] = useState();
18
+ const [isDirty, setIsDirty] = useState(false);
19
+ const [templateSource, setTemplateSource] = useState();
20
+ const [isReloading, setIsReloading] = useState(false);
21
+ const [isSaving, setIsSaving] = useState(false);
22
+ const fileInputRef = useRef(null);
23
+ const ensureHandlePermission = useCallback(
24
+ async (handle, mode) => {
25
+ if (!handle || !handle.queryPermission || !handle.requestPermission) {
26
+ return true;
27
+ }
28
+ const options = { mode };
29
+ const current = await handle.queryPermission(options);
30
+ if (current === "granted") {
31
+ return true;
32
+ }
33
+ const request = await handle.requestPermission(options);
34
+ return request === "granted";
35
+ },
36
+ []
37
+ );
38
+ const applyTemplate = useCallback(
39
+ (template, source) => {
40
+ const nextTemplate = cloneDeep(template);
41
+ const nextYaml = convertJsonToYaml(nextTemplate);
42
+ setTemplateObject(nextTemplate);
43
+ setTemplateYaml(nextYaml);
44
+ setYamlError(void 0);
45
+ setLoadError(void 0);
46
+ setTemplateSource(source);
47
+ setIsDirty(false);
48
+ },
49
+ []
50
+ );
51
+ const confirmDiscardChanges = useCallback(() => {
52
+ if (!templateObject || !isDirty) {
53
+ return true;
54
+ }
55
+ if (typeof window === "undefined") {
56
+ return true;
57
+ }
58
+ return window.confirm(
59
+ "This will discard the changes you have made. Continue?"
60
+ );
61
+ }, [isDirty, templateObject]);
62
+ const handleStartSampleTemplate = useCallback(() => {
63
+ if (!confirmDiscardChanges()) {
64
+ return;
65
+ }
66
+ applyTemplate(SAMPLE_TEMPLATE_BLUEPRINT, {
67
+ type: "sample",
68
+ label: "Sample template"
69
+ });
70
+ }, [applyTemplate, confirmDiscardChanges]);
71
+ const handleTemplateFileSelected = useCallback(
72
+ async (event) => {
73
+ const file = event.target.files?.[0];
74
+ event.target.value = "";
75
+ if (!file) {
76
+ return;
77
+ }
78
+ if (!confirmDiscardChanges()) {
79
+ return;
80
+ }
81
+ try {
82
+ const fileContents = await file.text();
83
+ const parsed = parseTemplateYaml(fileContents);
84
+ applyTemplate(parsed, {
85
+ type: "file",
86
+ label: file.name
87
+ });
88
+ } catch (error) {
89
+ const message = error instanceof Error ? error.message : "Unknown error loading template";
90
+ setLoadError(`Could not load template: ${message}`);
91
+ }
92
+ },
93
+ [applyTemplate, confirmDiscardChanges]
94
+ );
95
+ const handleOpenTemplatePicker = useCallback(async () => {
96
+ if (!confirmDiscardChanges()) {
97
+ return;
98
+ }
99
+ if (typeof window === "undefined") {
100
+ return;
101
+ }
102
+ const fsWindow = window;
103
+ if (fsWindow.showOpenFilePicker) {
104
+ try {
105
+ const handles = await fsWindow.showOpenFilePicker({
106
+ multiple: false,
107
+ types: FILE_PICKER_TYPES
108
+ });
109
+ const [handle] = handles ?? [];
110
+ if (!handle) {
111
+ return;
112
+ }
113
+ const granted = await ensureHandlePermission(handle, "read");
114
+ if (!granted) {
115
+ setLoadError("Permission to read the selected file was denied.");
116
+ return;
117
+ }
118
+ const file = await handle.getFile();
119
+ const text = await file.text();
120
+ const parsed = parseTemplateYaml(text);
121
+ applyTemplate(parsed, {
122
+ type: "file",
123
+ label: handle.name ?? file.name,
124
+ handle
125
+ });
126
+ } catch (error) {
127
+ if (error instanceof DOMException && error.name === "AbortError") {
128
+ return;
129
+ }
130
+ const message = error instanceof Error ? error.message : "Unknown error loading template";
131
+ setLoadError(`Could not load template: ${message}`);
132
+ }
133
+ return;
134
+ }
135
+ fileInputRef.current?.click();
136
+ }, [applyTemplate, confirmDiscardChanges, ensureHandlePermission]);
137
+ const templateSteps = useMemo(() => {
138
+ if (!templateObject) {
139
+ return [];
140
+ }
141
+ const template = asRecord(templateObject);
142
+ if (!template) {
143
+ return [];
144
+ }
145
+ const spec = asRecord(template.spec);
146
+ if (!spec) {
147
+ return [];
148
+ }
149
+ const maybeSteps = spec.steps;
150
+ if (!Array.isArray(maybeSteps)) {
151
+ return [];
152
+ }
153
+ const validSteps = maybeSteps.filter(isTaskStep);
154
+ return cloneSteps(validSteps);
155
+ }, [templateObject]);
156
+ const templateParameters = useMemo(() => {
157
+ if (!templateObject) {
158
+ return void 0;
159
+ }
160
+ const template = asRecord(templateObject);
161
+ if (!template) {
162
+ return void 0;
163
+ }
164
+ const spec = asRecord(template.spec);
165
+ if (!spec) {
166
+ return void 0;
167
+ }
168
+ if (!Object.prototype.hasOwnProperty.call(spec, "parameters")) {
169
+ return void 0;
170
+ }
171
+ const rawParameters = spec.parameters;
172
+ if (rawParameters === void 0) {
173
+ return void 0;
174
+ }
175
+ return cloneDeep(rawParameters);
176
+ }, [templateObject]);
177
+ const templateOutput = useMemo(() => {
178
+ if (!templateObject) {
179
+ return void 0;
180
+ }
181
+ const template = asRecord(templateObject);
182
+ if (!template) {
183
+ return void 0;
184
+ }
185
+ const spec = asRecord(template.spec);
186
+ if (!spec) {
187
+ return void 0;
188
+ }
189
+ const rawOutput = spec.output;
190
+ if (!rawOutput || typeof rawOutput !== "object") {
191
+ return void 0;
192
+ }
193
+ return cloneDeep(rawOutput);
194
+ }, [templateObject]);
195
+ const handleYamlChange = useCallback((value) => {
196
+ setTemplateYaml(value);
197
+ setIsDirty(true);
198
+ try {
199
+ const parsed = parseTemplateYaml(value);
200
+ setTemplateObject(parsed);
201
+ setYamlError(void 0);
202
+ } catch (error) {
203
+ const message = error instanceof Error ? error.message : "Unknown error parsing YAML";
204
+ setYamlError(message);
205
+ }
206
+ }, []);
207
+ const handleStepsChange = useCallback((steps) => {
208
+ setIsDirty(true);
209
+ setTemplateObject((prevTemplate) => {
210
+ const base = prevTemplate && typeof prevTemplate === "object" ? cloneDeep(prevTemplate) : {};
211
+ const spec = asRecord(base.spec) ?? {};
212
+ const nextSteps = cloneSteps(steps);
213
+ const nextTemplate = {
214
+ ...base,
215
+ spec: {
216
+ ...spec,
217
+ steps: nextSteps
218
+ }
219
+ };
220
+ setTemplateYaml(convertJsonToYaml(nextTemplate));
221
+ return nextTemplate;
222
+ });
223
+ }, []);
224
+ const handleParametersChange = useCallback(
225
+ (parameters) => {
226
+ setIsDirty(true);
227
+ setTemplateObject((prevTemplate) => {
228
+ const base = prevTemplate && typeof prevTemplate === "object" ? cloneDeep(prevTemplate) : {};
229
+ const spec = asRecord(base.spec) ?? {};
230
+ const nextTemplate = {
231
+ ...base,
232
+ spec: {
233
+ ...spec,
234
+ parameters: cloneDeep(parameters)
235
+ }
236
+ };
237
+ setTemplateYaml(convertJsonToYaml(nextTemplate));
238
+ return nextTemplate;
239
+ });
240
+ },
241
+ []
242
+ );
243
+ const handleOutputChange = useCallback((output) => {
244
+ setIsDirty(true);
245
+ setTemplateObject((prevTemplate) => {
246
+ const base = prevTemplate && typeof prevTemplate === "object" ? cloneDeep(prevTemplate) : {};
247
+ const spec = asRecord(base.spec) ?? {};
248
+ const nextTemplate = {
249
+ ...base,
250
+ spec: {
251
+ ...spec,
252
+ output: cloneDeep(output)
253
+ }
254
+ };
255
+ setTemplateYaml(convertJsonToYaml(nextTemplate));
256
+ return nextTemplate;
257
+ });
258
+ }, []);
259
+ const handleReloadFromFile = useCallback(async () => {
260
+ if (!templateSource) {
261
+ return;
262
+ }
263
+ if (templateSource.type !== "file") {
264
+ handleStartSampleTemplate();
265
+ return;
266
+ }
267
+ if (!templateSource.handle) {
268
+ handleOpenTemplatePicker();
269
+ return;
270
+ }
271
+ if (!confirmDiscardChanges()) {
272
+ return;
273
+ }
274
+ try {
275
+ setIsReloading(true);
276
+ const granted = await ensureHandlePermission(
277
+ templateSource.handle,
278
+ "read"
279
+ );
280
+ if (!granted) {
281
+ setLoadError("Permission to read the selected file was denied.");
282
+ return;
283
+ }
284
+ const file = await templateSource.handle.getFile();
285
+ const text = await file.text();
286
+ const parsed = parseTemplateYaml(text);
287
+ applyTemplate(parsed, {
288
+ type: "file",
289
+ label: templateSource.handle.name ?? file.name ?? templateSource.label,
290
+ handle: templateSource.handle
291
+ });
292
+ } catch (error) {
293
+ const message = error instanceof Error ? error.message : "Unknown error reloading template";
294
+ setLoadError(`Could not reload template: ${message}`);
295
+ } finally {
296
+ setIsReloading(false);
297
+ }
298
+ }, [
299
+ applyTemplate,
300
+ confirmDiscardChanges,
301
+ ensureHandlePermission,
302
+ handleOpenTemplatePicker,
303
+ handleStartSampleTemplate,
304
+ templateSource
305
+ ]);
306
+ const handleSaveTemplate = useCallback(async () => {
307
+ if (!templateObject) {
308
+ return;
309
+ }
310
+ if (typeof window === "undefined") {
311
+ downloadString(templateYaml, DEFAULT_FILE_NAME);
312
+ setIsDirty(false);
313
+ return;
314
+ }
315
+ try {
316
+ setIsSaving(true);
317
+ setLoadError(void 0);
318
+ const fsWindow = window;
319
+ if (templateSource?.type === "file" && templateSource.handle) {
320
+ const granted = await ensureHandlePermission(
321
+ templateSource.handle,
322
+ "readwrite"
323
+ );
324
+ if (!granted) {
325
+ setLoadError("Permission to save to the selected file was denied.");
326
+ return;
327
+ }
328
+ const writable = await templateSource.handle.createWritable?.();
329
+ if (!writable) {
330
+ throw new Error("Unable to open file for writing.");
331
+ }
332
+ await writable.write(templateYaml);
333
+ await writable.close();
334
+ setIsDirty(false);
335
+ return;
336
+ }
337
+ if (fsWindow.showSaveFilePicker) {
338
+ const handle = await fsWindow.showSaveFilePicker({
339
+ suggestedName: templateSource?.label ?? DEFAULT_FILE_NAME,
340
+ types: FILE_PICKER_TYPES
341
+ });
342
+ const writable = await handle.createWritable?.();
343
+ if (!writable) {
344
+ throw new Error("Unable to open file for writing.");
345
+ }
346
+ await writable.write(templateYaml);
347
+ await writable.close();
348
+ setTemplateSource({
349
+ type: "file",
350
+ label: handle.name ?? templateSource?.label ?? DEFAULT_FILE_NAME,
351
+ handle
352
+ });
353
+ setIsDirty(false);
354
+ return;
355
+ }
356
+ downloadString(templateYaml, templateSource?.label ?? DEFAULT_FILE_NAME);
357
+ setIsDirty(false);
358
+ } catch (error) {
359
+ const message = error instanceof Error ? error.message : "Unknown error saving template";
360
+ setLoadError(`Failed to save template: ${message}`);
361
+ } finally {
362
+ setIsSaving(false);
363
+ }
364
+ }, [ensureHandlePermission, templateObject, templateSource, templateYaml]);
365
+ return {
366
+ templateObject,
367
+ templateYaml,
368
+ yamlError,
369
+ loadError,
370
+ isDirty,
371
+ templateSource,
372
+ isReloading,
373
+ isSaving,
374
+ templateSteps,
375
+ templateParameters,
376
+ templateOutput,
377
+ fileInputRef,
378
+ handleStartSampleTemplate,
379
+ handleTemplateFileSelected,
380
+ handleOpenTemplatePicker,
381
+ handleYamlChange,
382
+ handleStepsChange,
383
+ handleParametersChange,
384
+ handleOutputChange,
385
+ handleReloadFromFile,
386
+ handleSaveTemplate
387
+ };
388
+ };
389
+
390
+ export { useTemplateState };
391
+ //# sourceMappingURL=useTemplateState.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTemplateState.esm.js","sources":["../../../src/components/TemplateDesigner/useTemplateState.ts"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { ChangeEvent, RefObject } from \"react\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../Nodes/types\";\nimport {\n convertJsonToYaml,\n convertYamlToJson,\n} from \"../../utils/yamlJsonConversion\";\nimport { SAMPLE_TEMPLATE_BLUEPRINT } from \"../../utils/sampleTemplate\";\nimport {\n DEFAULT_FILE_NAME,\n FILE_PICKER_TYPES,\n FileSystemFileHandleLike,\n FileSystemWindow,\n TemplateSource,\n asRecord,\n cloneDeep,\n cloneSteps,\n downloadString,\n isTaskStep,\n} from \"./utils\";\n\ntype TemplateState = {\n templateObject: Record<string, unknown> | null;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n isDirty: boolean;\n templateSource?: TemplateSource;\n isReloading: boolean;\n isSaving: boolean;\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n fileInputRef: RefObject<HTMLInputElement>;\n handleStartSampleTemplate: () => void;\n handleTemplateFileSelected: (event: ChangeEvent<HTMLInputElement>) => void;\n handleOpenTemplatePicker: () => void;\n handleYamlChange: (value: string) => void;\n handleStepsChange: (steps: TaskStep[]) => void;\n handleParametersChange: (parameters: TemplateParametersValue) => void;\n handleOutputChange: (output?: ScaffolderTaskOutput) => void;\n handleReloadFromFile: () => void;\n handleSaveTemplate: () => void;\n};\n\nconst parseTemplateYaml = (value: string) => {\n const parsed = JSON.parse(convertYamlToJson(value));\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Template YAML must describe an object\");\n }\n return parsed as Record<string, unknown>;\n};\n\n/**\n * Encapsulates the template designer data model including YAML parsing,\n * scaffolder spec updates, and file-system interactions.\n */\nexport const useTemplateState = (): TemplateState => {\n const [templateObject, setTemplateObject] = useState<Record<\n string,\n unknown\n > | null>(null);\n const [templateYaml, setTemplateYaml] = useState(\"\");\n const [yamlError, setYamlError] = useState<string | undefined>();\n const [loadError, setLoadError] = useState<string | undefined>();\n const [isDirty, setIsDirty] = useState(false);\n const [templateSource, setTemplateSource] = useState<\n TemplateSource | undefined\n >();\n const [isReloading, setIsReloading] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n\n const ensureHandlePermission = useCallback(\n async (\n handle: FileSystemFileHandleLike | undefined,\n mode: \"read\" | \"readwrite\"\n ) => {\n if (!handle || !handle.queryPermission || !handle.requestPermission) {\n return true;\n }\n const options = { mode };\n const current = await handle.queryPermission(options);\n if (current === \"granted\") {\n return true;\n }\n const request = await handle.requestPermission(options);\n return request === \"granted\";\n },\n []\n );\n\n const applyTemplate = useCallback(\n (template: Record<string, unknown>, source: TemplateSource) => {\n const nextTemplate = cloneDeep(template);\n const nextYaml = convertJsonToYaml(nextTemplate);\n setTemplateObject(nextTemplate);\n setTemplateYaml(nextYaml);\n setYamlError(undefined);\n setLoadError(undefined);\n setTemplateSource(source);\n setIsDirty(false);\n },\n []\n );\n\n const confirmDiscardChanges = useCallback(() => {\n if (!templateObject || !isDirty) {\n return true;\n }\n\n if (typeof window === \"undefined\") {\n return true;\n }\n\n // eslint-disable-next-line no-alert\n return window.confirm(\n \"This will discard the changes you have made. Continue?\"\n );\n }, [isDirty, templateObject]);\n\n const handleStartSampleTemplate = useCallback(() => {\n if (!confirmDiscardChanges()) {\n return;\n }\n applyTemplate(SAMPLE_TEMPLATE_BLUEPRINT, {\n type: \"sample\",\n label: \"Sample template\",\n });\n }, [applyTemplate, confirmDiscardChanges]);\n\n const handleTemplateFileSelected = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n event.target.value = \"\";\n\n if (!file) {\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n const fileContents = await file.text();\n const parsed = parseTemplateYaml(fileContents);\n applyTemplate(parsed, {\n type: \"file\",\n label: file.name,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n },\n [applyTemplate, confirmDiscardChanges]\n );\n\n const handleOpenTemplatePicker = useCallback(async () => {\n if (!confirmDiscardChanges()) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const fsWindow = window as FileSystemWindow;\n\n if (fsWindow.showOpenFilePicker) {\n try {\n const handles = await fsWindow.showOpenFilePicker({\n multiple: false,\n types: FILE_PICKER_TYPES,\n });\n const [handle] = handles ?? [];\n if (!handle) {\n return;\n }\n\n const granted = await ensureHandlePermission(handle, \"read\");\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: handle.name ?? file.name,\n handle,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return;\n }\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n return;\n }\n\n fileInputRef.current?.click();\n }, [applyTemplate, confirmDiscardChanges, ensureHandlePermission]);\n\n const templateSteps = useMemo(() => {\n if (!templateObject) {\n return [];\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return [];\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return [];\n }\n\n const maybeSteps = spec.steps;\n if (!Array.isArray(maybeSteps)) {\n return [];\n }\n\n const validSteps = maybeSteps.filter(isTaskStep) as TaskStep[];\n return cloneSteps(validSteps);\n }, [templateObject]);\n\n const templateParameters = useMemo((): TemplateParametersValue => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n if (!Object.prototype.hasOwnProperty.call(spec, \"parameters\")) {\n return undefined;\n }\n\n const rawParameters = (spec as Record<string, unknown>).parameters;\n if (rawParameters === undefined) {\n return undefined;\n }\n\n return cloneDeep(rawParameters as TemplateParametersValue);\n }, [templateObject]);\n\n const templateOutput = useMemo(() => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n const rawOutput = spec.output;\n if (!rawOutput || typeof rawOutput !== \"object\") {\n return undefined;\n }\n\n return cloneDeep(rawOutput as ScaffolderTaskOutput);\n }, [templateObject]);\n\n const handleYamlChange = useCallback((value: string) => {\n setTemplateYaml(value);\n setIsDirty(true);\n try {\n const parsed = parseTemplateYaml(value);\n setTemplateObject(parsed);\n setYamlError(undefined);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error parsing YAML\";\n setYamlError(message);\n }\n }, []);\n\n const handleStepsChange = useCallback((steps: TaskStep[]) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextSteps = cloneSteps(steps);\n\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n steps: nextSteps,\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleParametersChange = useCallback(\n (parameters: TemplateParametersValue) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n parameters: cloneDeep(parameters),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n },\n []\n );\n\n const handleOutputChange = useCallback((output?: ScaffolderTaskOutput) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n output: cloneDeep(output),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleReloadFromFile = useCallback(async () => {\n if (!templateSource) {\n return;\n }\n\n if (templateSource.type !== \"file\") {\n handleStartSampleTemplate();\n return;\n }\n\n if (!templateSource.handle) {\n handleOpenTemplatePicker();\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n setIsReloading(true);\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"read\"\n );\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await templateSource.handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: templateSource.handle.name ?? file.name ?? templateSource.label,\n handle: templateSource.handle,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error reloading template\";\n setLoadError(`Could not reload template: ${message}`);\n } finally {\n setIsReloading(false);\n }\n }, [\n applyTemplate,\n confirmDiscardChanges,\n ensureHandlePermission,\n handleOpenTemplatePicker,\n handleStartSampleTemplate,\n templateSource,\n ]);\n\n const handleSaveTemplate = useCallback(async () => {\n if (!templateObject) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n downloadString(templateYaml, DEFAULT_FILE_NAME);\n setIsDirty(false);\n return;\n }\n\n try {\n setIsSaving(true);\n setLoadError(undefined);\n const fsWindow = window as FileSystemWindow;\n\n if (templateSource?.type === \"file\" && templateSource.handle) {\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"readwrite\"\n );\n if (!granted) {\n setLoadError(\"Permission to save to the selected file was denied.\");\n return;\n }\n const writable = await templateSource.handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setIsDirty(false);\n return;\n }\n\n if (fsWindow.showSaveFilePicker) {\n const handle = await fsWindow.showSaveFilePicker({\n suggestedName: templateSource?.label ?? DEFAULT_FILE_NAME,\n types: FILE_PICKER_TYPES,\n });\n const writable = await handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setTemplateSource({\n type: \"file\",\n label: handle.name ?? templateSource?.label ?? DEFAULT_FILE_NAME,\n handle,\n });\n setIsDirty(false);\n return;\n }\n\n downloadString(templateYaml, templateSource?.label ?? DEFAULT_FILE_NAME);\n setIsDirty(false);\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error saving template\";\n setLoadError(`Failed to save template: ${message}`);\n } finally {\n setIsSaving(false);\n }\n }, [ensureHandlePermission, templateObject, templateSource, templateYaml]);\n\n return {\n templateObject,\n templateYaml,\n yamlError,\n loadError,\n isDirty,\n templateSource,\n isReloading,\n isSaving,\n templateSteps,\n templateParameters,\n templateOutput,\n fileInputRef,\n handleStartSampleTemplate,\n handleTemplateFileSelected,\n handleOpenTemplatePicker,\n handleYamlChange,\n handleStepsChange,\n handleParametersChange,\n handleOutputChange,\n handleReloadFromFile,\n handleSaveTemplate,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ const FILE_PICKER_ACCEPT = {
2
+ "application/yaml": [".yaml", ".yml"],
3
+ "application/json": [".json"]
4
+ };
5
+ const FILE_PICKER_TYPES = [
6
+ {
7
+ description: "Scaffolder template",
8
+ accept: FILE_PICKER_ACCEPT
9
+ }
10
+ ];
11
+ const DEFAULT_FILE_NAME = "template.yaml";
12
+ const isTaskStep = (candidate) => {
13
+ if (!candidate || typeof candidate !== "object") {
14
+ return false;
15
+ }
16
+ const step = candidate;
17
+ return typeof step.id === "string" && typeof step.name === "string" && typeof step.action === "string";
18
+ };
19
+ const cloneDeep = (value) => {
20
+ if (value === void 0 || value === null) {
21
+ return value;
22
+ }
23
+ return JSON.parse(JSON.stringify(value));
24
+ };
25
+ const cloneSteps = (steps) => steps.map((step) => cloneDeep(step));
26
+ const asRecord = (candidate) => {
27
+ if (!candidate || typeof candidate !== "object") {
28
+ return void 0;
29
+ }
30
+ return candidate;
31
+ };
32
+ const downloadString = (value, fileName) => {
33
+ const blob = new Blob([value], { type: "text/yaml" });
34
+ const url = URL.createObjectURL(blob);
35
+ const anchor = document.createElement("a");
36
+ anchor.href = url;
37
+ anchor.download = fileName;
38
+ anchor.style.display = "none";
39
+ document.body.appendChild(anchor);
40
+ anchor.click();
41
+ document.body.removeChild(anchor);
42
+ URL.revokeObjectURL(url);
43
+ };
44
+
45
+ export { DEFAULT_FILE_NAME, FILE_PICKER_ACCEPT, FILE_PICKER_TYPES, asRecord, cloneDeep, cloneSteps, downloadString, isTaskStep };
46
+ //# sourceMappingURL=utils.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.esm.js","sources":["../../../src/components/TemplateDesigner/utils.ts"],"sourcesContent":["import type { TaskStep } from \"@backstage/plugin-scaffolder-common\";\n\nexport const FILE_PICKER_ACCEPT = {\n \"application/yaml\": [\".yaml\", \".yml\"],\n \"application/json\": [\".json\"],\n};\n\nexport const FILE_PICKER_TYPES = [\n {\n description: \"Scaffolder template\",\n accept: FILE_PICKER_ACCEPT,\n },\n];\n\nexport const DEFAULT_FILE_NAME = \"template.yaml\";\n\nexport const isTaskStep = (candidate: unknown): candidate is TaskStep => {\n if (!candidate || typeof candidate !== \"object\") {\n return false;\n }\n const step = candidate as Record<string, unknown>;\n return (\n typeof step.id === \"string\" &&\n typeof step.name === \"string\" &&\n typeof step.action === \"string\"\n );\n};\n\nexport const cloneDeep = <T>(value: T): T => {\n if (value === undefined || value === null) {\n return value;\n }\n return JSON.parse(JSON.stringify(value)) as T;\n};\n\nexport const cloneSteps = (steps: TaskStep[]): TaskStep[] =>\n steps.map((step) => cloneDeep(step));\n\nexport const asRecord = (\n candidate: unknown\n): Record<string, unknown> | undefined => {\n if (!candidate || typeof candidate !== \"object\") {\n return undefined;\n }\n return candidate as Record<string, unknown>;\n};\n\nexport const downloadString = (value: string, fileName: string) => {\n const blob = new Blob([value], { type: \"text/yaml\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = \"none\";\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n};\n\nexport type FileSystemFileHandleLike = {\n name?: string;\n getFile: () => Promise<File>;\n createWritable?: () => Promise<{\n write: (data: Blob | string) => Promise<void>;\n close: () => Promise<void>;\n }>;\n queryPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n requestPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n};\n\nexport type TemplateSource =\n | { type: \"sample\"; label: string }\n | { type: \"file\"; label: string; handle?: FileSystemFileHandleLike };\n\nexport type FileSystemWindow = Window &\n Partial<{\n showOpenFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike[]>;\n showSaveFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike>;\n }>;\n"],"names":[],"mappings":"AAEO,MAAM,kBAAA,GAAqB;AAAA,EAChC,kBAAA,EAAoB,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpC,kBAAA,EAAoB,CAAC,OAAO;AAC9B;AAEO,MAAM,iBAAA,GAAoB;AAAA,EAC/B;AAAA,IACE,WAAA,EAAa,qBAAA;AAAA,IACb,MAAA,EAAQ;AAAA;AAEZ;AAEO,MAAM,iBAAA,GAAoB;AAE1B,MAAM,UAAA,GAAa,CAAC,SAAA,KAA8C;AACvE,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,SAAA;AACb,EAAA,OACE,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,IACnB,OAAO,KAAK,IAAA,KAAS,QAAA,IACrB,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA;AAE3B;AAEO,MAAM,SAAA,GAAY,CAAI,KAAA,KAAgB;AAC3C,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACzC;AAEO,MAAM,UAAA,GAAa,CAAC,KAAA,KACzB,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,SAAA,CAAU,IAAI,CAAC;AAE9B,MAAM,QAAA,GAAW,CACtB,SAAA,KACwC;AACxC,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AAEO,MAAM,cAAA,GAAiB,CAAC,KAAA,EAAe,QAAA,KAAqB;AACjE,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,KAAK,CAAA,EAAG,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AACpD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACzC,EAAA,MAAA,CAAO,IAAA,GAAO,GAAA;AACd,EAAA,MAAA,CAAO,QAAA,GAAW,QAAA;AAClB,EAAA,MAAA,CAAO,MAAM,OAAA,GAAU,MAAA;AACvB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;;;;"}
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
+
4
+ declare const templateDesignerPlugin: _backstage_core_plugin_api.BackstagePlugin<{
5
+ root: _backstage_core_plugin_api.RouteRef<undefined>;
6
+ }, {}, {}>;
7
+ declare const TemplateDesignerPage: () => react_jsx_runtime.JSX.Element;
8
+
9
+ export { TemplateDesignerPage, templateDesignerPlugin };
@@ -0,0 +1,2 @@
1
+ export { TemplateDesignerPage, templateDesignerPlugin } from './plugin.esm.js';
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import { createPlugin, createRoutableExtension } from '@backstage/core-plugin-api';
2
+ import { rootRouteRef } from './routes.esm.js';
3
+
4
+ const templateDesignerPlugin = createPlugin({
5
+ id: "template-designer",
6
+ routes: {
7
+ root: rootRouteRef
8
+ }
9
+ });
10
+ const TemplateDesignerPage = templateDesignerPlugin.provide(
11
+ createRoutableExtension({
12
+ name: "TemplateDesignerPage",
13
+ component: () => import('./components/TemplateDesigner/index.esm.js').then((m) => m.TemplateDesigner),
14
+ mountPoint: rootRouteRef
15
+ })
16
+ );
17
+
18
+ export { TemplateDesignerPage, templateDesignerPlugin };
19
+ //# sourceMappingURL=plugin.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createPlugin,\n createRoutableExtension,\n} from \"@backstage/core-plugin-api\";\n\nimport { rootRouteRef } from \"./routes\";\n\nexport const templateDesignerPlugin = createPlugin({\n id: \"template-designer\",\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const TemplateDesignerPage = templateDesignerPlugin.provide(\n createRoutableExtension({\n name: \"TemplateDesignerPage\",\n component: () =>\n import(\"./components/TemplateDesigner\").then((m) => m.TemplateDesigner),\n mountPoint: rootRouteRef,\n })\n);\n"],"names":[],"mappings":";;;AAOO,MAAM,yBAAyB,YAAA,CAAa;AAAA,EACjD,EAAA,EAAI,mBAAA;AAAA,EACJ,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC;AAEM,MAAM,uBAAuB,sBAAA,CAAuB,OAAA;AAAA,EACzD,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,sBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,4CAA+B,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,CAAA;AAAA,IACxE,UAAA,EAAY;AAAA,GACb;AACH;;;;"}
@@ -0,0 +1,8 @@
1
+ import { createRouteRef } from '@backstage/core-plugin-api';
2
+
3
+ const rootRouteRef = createRouteRef({
4
+ id: "template-designer"
5
+ });
6
+
7
+ export { rootRouteRef };
8
+ //# sourceMappingURL=routes.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from \"@backstage/core-plugin-api\";\n\nexport const rootRouteRef = createRouteRef({\n id: \"template-designer\",\n});\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA,CAAe;AAAA,EACzC,EAAA,EAAI;AACN,CAAC;;;;"}
@@ -0,0 +1,15 @@
1
+ function createSequentialEdges(nodes) {
2
+ if (nodes.length < 2) return [];
3
+ return nodes.slice(0, -1).map((node, index) => {
4
+ const nextNode = nodes[index + 1];
5
+ return {
6
+ id: `e-${node.id}-${nextNode.id}`,
7
+ source: node.id,
8
+ target: nextNode.id,
9
+ type: "smoothstep"
10
+ };
11
+ });
12
+ }
13
+
14
+ export { createSequentialEdges };
15
+ //# sourceMappingURL=createSequentialEdges.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSequentialEdges.esm.js","sources":["../../src/utils/createSequentialEdges.ts"],"sourcesContent":["import { Edge, Node } from \"@xyflow/react\";\n\nexport function createSequentialEdges(nodes: Node[]): Edge[] {\n if (nodes.length < 2) return [];\n\n return nodes.slice(0, -1).map((node, index) => {\n const nextNode = nodes[index + 1];\n return {\n id: `e-${node.id}-${nextNode.id}`,\n source: node.id,\n target: nextNode.id,\n type: \"smoothstep\",\n } as Edge;\n });\n}\n"],"names":[],"mappings":"AAEO,SAAS,sBAAsB,KAAA,EAAuB;AAC3D,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,EAAC;AAE9B,EAAA,OAAO,KAAA,CAAM,MAAM,CAAA,EAAG,EAAE,EAAE,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC7C,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA;AAChC,IAAA,OAAO;AAAA,MACL,IAAI,CAAA,EAAA,EAAK,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,SAAS,EAAE,CAAA,CAAA;AAAA,MAC/B,QAAQ,IAAA,CAAK,EAAA;AAAA,MACb,QAAQ,QAAA,CAAS,EAAA;AAAA,MACjB,IAAA,EAAM;AAAA,KACR;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
@@ -0,0 +1,40 @@
1
+ const SAMPLE_TEMPLATE_BLUEPRINT = {
2
+ apiVersion: "scaffolder.backstage.io/v1beta3",
3
+ kind: "Template",
4
+ metadata: {
5
+ name: "sample-template",
6
+ title: "Sample Template",
7
+ description: "Start from a single-step scaffolder template."
8
+ },
9
+ spec: {
10
+ owner: "user:guest",
11
+ type: "sample",
12
+ parameters: [
13
+ {
14
+ title: "Basic Information",
15
+ properties: {
16
+ message: {
17
+ title: "Message",
18
+ type: "string",
19
+ description: "Optional log message for the sample action.",
20
+ default: "Hello from Template Designer!"
21
+ }
22
+ }
23
+ }
24
+ ],
25
+ steps: [
26
+ {
27
+ id: "sample-action",
28
+ name: "Log Sample Message",
29
+ action: "debug:log",
30
+ input: {
31
+ message: "${{ parameters.message }}"
32
+ }
33
+ }
34
+ ],
35
+ output: {}
36
+ }
37
+ };
38
+
39
+ export { SAMPLE_TEMPLATE_BLUEPRINT };
40
+ //# sourceMappingURL=sampleTemplate.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampleTemplate.esm.js","sources":["../../src/utils/sampleTemplate.ts"],"sourcesContent":["export const SAMPLE_TEMPLATE_BLUEPRINT: Record<string, unknown> = {\n apiVersion: \"scaffolder.backstage.io/v1beta3\",\n kind: \"Template\",\n metadata: {\n name: \"sample-template\",\n title: \"Sample Template\",\n description: \"Start from a single-step scaffolder template.\",\n },\n spec: {\n owner: \"user:guest\",\n type: \"sample\",\n parameters: [\n {\n title: \"Basic Information\",\n properties: {\n message: {\n title: \"Message\",\n type: \"string\",\n description: \"Optional log message for the sample action.\",\n default: \"Hello from Template Designer!\",\n },\n },\n },\n ],\n steps: [\n {\n id: \"sample-action\",\n name: \"Log Sample Message\",\n action: \"debug:log\",\n input: {\n message: \"${{ parameters.message }}\",\n },\n },\n ],\n output: {},\n },\n};\n"],"names":[],"mappings":"AAAO,MAAM,yBAAA,GAAqD;AAAA,EAChE,UAAA,EAAY,iCAAA;AAAA,EACZ,IAAA,EAAM,UAAA;AAAA,EACN,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,iBAAA;AAAA,IACN,KAAA,EAAO,iBAAA;AAAA,IACP,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,YAAA;AAAA,IACP,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV;AAAA,QACE,KAAA,EAAO,mBAAA;AAAA,QACP,UAAA,EAAY;AAAA,UACV,OAAA,EAAS;AAAA,YACP,KAAA,EAAO,SAAA;AAAA,YACP,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa,6CAAA;AAAA,YACb,OAAA,EAAS;AAAA;AACX;AACF;AACF,KACF;AAAA,IACA,KAAA,EAAO;AAAA,MACL;AAAA,QACE,EAAA,EAAI,eAAA;AAAA,QACJ,IAAA,EAAM,oBAAA;AAAA,QACN,MAAA,EAAQ,WAAA;AAAA,QACR,KAAA,EAAO;AAAA,UACL,OAAA,EAAS;AAAA;AACX;AACF,KACF;AAAA,IACA,QAAQ;AAAC;AAEb;;;;"}