@ostack.tech/ui-kform-scaffolder 0.1.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 (38) hide show
  1. package/README.md +3 -0
  2. package/bin/at-ui-kform-scaffolder +3 -0
  3. package/dist/ostack-ui-kform-scaffolder.cjs +1754 -0
  4. package/dist/ostack-ui-kform-scaffolder.cjs.map +1 -0
  5. package/dist/ostack-ui-kform-scaffolder.css +199 -0
  6. package/dist/ostack-ui-kform-scaffolder.js +1737 -0
  7. package/dist/ostack-ui-kform-scaffolder.js.map +1 -0
  8. package/dist/types/SchematicBuilder.d.ts +6 -0
  9. package/dist/types/SchematicKind.d.ts +37 -0
  10. package/dist/types/configs/SerializationFormatConfig.d.ts +6 -0
  11. package/dist/types/configs/UseTableValuesSerializerConfig.d.ts +4 -0
  12. package/dist/types/index.d.ts +24 -0
  13. package/dist/types/main.d.ts +1 -0
  14. package/dist/types/scaffolding/ScaffoldingData.d.ts +7 -0
  15. package/dist/types/scaffolding/kotlin/KtData.d.ts +4 -0
  16. package/dist/types/scaffolding/reactApp/ReactAppData.d.ts +6 -0
  17. package/dist/types/scaffolding/reactApp/util/reactAppLayout.d.ts +12 -0
  18. package/dist/types/scaffolding/scaffolders/scaffoldActions.d.ts +3 -0
  19. package/dist/types/scaffolding/scaffolders/scaffoldApi.d.ts +3 -0
  20. package/dist/types/scaffolding/scaffolders/scaffoldAppComponent.d.ts +6 -0
  21. package/dist/types/scaffolding/scaffolders/scaffoldAppContext.d.ts +3 -0
  22. package/dist/types/scaffolding/scaffolders/scaffoldExternalContexts.d.ts +3 -0
  23. package/dist/types/scaffolding/scaffolders/scaffoldFormPages.d.ts +4 -0
  24. package/dist/types/scaffolding/scaffolders/scaffoldGradleProject.d.ts +3 -0
  25. package/dist/types/scaffolding/scaffolders/scaffoldGradleWrapper.d.ts +3 -0
  26. package/dist/types/scaffolding/scaffolders/scaffoldIssueMessages.d.ts +3 -0
  27. package/dist/types/scaffolding/scaffolders/scaffoldMain.d.ts +4 -0
  28. package/dist/types/scaffolding/scaffolders/scaffoldProjectMisc.d.ts +3 -0
  29. package/dist/types/scaffolding/scaffolders/scaffoldResponses.d.ts +3 -0
  30. package/dist/types/scaffolding/scaffolders/scaffoldSerializer.d.ts +3 -0
  31. package/dist/types/scaffolding/scaffolders/scaffoldStyles.d.ts +3 -0
  32. package/dist/types/scaffolding/scaffolders/scaffoldViteProject.d.ts +3 -0
  33. package/dist/types/scaffolding/templates/react-app/src/api/reportError.d.ts +1 -0
  34. package/dist/types/util/arrayify.d.ts +1 -0
  35. package/dist/webapp/assets/index-A9c6aN_V.js +1598 -0
  36. package/dist/webapp/assets/index-rLmIK8TT.css +1 -0
  37. package/dist/webapp/index.html +14 -0
  38. package/package.json +53 -0
@@ -0,0 +1,1754 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const kformScaffolder = require("@ostack.tech/kform-scaffolder");
5
+ const React = require("react");
6
+ function _interopNamespaceDefault(e) {
7
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
+ if (e) {
9
+ for (const k in e) {
10
+ if (k !== "default") {
11
+ const d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: () => e[k]
15
+ });
16
+ }
17
+ }
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+ const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
23
+ function SerializationFormatConfig({
24
+ defaultValue = "json",
25
+ disabled
26
+ }) {
27
+ const [useTableValuesSerializerConfig, setUseTableValuesSerializerConfig] = kformScaffolder.useConfig("useTableValuesSerializer", false);
28
+ const lastUseTableValuesSerializerConfig = React__namespace.useRef(
29
+ useTableValuesSerializerConfig
30
+ );
31
+ const [config, setConfig] = kformScaffolder.useConfig("serializationFormat", defaultValue);
32
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "builder-config-field", children: [
33
+ /* @__PURE__ */ jsxRuntime.jsx("label", { children: "Serialization format" }),
34
+ /* @__PURE__ */ jsxRuntime.jsxs(
35
+ "select",
36
+ {
37
+ value: config,
38
+ onChange: (evt) => {
39
+ setConfig(evt.target.value);
40
+ if (evt.target.value === "xml") {
41
+ lastUseTableValuesSerializerConfig.current = useTableValuesSerializerConfig;
42
+ setUseTableValuesSerializerConfig(true);
43
+ } else {
44
+ setUseTableValuesSerializerConfig(
45
+ lastUseTableValuesSerializerConfig.current
46
+ );
47
+ }
48
+ },
49
+ disabled,
50
+ children: [
51
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "json", children: "JSON" }),
52
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "xml", children: "XML" })
53
+ ]
54
+ }
55
+ )
56
+ ] });
57
+ }
58
+ function UseTableValuesSerializerConfig({
59
+ disabled
60
+ }) {
61
+ const [serializationFormatConfig] = kformScaffolder.useConfig("serializationFormat", "json");
62
+ return /* @__PURE__ */ jsxRuntime.jsx(
63
+ kformScaffolder.UseTableValuesSerializerConfig,
64
+ {
65
+ disabled: disabled || serializationFormatConfig === "xml"
66
+ }
67
+ );
68
+ }
69
+ const SPLIT_LOWER_UPPER_RE = new RegExp("([\\p{Ll}\\d])(\\p{Lu})", "gu");
70
+ const SPLIT_UPPER_UPPER_RE = new RegExp("(\\p{Lu})([\\p{Lu}][\\p{Ll}])", "gu");
71
+ const SPLIT_SEPARATE_NUMBER_RE = new RegExp("(\\d)\\p{Ll}|(\\p{L})\\d", "u");
72
+ const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
73
+ const SPLIT_REPLACE_VALUE = "$1\0$2";
74
+ const DEFAULT_PREFIX_SUFFIX_CHARACTERS = "";
75
+ function split(value) {
76
+ let result = value.trim();
77
+ result = result.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE).replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
78
+ result = result.replace(DEFAULT_STRIP_REGEXP, "\0");
79
+ let start = 0;
80
+ let end = result.length;
81
+ while (result.charAt(start) === "\0")
82
+ start++;
83
+ if (start === end)
84
+ return [];
85
+ while (result.charAt(end - 1) === "\0")
86
+ end--;
87
+ return result.slice(start, end).split(/\0/g);
88
+ }
89
+ function splitSeparateNumbers(value) {
90
+ const words = split(value);
91
+ for (let i = 0; i < words.length; i++) {
92
+ const word = words[i];
93
+ const match = SPLIT_SEPARATE_NUMBER_RE.exec(word);
94
+ if (match) {
95
+ const offset = match.index + (match[1] ?? match[2]).length;
96
+ words.splice(i, 1, word.slice(0, offset), word.slice(offset));
97
+ }
98
+ }
99
+ return words;
100
+ }
101
+ function noCase(input, options) {
102
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
103
+ return prefix + words.map(lowerFactory(options?.locale)).join(options?.delimiter ?? " ") + suffix;
104
+ }
105
+ function camelCase(input, options) {
106
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
107
+ const lower = lowerFactory(options?.locale);
108
+ const upper = upperFactory(options?.locale);
109
+ const transform = pascalCaseTransformFactory(lower, upper);
110
+ return prefix + words.map((word, index) => {
111
+ if (index === 0)
112
+ return lower(word);
113
+ return transform(word, index);
114
+ }).join("") + suffix;
115
+ }
116
+ function pascalCase(input, options) {
117
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
118
+ const lower = lowerFactory(options?.locale);
119
+ const upper = upperFactory(options?.locale);
120
+ const transform = pascalCaseTransformFactory(lower, upper);
121
+ return prefix + words.map(transform).join("") + suffix;
122
+ }
123
+ function capitalCase(input, options) {
124
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
125
+ const lower = lowerFactory(options?.locale);
126
+ const upper = upperFactory(options?.locale);
127
+ return prefix + words.map(capitalCaseTransformFactory(lower, upper)).join(" ") + suffix;
128
+ }
129
+ function constantCase(input, options) {
130
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
131
+ return prefix + words.map(upperFactory(options?.locale)).join("_") + suffix;
132
+ }
133
+ function kebabCase(input, options) {
134
+ return noCase(input, { delimiter: "-", ...options });
135
+ }
136
+ function sentenceCase(input, options) {
137
+ const [prefix, words, suffix] = splitPrefixSuffix(input, options);
138
+ const lower = lowerFactory(options?.locale);
139
+ const upper = upperFactory(options?.locale);
140
+ const transform = capitalCaseTransformFactory(lower, upper);
141
+ return prefix + words.map((word, index) => {
142
+ if (index === 0)
143
+ return transform(word);
144
+ return lower(word);
145
+ }).join(" ") + suffix;
146
+ }
147
+ function lowerFactory(locale) {
148
+ return locale === false ? (input) => input.toLowerCase() : (input) => input.toLocaleLowerCase(locale);
149
+ }
150
+ function upperFactory(locale) {
151
+ return (input) => input.toLocaleUpperCase(locale);
152
+ }
153
+ function capitalCaseTransformFactory(lower, upper) {
154
+ return (word) => `${upper(word[0])}${lower(word.slice(1))}`;
155
+ }
156
+ function pascalCaseTransformFactory(lower, upper) {
157
+ return (word, index) => {
158
+ const char0 = word[0];
159
+ const initial = index > 0 && char0 >= "0" && char0 <= "9" ? "_" + char0 : upper(char0);
160
+ return initial + lower(word.slice(1));
161
+ };
162
+ }
163
+ function splitPrefixSuffix(input, options = {}) {
164
+ const splitFn = options.split ?? (options.separateNumbers ? splitSeparateNumbers : split);
165
+ const prefixCharacters = options.prefixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;
166
+ const suffixCharacters = options.suffixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;
167
+ let prefixIndex = 0;
168
+ let suffixIndex = input.length;
169
+ while (prefixIndex < input.length) {
170
+ const char = input.charAt(prefixIndex);
171
+ if (!prefixCharacters.includes(char))
172
+ break;
173
+ prefixIndex++;
174
+ }
175
+ while (suffixIndex > prefixIndex) {
176
+ const index = suffixIndex - 1;
177
+ const char = input.charAt(index);
178
+ if (!suffixCharacters.includes(char))
179
+ break;
180
+ suffixIndex = index;
181
+ }
182
+ return [
183
+ input.slice(0, prefixIndex),
184
+ splitFn(input.slice(prefixIndex, suffixIndex)),
185
+ input.slice(suffixIndex)
186
+ ];
187
+ }
188
+ const loadTsxEjs = 'import { LoadAction } from "@ostack.tech/ui-kform";\nimport { decode<%= formClass %>FromString, <%= formClass %>FormMode } from "<%= kmpModuleName %>";\nimport { use<%= formClass %>Context } from "../<%= formClass %>Context.ts";\n\nexport function Load() {\n const { externalContexts } = use<%= formClass %>Context();\n\n return (\n externalContexts.mode !== <%= formClass %>FormMode.READ && (\n <LoadAction\n decode={async (file) => decode<%= formClass %>FromString(await file.text())}\n mimeTypes={["<%= serializationMimeType %>"]}\n extensions={[".<%= serializationFormat %>"]}\n />\n )\n );\n}\n';
189
+ const saveTsxEjs = 'import { SaveAction } from "@ostack.tech/ui-kform";\nimport { format } from "date-fns";\nimport { type <%= formClass %>, encode<%= formClass %>ToString, <%= formClass %>FormMode } from "<%= kmpModuleName %>";\nimport { use<%= formClass %>Context } from "../<%= formClass %>Context.ts";\n\nexport function Save() {\n const { externalContexts } = use<%= formClass %>Context();\n\n return (\n <SaveAction\n encode={(<%= formVar %>: <%= formClass %>) => encode<%= formClass %>ToString(<%= formVar %>, true)}\n disableOverwrite={externalContexts.mode === <%= formClass %>FormMode.READ}\n fileName={() => `<%= formTitle %> ${format(new Date(), "yyyy-MM-dd")}.<%= serializationFormat %>`}\n mimeTypes={["<%= serializationMimeType %>"]}\n extensions={[".<%= serializationFormat %>"]}\n />\n );\n}\n';
190
+ const submitTsxEjs = 'import { LocatedValidationWarning } from "@ostack.tech/kform";\nimport { SubmitAction } from "@ostack.tech/ui-kform";\nimport {\n type <%= formClass %>,\n <%= formClass %>FormMode,\n <%= formClass %>SubmitSuccess,\n <%= formClass %>SubmitValidationError,\n <%= formClass %>SubmitError,\n} from "<%= kmpModuleName %>";\nimport { use<%= formClass %>Context } from "../<%= formClass %>Context.ts";\nimport { submit } from "../api/submit.ts";\n\nexport function Submit() {\n const { externalContexts } = use<%= formClass %>Context();\n\n const handleSubmit = async (\n <%= formVar %>: <%= formClass %>,\n acceptedWarnings?: LocatedValidationWarning[],\n ) => {\n const response = await submit(<%= formVar %>, acceptedWarnings);\n if (response instanceof <%= formClass %>SubmitSuccess) {\n return response.redirectTo;\n } else if (response instanceof <%= formClass %>SubmitValidationError) {\n return response.issues;\n } else {\n throw response as <%= formClass %>SubmitError;\n }\n };\n\n const handleSuccessfulSubmit = (redirectTo: string) => {\n window.location.href = redirectTo;\n };\n\n return (\n externalContexts.mode !== <%= formClass %>FormMode.READ && (\n <SubmitAction\n onSubmit={handleSubmit}\n onSuccessfulSubmit={handleSuccessfulSubmit}\n <%_ if (useTableValuesSerializer) { -%>\n convertExternalIssuesTableRowIndicesToIds\n <%_ } -%>\n />\n )\n );\n}\n';
191
+ const validateTsxEjs = 'import { ValidateAction } from "@ostack.tech/ui-kform";\nimport { <%= formClass %>FormMode } from "<%= kmpModuleName %>";\nimport { use<%= formClass %>Context } from "../<%= formClass %>Context.ts";\n\nexport function Validate() {\n const { externalContexts } = use<%= formClass %>Context();\n\n return externalContexts.mode !== <%= formClass %>FormMode.READ && <ValidateAction />;\n}\n';
192
+ function scaffoldActions(schematic, data) {
193
+ const ejsData = {
194
+ kmpModuleName: data.kmpModuleName ?? `${kebabCase(schematic.name)}-shared`,
195
+ serializationFormat: data.serializationFormat ?? "json",
196
+ serializationMimeType: `application/${data.serializationFormat}`,
197
+ formVar: camelCase(schematic.name),
198
+ formClass: schematic.name,
199
+ formTitle: capitalCase(schematic.name),
200
+ useTableValuesSerializer: data.useTableValuesSerializer
201
+ };
202
+ kformScaffolder.addEjsTemplateFile(data, "actions/Load.tsx", loadTsxEjs, ejsData);
203
+ kformScaffolder.addEjsTemplateFile(data, "actions/Save.tsx", saveTsxEjs, ejsData);
204
+ kformScaffolder.addEjsTemplateFile(data, "actions/Submit.tsx", submitTsxEjs, ejsData);
205
+ kformScaffolder.addEjsTemplateFile(data, "actions/Validate.tsx", validateTsxEjs, ejsData);
206
+ }
207
+ const reportErrorTs = 'export const REPORT_ERROR_ENDPOINT = "/api/report-error";\n';
208
+ const submitTsEjs = 'import { LocatedValidationWarning } from "@ostack.tech/kform";\nimport {\n decode<%= formClass %>SubmitResponseFromString,\n encode<%= formClass %>ToString,\n <%= formClass %>,\n} from "<%= kmpModuleName %>";\n\nexport const SUBMIT_ENDPOINT = "/api/submit";\n\nexport async function submit(\n <%= formVar %>: <%= formClass %>,\n acceptedWarnings?: LocatedValidationWarning[],\n) {\n const params = new URLSearchParams();\n if (acceptedWarnings?.length) {\n const acceptedWarningCodes = new Set(acceptedWarnings.map((w) => w.code));\n params.set("acceptedWarnings", Array.from(acceptedWarningCodes).join());\n }\n\n const res = await fetch(`${SUBMIT_ENDPOINT}?${params}`, {\n method: "POST",\n headers: { "Content-Type": "<%= serializationMimeType %>" },\n body: encode<%= formClass %>ToString(<%= formVar %>, import.meta.env.DEV),\n });\n return decode<%= formClass %>SubmitResponseFromString(await res.text());\n}\n';
209
+ function scaffoldApi(schematic, data) {
210
+ const ejsData = {
211
+ kmpModuleName: data.kmpModuleName ?? `${kebabCase(schematic.name)}-shared`,
212
+ serializationFormat: data.serializationFormat ?? "json",
213
+ serializationMimeType: `application/${data.serializationFormat}`,
214
+ formVar: camelCase(schematic.name),
215
+ formClass: schematic.name
216
+ };
217
+ kformScaffolder.addTemplateFile(data, "api/reportError.ts", reportErrorTs);
218
+ kformScaffolder.addEjsTemplateFile(data, "api/submit.ts", submitTsEjs, ejsData);
219
+ }
220
+ function scaffoldIssueMessages(schematic, data) {
221
+ const fileName = kformScaffolder.joinPaths(
222
+ data.currentDir,
223
+ `${schematic.name}IssueMessages.tsx`
224
+ );
225
+ let file = data.files.get(fileName);
226
+ if (!file) {
227
+ data.files.set(fileName, file = kformScaffolder.tsFile());
228
+ }
229
+ scaffoldIssueMessagesConstant(schematic, {
230
+ kmpModuleName: `${kebabCase(data.rootSchematic.name)}-shared`,
231
+ ...data,
232
+ currentFile: file
233
+ });
234
+ }
235
+ function scaffoldIssueMessagesConstant(schematic, data) {
236
+ data.currentFile.imports.push({
237
+ moduleName: "@ostack.tech/ui-kform",
238
+ name: "IssueMessagesByCode",
239
+ isType: true
240
+ });
241
+ data.currentFile.declarations.push(kformScaffolder.code`
242
+ export const ${constantCase(schematic.name)}_ISSUE_MESSAGES: Record<string, IssueMessagesByCode> = {};
243
+ `);
244
+ }
245
+ function scaffoldFormPages(schematic, data) {
246
+ const layout = reactAppLayout(schematic, {
247
+ kmpModuleName: `${kebabCase(schematic.name)}-shared`,
248
+ ...data
249
+ });
250
+ for (const annex of layout) {
251
+ for (const formPage of annex.formPages) {
252
+ scaffoldFormPage(formPage.schematic, formPage.data);
253
+ if (formPage.data.currentPath !== "/") {
254
+ scaffoldIssueMessages(formPage.schematic, formPage.data);
255
+ }
256
+ }
257
+ }
258
+ }
259
+ function scaffoldFormPage(schematic, data) {
260
+ const fileName = kformScaffolder.joinPaths(data.currentDir, `${schematic.name}.tsx`);
261
+ let file = data.files.get(fileName);
262
+ if (!file) {
263
+ data.files.set(fileName, file = kformScaffolder.tsFile());
264
+ }
265
+ scaffoldFormPageComponent(schematic, {
266
+ kmpModuleName: `${kebabCase(data.rootSchematic.name)}-shared`,
267
+ ...data,
268
+ currentFile: file
269
+ });
270
+ }
271
+ function scaffoldFormPageComponent(schematic, data) {
272
+ data.currentFile.imports.push(
273
+ { moduleName: "@ostack.tech/ui-kform", name: "FormPage" },
274
+ { moduleName: "@ostack.tech/ui", name: "Grid" }
275
+ );
276
+ if (data.currentPath !== "/") {
277
+ data.currentFile.imports.push({
278
+ moduleName: `./${schematic.name}IssueMessages.tsx`,
279
+ name: `${constantCase(schematic.name)}_ISSUE_MESSAGES`
280
+ });
281
+ }
282
+ let pathString;
283
+ let preamble;
284
+ const splitPath = data.currentPath.split("/");
285
+ if (splitPath.some((fragment) => fragment === "*")) {
286
+ data.currentFile.imports.push({
287
+ moduleName: "react-router",
288
+ name: "useParams"
289
+ });
290
+ pathString = `{\`${splitPath.map((f) => f === "*" ? "${id}" : f).join("/")}\`}`;
291
+ preamble = "\n const { id } = useParams();\n";
292
+ } else {
293
+ pathString = `"${data.currentPath}"`;
294
+ preamble = "";
295
+ }
296
+ const pageComponent = kformScaffolder.code`
297
+ export function ${schematic.name}() {${preamble}
298
+ return (
299
+ <FormPage${data.currentPath === "/" ? "" : ` path=${pathString} issueMessages={${constantCase(schematic.name)}_ISSUE_MESSAGES}`}>
300
+ <Grid container>
301
+ ${schematic.children.map(
302
+ (child) => kformScaffolder.code`
303
+ <Grid xs={12}>
304
+ ${scaffoldField(child, {
305
+ ...data,
306
+ currentPath: child.childName
307
+ })}
308
+ </Grid>
309
+ `
310
+ ).join("\n\n")}
311
+ </Grid>
312
+ </FormPage>
313
+ );
314
+ }
315
+ `;
316
+ data.currentFile.declarations.push(pageComponent);
317
+ }
318
+ function scaffoldField(schematic, data) {
319
+ const schematicKind = data.schematicKinds.get(
320
+ schematic.kind
321
+ );
322
+ if (!schematicKind) {
323
+ throw new Error(`Unknown schematic kind ${schematic.kind}`);
324
+ }
325
+ if (schematicKind.scaffoldField) {
326
+ return schematicKind.scaffoldField?.(schematic, data);
327
+ }
328
+ data.currentFile.imports.push({
329
+ moduleName: "@ostack.tech/ui-kform",
330
+ name: "ControlField"
331
+ });
332
+ if (schematicKind.control) {
333
+ const [moduleName, name] = schematicKind.control.split(".");
334
+ data.currentFile.imports.push({ moduleName, name });
335
+ }
336
+ let control = schematicKind.scaffoldControl?.(schematic, data);
337
+ if (!control) {
338
+ if (!data.omitLabel) {
339
+ data.currentFile.imports.push({
340
+ moduleName: "@ostack.tech/ui",
341
+ name: "Label"
342
+ });
343
+ }
344
+ control = [
345
+ data.omitLabel ? null : `<Label>${sentenceCase(schematic.childName)}</Label>`,
346
+ `<${schematicKind.control?.split(".")[1]} />`
347
+ ].filter((s) => s).join("\n");
348
+ }
349
+ return kformScaffolder.code`
350
+ <ControlField path="${data.currentPath}">
351
+ ${control}
352
+ </ControlField>
353
+ `;
354
+ }
355
+ function arrayify(value) {
356
+ return value == null ? [] : Array.isArray(value) ? value : [value];
357
+ }
358
+ const anySchematicKind = {
359
+ ...kformScaffolder.anySchematicKind
360
+ };
361
+ const bigDecimalSchematicKind = {
362
+ ...kformScaffolder.bigDecimalSchematicKind,
363
+ control: "@ostack.tech/ui-kform.NumericControl"
364
+ };
365
+ const bigIntegerSchematicKind = {
366
+ ...kformScaffolder.bigIntegerSchematicKind,
367
+ control: "@ostack.tech/ui-kform.NumericControl"
368
+ };
369
+ const booleanSchematicKind = {
370
+ ...kformScaffolder.booleanSchematicKind,
371
+ control: "@ostack.tech/ui-kform.CheckboxControl",
372
+ scaffoldControl: (schematic, data) => data.omitLabel ? `<CheckboxControl />` : `<CheckboxControl>${sentenceCase(schematic.childName)}</CheckboxControl>`
373
+ };
374
+ const byteSchematicKind = {
375
+ ...kformScaffolder.byteSchematicKind,
376
+ control: "@ostack.tech/ui-kform.NumericControl"
377
+ };
378
+ const classAnnexSchematicKind = {
379
+ ...kformScaffolder.classSchematicKind,
380
+ defaultPackageSuffix: (childName) => `annexes.${childName.toLowerCase()}`,
381
+ kind: "Class (Annex)"
382
+ };
383
+ const classFormPageSchematicKind = {
384
+ ...kformScaffolder.classSchematicKind,
385
+ kind: "Class (FormPage)",
386
+ nullable: false
387
+ };
388
+ const classSchematicKind = {
389
+ ...kformScaffolder.classSchematicKind,
390
+ nullable: false,
391
+ scaffoldModel: (schematic, data) => {
392
+ const baseModel = kformScaffolder.classSchematicKind.scaffoldModel(schematic, data);
393
+ if (data.currentPath !== "/") {
394
+ return baseModel;
395
+ }
396
+ data.currentFile.imports.add("kotlin.js.ExperimentalJsStatic").add("kotlin.js.JsStatic").add("kotlinx.serialization.EncodeDefault").add("kotlinx.serialization.ExperimentalSerializationApi");
397
+ const classAnnotations = [];
398
+ const versionAnnotations = [
399
+ "@EncodeDefault",
400
+ "@OptIn(ExperimentalSerializationApi::class)"
401
+ ];
402
+ if (data.serializationFormat === "xml") {
403
+ data.currentFile.imports.add("nl.adaptivity.xmlutil.serialization.XmlChildrenName").add("nl.adaptivity.xmlutil.serialization.XmlElement").add("nl.adaptivity.xmlutil.serialization.XmlSerialName");
404
+ const defaultNamespace = `http://${data.currentPackage.split(".").reverse().join(".")}/schema/${(/* @__PURE__ */ new Date()).getFullYear()}`;
405
+ classAnnotations.push(
406
+ `@XmlSerialName("${schematic.name}", "${defaultNamespace}")`
407
+ );
408
+ versionAnnotations.push("@XmlElement(false)");
409
+ } else {
410
+ data.currentFile.imports.add("kotlinx.serialization.SerialName");
411
+ versionAnnotations.push('@SerialName($$"$version")');
412
+ }
413
+ return kformScaffolder.annotate(
414
+ classAnnotations,
415
+ `${baseModel} ${kformScaffolder.code`
416
+ {
417
+ ${kformScaffolder.annotate(versionAnnotations, `internal var version = ${constantCase(schematic.name)}_SERIALIZATION_VERSION`)}
418
+
419
+ companion object {
420
+ @OptIn(ExperimentalJsStatic::class)
421
+ @JsStatic
422
+ fun createInitialValue(externalContexts: ${schematic.name}ExternalContexts) =
423
+ externalContexts.initialValue ?: ${schematic.name}()
424
+ }
425
+ }
426
+ `}`
427
+ );
428
+ },
429
+ scaffoldField: (schematic, data) => {
430
+ data.currentFile.imports.push(
431
+ { moduleName: "@ostack.tech/ui", name: "FieldGroup" },
432
+ { moduleName: "@ostack.tech/ui", name: "FieldGroupHeader" },
433
+ { moduleName: "@ostack.tech/ui", name: "FieldGroupTitle" },
434
+ { moduleName: "@ostack.tech/ui", name: "FieldGroupBody" },
435
+ { moduleName: "@ostack.tech/ui", name: "Grid" }
436
+ );
437
+ return kformScaffolder.code`
438
+ <FieldGroup>
439
+ <FieldGroupHeader>
440
+ <FieldGroupTitle>${capitalCase(schematic.name)}</FieldGroupTitle>
441
+ </FieldGroupHeader>
442
+
443
+ <FieldGroupBody>
444
+ <Grid container>
445
+ ${schematic.children.map(
446
+ (child) => kformScaffolder.code`
447
+ <Grid xs={12}>
448
+ ${scaffoldField(child, {
449
+ ...data,
450
+ currentPath: kformScaffolder.joinPaths(
451
+ data.currentPath,
452
+ child.childName
453
+ )
454
+ })}
455
+ </Grid>
456
+ `
457
+ ).join("\n\n")}
458
+ </Grid>
459
+ </FieldGroupBody>
460
+ </FieldGroup>
461
+ `;
462
+ }
463
+ };
464
+ const doubleSchematicKind = {
465
+ ...kformScaffolder.doubleSchematicKind,
466
+ control: "@ostack.tech/ui-kform.NumericControl"
467
+ };
468
+ const enumSchematicKind = {
469
+ ...kformScaffolder.enumSchematicKind,
470
+ kind: "Enum",
471
+ internal: true,
472
+ nullable: false
473
+ };
474
+ const enumSelectSchematicKind = {
475
+ ...kformScaffolder.enumSchematicKind,
476
+ kind: "Enum (Select)",
477
+ control: "@ostack.tech/ui-kform.SelectControl",
478
+ scaffoldControl: (schematic, data) => {
479
+ if (!data.omitLabel) {
480
+ data.currentFile.imports.push({
481
+ moduleName: "@ostack.tech/ui",
482
+ name: "Label"
483
+ });
484
+ }
485
+ data.currentFile.imports.push({
486
+ moduleName: data.kmpModuleName,
487
+ name: schematic.name
488
+ });
489
+ return [
490
+ data.omitLabel ? null : `<Label>${sentenceCase(schematic.childName)}</Label>`,
491
+ kformScaffolder.code`
492
+ <SelectControl
493
+ options={[
494
+ ${schematic.children.map(
495
+ (child) => `{ value: ${schematic.name}.${child.childName}, text: ${JSON.stringify(sentenceCase(child.childName))} }`
496
+ ).join(",\n")}
497
+ ]}
498
+ />
499
+ `
500
+ ].filter((s) => s).join("\n");
501
+ }
502
+ };
503
+ const enumRadioGroupSchematicKind = {
504
+ ...kformScaffolder.enumSchematicKind,
505
+ kind: "Enum (RadioGroup)",
506
+ control: "@ostack.tech/ui-kform.RadioGroupControl",
507
+ scaffoldControl: (schematic, data) => {
508
+ if (!data.omitLabel) {
509
+ data.currentFile.imports.push({
510
+ moduleName: "@ostack.tech/ui",
511
+ name: "Label"
512
+ });
513
+ }
514
+ data.currentFile.imports.push({
515
+ moduleName: data.kmpModuleName,
516
+ name: schematic.name
517
+ });
518
+ return [
519
+ data.omitLabel ? null : `<Label>${sentenceCase(schematic.childName)}</Label>`,
520
+ kformScaffolder.code`
521
+ <RadioGroupControl
522
+ options={[
523
+ ${schematic.children.map(
524
+ (child) => `{ value: ${schematic.name}.${child.childName}, text: ${JSON.stringify(sentenceCase(child.childName))} }`
525
+ ).join(",\n")}
526
+ ]}
527
+ />
528
+ `
529
+ ].filter((s) => s).join("\n");
530
+ }
531
+ };
532
+ const fileSchematicKind = {
533
+ ...kformScaffolder.fileSchematicKind,
534
+ nullable: true,
535
+ control: "@ostack.tech/ui-kform.FileControl"
536
+ };
537
+ const floatSchematicKind = {
538
+ ...kformScaffolder.floatSchematicKind,
539
+ control: "@ostack.tech/ui-kform.NumericControl"
540
+ };
541
+ const intSchematicKind = {
542
+ ...kformScaffolder.intSchematicKind,
543
+ control: "@ostack.tech/ui-kform.NumericControl"
544
+ };
545
+ const listCheckboxGroupSchematicKind = {
546
+ ...kformScaffolder.listSchematicKind,
547
+ kind: "List<Enum> (CheckboxGroup)",
548
+ nullable: false,
549
+ initChildren: (childName) => [
550
+ kformScaffolder.createSchematic({
551
+ kind: "Enum",
552
+ name: pascalCase(childName),
553
+ nullable: false,
554
+ children: []
555
+ })
556
+ ],
557
+ builder: kformScaffolder.ListableBuilderWithoutKindSelect,
558
+ control: "@ostack.tech/ui-kform.CheckboxGroupControl",
559
+ scaffoldControl: (schematic, data) => {
560
+ const childSchematic = schematic.children[0];
561
+ if (childSchematic.kind !== "Enum") {
562
+ throw new Error("Invalid child kind.");
563
+ }
564
+ if (!data.omitLabel) {
565
+ data.currentFile.imports.push({
566
+ moduleName: "@ostack.tech/ui",
567
+ name: "Label"
568
+ });
569
+ }
570
+ data.currentFile.imports.push({
571
+ moduleName: data.kmpModuleName,
572
+ name: childSchematic.name
573
+ });
574
+ return [
575
+ data.omitLabel ? null : `<Label>${sentenceCase(schematic.childName)}</Label>`,
576
+ kformScaffolder.code`
577
+ <CheckboxGroupControl
578
+ options={[
579
+ ${childSchematic.children.map(
580
+ (child) => `{ value: ${childSchematic.name}.${child.childName}, text: ${JSON.stringify(sentenceCase(child.childName))} }`
581
+ ).join(",\n")}
582
+ ]}
583
+ />
584
+ `
585
+ ].filter((s) => s).join("\n");
586
+ }
587
+ };
588
+ const listSelectMultipleSchematicKind = {
589
+ ...kformScaffolder.listSchematicKind,
590
+ kind: "List<Enum> (SelectMultiple)",
591
+ nullable: false,
592
+ initChildren: (childName) => [
593
+ kformScaffolder.createSchematic({
594
+ kind: "Enum",
595
+ name: pascalCase(childName),
596
+ nullable: false,
597
+ children: []
598
+ })
599
+ ],
600
+ builder: kformScaffolder.ListableBuilderWithoutKindSelect,
601
+ control: "@ostack.tech/ui-kform.SelectMultipleControl",
602
+ scaffoldControl: (schematic, data) => {
603
+ const childSchematic = schematic.children[0];
604
+ if (childSchematic.kind !== "Enum") {
605
+ throw new Error("Invalid child kind.");
606
+ }
607
+ if (!data.omitLabel) {
608
+ data.currentFile.imports.push({
609
+ moduleName: "@ostack.tech/ui",
610
+ name: "Label"
611
+ });
612
+ }
613
+ data.currentFile.imports.push({
614
+ moduleName: data.kmpModuleName,
615
+ name: childSchematic.name
616
+ });
617
+ return [
618
+ data.omitLabel ? null : `<Label>${sentenceCase(schematic.childName)}</Label>`,
619
+ kformScaffolder.code`
620
+ <SelectMultipleControl
621
+ options={[
622
+ ${childSchematic.children.map(
623
+ (child) => `{ value: ${childSchematic.name}.${child.childName}, text: ${JSON.stringify(sentenceCase(child.childName))} }`
624
+ ).join(",\n")}
625
+ ]}
626
+ />
627
+ `
628
+ ].filter((s) => s).join("\n");
629
+ }
630
+ };
631
+ const localDateSchematicKind = {
632
+ ...kformScaffolder.localDateSchematicKind,
633
+ nullable: true,
634
+ control: "@ostack.tech/ui-kform.DateControl"
635
+ };
636
+ const longSchematicKind = {
637
+ ...kformScaffolder.longSchematicKind,
638
+ control: "@ostack.tech/ui-kform.NumericControl"
639
+ };
640
+ const shortSchematicKind = {
641
+ ...kformScaffolder.shortSchematicKind,
642
+ control: "@ostack.tech/ui-kform.NumericControl"
643
+ };
644
+ const stringSchematicKind = {
645
+ ...kformScaffolder.stringSchematicKind,
646
+ control: "@ostack.tech/ui-kform.TextControl"
647
+ };
648
+ const tableAnnexesSchematicKind = {
649
+ ...kformScaffolder.tableSchematicKind,
650
+ kind: "Table (Annexes)",
651
+ nullable: false,
652
+ builder: kformScaffolder.ListableBuilderWithoutKindSelect,
653
+ initChildren: (childName) => [
654
+ kformScaffolder.createSchematic({
655
+ kind: "Class (Annex)",
656
+ packageSuffix: `annexes.${childName.toLowerCase()}`,
657
+ name: pascalCase(childName),
658
+ nullable: false,
659
+ children: []
660
+ })
661
+ ],
662
+ propertyAnnotations: (schematic, data) => {
663
+ const annotations = arrayify(
664
+ typeof kformScaffolder.tableSchematicKind.propertyAnnotations === "function" ? kformScaffolder.tableSchematicKind.propertyAnnotations?.(schematic, data) : kformScaffolder.tableSchematicKind.propertyAnnotations
665
+ );
666
+ if (data.serializationFormat === "xml") {
667
+ data.currentFile.imports.add(
668
+ "nl.adaptivity.xmlutil.serialization.XmlChildrenName"
669
+ );
670
+ annotations.push(
671
+ `@XmlChildrenName("${camelCase(schematic.children[0].name)}")`
672
+ );
673
+ }
674
+ return annotations;
675
+ }
676
+ };
677
+ const tableSchematicKind = {
678
+ ...kformScaffolder.tableSchematicKind,
679
+ nullable: false,
680
+ builder: kformScaffolder.ListableBuilderWithoutKindSelect,
681
+ initChildren: (childName) => [
682
+ kformScaffolder.createSchematic({
683
+ kind: "Class",
684
+ name: `${pascalCase(childName)}Row`,
685
+ nullable: false,
686
+ children: []
687
+ })
688
+ ],
689
+ propertyAnnotations: tableAnnexesSchematicKind.propertyAnnotations,
690
+ control: "@ostack.tech/ui-kform.TableControl",
691
+ scaffoldControl: (schematic, data) => {
692
+ const rowSchematic = schematic.children[0];
693
+ if (rowSchematic.kind !== "Class") {
694
+ throw new Error("Table child schematic is not of Class kind.");
695
+ }
696
+ data.currentFile.imports.push(
697
+ { moduleName: "@ostack.tech/ui", name: "Label" },
698
+ {
699
+ moduleName: "@ostack.tech/ui-kform",
700
+ name: "tableControlIndexColumn"
701
+ },
702
+ {
703
+ moduleName: "@ostack.tech/ui-kform",
704
+ name: "tableControlActionsColumn"
705
+ },
706
+ {
707
+ moduleName: "@ostack.tech/ui-kform",
708
+ name: "TableControlAddRowTrigger"
709
+ },
710
+ { moduleName: "@ostack.tech/ui-kform", name: "TableControlContent" }
711
+ );
712
+ return kformScaffolder.code`
713
+ <TableControl
714
+ columns={[
715
+ tableControlIndexColumn(),
716
+ ${rowSchematic.children.map(
717
+ (child) => kformScaffolder.code`
718
+ {
719
+ label: ${JSON.stringify(sentenceCase(child.childName))},
720
+ render: () => (
721
+ ${scaffoldField(child, {
722
+ ...data,
723
+ omitLabel: true,
724
+ currentPath: child.childName
725
+ })}
726
+ )
727
+ }
728
+ `
729
+ ).join(",\n")},
730
+ tableControlActionsColumn()
731
+ ]}
732
+ >
733
+ <Label>${sentenceCase(schematic.childName)}</Label>
734
+ <TableControlAddRowTrigger />
735
+ <TableControlContent />
736
+ </TableControl>
737
+ `;
738
+ }
739
+ };
740
+ const defaultSchematicKinds = [
741
+ anySchematicKind,
742
+ bigDecimalSchematicKind,
743
+ bigIntegerSchematicKind,
744
+ booleanSchematicKind,
745
+ byteSchematicKind,
746
+ classSchematicKind,
747
+ classAnnexSchematicKind,
748
+ classFormPageSchematicKind,
749
+ doubleSchematicKind,
750
+ enumSchematicKind,
751
+ enumSelectSchematicKind,
752
+ enumRadioGroupSchematicKind,
753
+ fileSchematicKind,
754
+ floatSchematicKind,
755
+ intSchematicKind,
756
+ listCheckboxGroupSchematicKind,
757
+ listSelectMultipleSchematicKind,
758
+ localDateSchematicKind,
759
+ longSchematicKind,
760
+ shortSchematicKind,
761
+ stringSchematicKind,
762
+ tableAnnexesSchematicKind,
763
+ tableSchematicKind
764
+ ];
765
+ function reactAppLayout(schematic, data) {
766
+ const annexes = [];
767
+ if (schematic.children?.every(
768
+ (child) => child.kind === classAnnexSchematicKind.kind || child.kind === tableAnnexesSchematicKind.kind
769
+ )) {
770
+ for (const annex of schematic.children) {
771
+ if (annex.kind === classAnnexSchematicKind.kind) {
772
+ annexes.push(
773
+ layoutAnnex(annex, {
774
+ ...data,
775
+ currentPath: kformScaffolder.joinPaths(data.currentPath, annex.childName),
776
+ currentDir: kformScaffolder.joinPaths(
777
+ data.currentDir,
778
+ annex.packageSuffix?.replace(".", "/")
779
+ )
780
+ })
781
+ );
782
+ } else {
783
+ annexes.push(
784
+ layoutRepetitiveAnnex(annex, {
785
+ ...data,
786
+ currentPath: kformScaffolder.joinPaths(data.currentPath, annex.childName)
787
+ })
788
+ );
789
+ }
790
+ }
791
+ } else if (schematic.children?.every(
792
+ (child) => child.kind === classFormPageSchematicKind.kind
793
+ )) {
794
+ annexes.push(layoutAnnex(schematic, data));
795
+ } else if (schematic.children?.some(
796
+ (child) => child.kind === classAnnexSchematicKind.kind || child.kind === tableAnnexesSchematicKind.kind || child.kind === classFormPageSchematicKind.kind
797
+ )) {
798
+ throw new Error(
799
+ "Annexes/form pages cannot be mixed with other kinds of fields."
800
+ );
801
+ } else {
802
+ annexes.push(layoutAnnex(schematic, data));
803
+ }
804
+ return annexes;
805
+ }
806
+ function layoutRepetitiveAnnex(schematic, data) {
807
+ const childSchematic = schematic.children[0];
808
+ return layoutAnnex(childSchematic, {
809
+ ...data,
810
+ currentPath: kformScaffolder.joinPaths(data.currentPath, "*"),
811
+ currentDir: kformScaffolder.joinPaths(
812
+ data.currentDir,
813
+ childSchematic.packageSuffix?.replace(".", "/")
814
+ )
815
+ });
816
+ }
817
+ function layoutAnnex(schematic, data) {
818
+ if (schematic.children?.some(
819
+ (child) => child.kind === classAnnexSchematicKind.kind || child.kind === tableAnnexesSchematicKind.kind
820
+ )) {
821
+ throw new Error(
822
+ "Annexes must only appear at the top level of the schematic."
823
+ );
824
+ }
825
+ let formPages;
826
+ if (schematic.children?.every(
827
+ (child) => child.kind === classFormPageSchematicKind.kind
828
+ )) {
829
+ formPages = schematic.children?.map((formPage) => ({
830
+ schematic: formPage,
831
+ data: {
832
+ ...data,
833
+ currentPath: kformScaffolder.joinPaths(
834
+ data.currentPath,
835
+ camelCase(formPage.childName)
836
+ ),
837
+ currentDir: kformScaffolder.joinPaths(
838
+ data.currentDir,
839
+ formPage.packageSuffix?.replace(".", "/")
840
+ )
841
+ }
842
+ }));
843
+ } else if (schematic.children?.some(
844
+ (child) => child.kind === classFormPageSchematicKind.kind
845
+ )) {
846
+ throw new Error("Form pages cannot be mixed with other kinds of fields.");
847
+ } else {
848
+ formPages = [{ schematic, data }];
849
+ }
850
+ return { schematic, data, formPages };
851
+ }
852
+ function scaffoldAppComponent(schematic, data) {
853
+ const fileName = kformScaffolder.joinPaths(data.currentDir, `${schematic.name}App.tsx`);
854
+ let file = data.files.get(fileName);
855
+ if (!file) {
856
+ data.files.set(fileName, file = kformScaffolder.tsFile());
857
+ }
858
+ scaffoldAppComponentFile(schematic, {
859
+ kmpModuleName: `${kebabCase(schematic.name)}-shared`,
860
+ ...data,
861
+ currentFile: file
862
+ });
863
+ scaffoldIssueMessages(schematic, data);
864
+ }
865
+ function scaffoldAppComponentFile(schematic, data) {
866
+ data.currentFile.imports.push(
867
+ { moduleName: "@ostack.tech/kform", name: "ktMapToObject" },
868
+ { moduleName: "@ostack.tech/ui-kform", name: "FormApp" },
869
+ { moduleName: "react", name: "useMemo" },
870
+ { moduleName: data.kmpModuleName, name: schematic.name },
871
+ { moduleName: data.kmpModuleName, name: `${schematic.name}FormMode` },
872
+ { moduleName: data.kmpModuleName, name: `${schematic.name}Schema` },
873
+ { moduleName: `./api/reportError.ts`, name: "REPORT_ERROR_ENDPOINT" },
874
+ {
875
+ moduleName: `./${schematic.name}Context.ts`,
876
+ name: `use${schematic.name}Context`
877
+ },
878
+ {
879
+ moduleName: `./${schematic.name}IssueMessages.tsx`,
880
+ name: `${constantCase(schematic.name)}_ISSUE_MESSAGES`
881
+ }
882
+ );
883
+ data.currentFile.declarations.push(kformScaffolder.code`
884
+ export function ${schematic.name}App() {
885
+ const { externalContexts } = use${schematic.name}Context();
886
+
887
+ return (
888
+ <FormApp
889
+ schema={${schematic.name}Schema.get()}
890
+ initialValue={useMemo(
891
+ () => ${schematic.name}.createInitialValue(externalContexts),
892
+ [externalContexts],
893
+ )}
894
+ externalContexts={useMemo(
895
+ () => ktMapToObject(externalContexts.toMap()),
896
+ [externalContexts],
897
+ )}
898
+ readOnly={externalContexts.mode === ${schematic.name}FormMode.READ}
899
+ validationMode={
900
+ externalContexts.mode === ${schematic.name}FormMode.READ
901
+ ? "manual"
902
+ : "auto"
903
+ }
904
+ issueMessages={${constantCase(schematic.name)}_ISSUE_MESSAGES}
905
+ errorReportingUrl={REPORT_ERROR_ENDPOINT}
906
+ >
907
+ <${schematic.name}Layout />
908
+ </FormApp>
909
+ );
910
+ }
911
+ `);
912
+ const layout = reactAppLayout(schematic, data);
913
+ data.currentFile.imports.push(
914
+ { moduleName: "react-router", name: "useNavigate" },
915
+ { moduleName: "react-router", name: "useLocation" },
916
+ { moduleName: "react-router", name: "Outlet" },
917
+ { moduleName: "@ostack.tech/ui-kform", name: "Annexes" },
918
+ { moduleName: "@ostack.tech/ui-kform", name: "Annex" },
919
+ {
920
+ moduleName: "@ostack.tech/ui-kform",
921
+ name: "AnnexObject",
922
+ isType: true
923
+ },
924
+ { moduleName: "@ostack.tech/ui-kform", name: "TopBar" },
925
+ { moduleName: "@ostack.tech/ui-kform", name: "TopBarActions" },
926
+ { moduleName: "./actions/Load.tsx", name: "Load" },
927
+ { moduleName: "./actions/Save.tsx", name: "Save" },
928
+ { moduleName: "./actions/Validate.tsx", name: "Validate" },
929
+ { moduleName: "./actions/Submit.tsx", name: "Submit" },
930
+ { moduleName: "@ostack.tech/ui-kform", name: "FormPages" },
931
+ {
932
+ moduleName: "@ostack.tech/ui-kform",
933
+ name: "FormPageObject",
934
+ isType: true
935
+ },
936
+ { moduleName: "@ostack.tech/ui-kform", name: "IssuesPanel" }
937
+ );
938
+ let annexesManager = "";
939
+ if (layout.length > 1) {
940
+ data.currentFile.imports.push({
941
+ moduleName: "@ostack.tech/ui-kform",
942
+ name: "AnnexesManager"
943
+ });
944
+ annexesManager = `
945
+ <AnnexesManager />
946
+ `;
947
+ }
948
+ let formPagesNavigation = "";
949
+ if (layout.some((annex) => annex.formPages.length > 1)) {
950
+ data.currentFile.imports.push({
951
+ moduleName: "@ostack.tech/ui-kform",
952
+ name: "FormPagesNavigation"
953
+ });
954
+ if (layout.every((annex) => annex.formPages.length > 1)) {
955
+ formPagesNavigation = `
956
+ <FormPagesNavigation />
957
+ `;
958
+ } else {
959
+ formPagesNavigation = `
960
+ {pages.length > 1 && <FormPagesNavigation />}
961
+ `;
962
+ }
963
+ }
964
+ data.currentFile.declarations.push(kformScaffolder.code`
965
+ function ${schematic.name}Layout() {
966
+ const navigate = useNavigate();
967
+ const { pathname } = useLocation();
968
+
969
+ const annexes: AnnexObject[] = useMemo(() => ${scaffoldAnnexesArray(layout)}, []);
970
+
971
+ const pagesByAnnex: Record<string, FormPageObject[]> = useMemo(() => (${scaffoldFormPagesByAnnexObject(layout)}), []);
972
+
973
+ return (
974
+ <>
975
+ <Annexes annexes={annexes} activeAnnex={pathname}>
976
+ <TopBar>${annexesManager}
977
+ <TopBarActions>
978
+ <Load />
979
+ <Save />
980
+ <Validate />
981
+ <Submit />
982
+ </TopBarActions>
983
+ </TopBar>
984
+
985
+ {Object.entries(pagesByAnnex).map(([annexPath, pages]) => (
986
+ <Annex path={annexPath} key={annexPath}>
987
+ <FormPages
988
+ pages={pages}
989
+ activePage={pathname}
990
+ onActivePageChange={(activePage) => {
991
+ const newPathname = activePage?.toString() ?? "/";
992
+ if (pathname !== newPathname) {
993
+ void navigate(newPathname, {
994
+ replace: newPathname.startsWith(
995
+ pathname.endsWith("/") ? pathname : \`\${pathname}/\`,
996
+ )
997
+ });
998
+ }
999
+ }}
1000
+ >${formPagesNavigation}
1001
+ <Outlet />
1002
+ </FormPages>
1003
+ </Annex>
1004
+ ))}
1005
+ </Annexes>
1006
+
1007
+ <IssuesPanel />
1008
+ </>
1009
+ );
1010
+ }
1011
+ `);
1012
+ }
1013
+ function scaffoldAnnexesArray(layout) {
1014
+ return kformScaffolder.code`
1015
+ [
1016
+ ${layout.map(
1017
+ (annex) => `{ path: "${annex.data.currentPath}", title: "${sentenceCase(
1018
+ annex.schematic.name
1019
+ )}"${annex.formPages.length === 1 && annex.data.currentPath === annex.formPages[0].data.currentPath ? ", documentTitle: null" : ""} }`
1020
+ ).join(",\n")}
1021
+ ]
1022
+ `;
1023
+ }
1024
+ function scaffoldFormPagesByAnnexObject(layout) {
1025
+ return kformScaffolder.code`
1026
+ {
1027
+ ${layout.map(
1028
+ (annex) => `"${annex.data.currentPath}": ` + kformScaffolder.code`
1029
+ [
1030
+ ${annex.formPages.map(
1031
+ (formPage) => annex.schematic === formPage.schematic ? `{ title: "${sentenceCase(
1032
+ formPage.schematic.name
1033
+ )}", code: "${formPage.schematic.name?.[0].toUpperCase()}"${formPage.data.currentPath === "/" ? ", documentTitle: null" : ""} }` : `{ path: "${formPage.data.currentPath.slice(
1034
+ annex.data.currentPath.length + (annex.data.currentPath.endsWith("/") ? 0 : 1)
1035
+ )}", title: "${sentenceCase(
1036
+ formPage.schematic.name
1037
+ )}", code: "${formPage.schematic.name?.[0].toUpperCase()}" }`
1038
+ ).join(",\n")}
1039
+ ]
1040
+ `
1041
+ ).join(",\n")}
1042
+ }
1043
+ `;
1044
+ }
1045
+ const contextTsEjs = 'import { createContext, useContext } from "react";\nimport { <%= formClass %>ExternalContexts } from "<%= kmpModuleName %>";\n\nexport interface <%= formClass %>ContextValue {\n externalContexts: <%= formClass %>ExternalContexts;\n}\n\nexport const <%= formClass %>Context = createContext<<%= formClass %>ContextValue>(null as never);\n\nexport function use<%= formClass %>Context(): <%= formClass %>ContextValue {\n return useContext(<%= formClass %>Context);\n}\n';
1046
+ function scaffoldAppContext(schematic, data) {
1047
+ const ejsData = {
1048
+ kmpModuleName: data.kmpModuleName ?? `${kebabCase(schematic.name)}-shared`,
1049
+ formClass: schematic.name
1050
+ };
1051
+ kformScaffolder.addEjsTemplateFile(
1052
+ data,
1053
+ `${schematic.name}Context.ts`,
1054
+ contextTsEjs,
1055
+ ejsData
1056
+ );
1057
+ }
1058
+ const externalContextsKt = 'package <%= filePackage %>\n\nimport kotlin.js.JsExport\nimport kotlin.jvm.JvmOverloads\nimport kotlinx.serialization.Serializable\n\n@JsExport\n@Serializable\nenum class <%= formClass %>FormMode {\n /** Submitting a new form. */\n NEW,\n /** Reading a previously submitted form (`initialValue` should be provided as context). */\n READ,\n /** Replacing a previously submitted form (`initialValue` should be provided as context). */\n REPLACE,\n}\n\n@JsExport\n@Serializable\ndata class <%= formClass %>ExternalContexts @JvmOverloads constructor(\n val mode: <%= formClass %>FormMode = <%= formClass %>FormMode.NEW,\n val initialValue: <%= formClass %>? = null,\n) {\n fun toMap(): Map<String, Any?> = mapOf("mode" to mode, "initialValue" to initialValue)\n}\n';
1059
+ function scaffoldExternalContexts(schematic, data) {
1060
+ const ejsData = {
1061
+ filePackage: data.currentPackage,
1062
+ formClass: schematic.name
1063
+ };
1064
+ kformScaffolder.addEjsTemplateFile(
1065
+ data,
1066
+ `${schematic.name}ExternalContexts.kt`,
1067
+ externalContextsKt,
1068
+ ejsData
1069
+ );
1070
+ }
1071
+ const buildGradleKts = "allprojects {\n repositories { mavenCentral() }\n}\n";
1072
+ const gradlePropertiesEjs = "group=<%= group %>\nversion=0.0.1\n\norg.gradle.caching=true\norg.gradle.configuration-cache=true\n";
1073
+ const libsVersionsTomlEjs = '[versions]\n# Plugins\nkotlin = "2.2.20"\nnodeGradle = "7.1.0"\n# Libraries\nkotlinxCoroutines = "1.10.2"\nkform = "<%= kFormVersion %>"\n<%_ if (usesKotlinxDatetime) { -%>\nkotlinxDatetime = "0.7.1"\n<%_ } -%>\n<%_ if (serializationFormat === "json") { -%>\nkotlinxSerialization = "1.9.0"\n<%_ } -%>\n<%_ if (usesKtMath) { -%>\nktMath = "0.10.2"\n<%_ } -%>\nslf4j = "2.0.17"\n<%_ if (serializationFormat === "xml") { -%>\nxmlutil = "0.91.1"\n<%_ } -%>\n# Runtimes\njvmToolchain = "17"\nnodejs = "22.20.0"\n\n[libraries]\nkform = { module = "tech.ostack:kform", version.ref = "kform" }\nkform-jsBindings = { module = "tech.ostack:kform-js-bindings", version.ref = "kform" }\nkotlinxCoroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }\n<%_ if (usesKotlinxDatetime) { -%>\nkotlinxDatetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }\n<%_ } -%>\n<%_ if (serializationFormat === "json") { -%>\nkotlinxSerialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }\n<%_ } -%>\n<%_ if (usesKtMath) { -%>\nktMath = { module = "io.github.gciatto:kt-math", version.ref = "ktMath" }\n<%_ } -%>\nslf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }\n<%_ if (serializationFormat === "xml") { -%>\nxmlutil-serialization = { module = "io.github.pdvrieze.xmlutil:serialization", version.ref = "xmlutil" }\n<%_ } -%>\n\n[plugins]\nkotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }\nkotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }\nnodeGradle = { id = "com.github.node-gradle.node", version.ref = "nodeGradle" }\n';
1074
+ const reactAppBuildGradleKtsEjs = 'import com.github.gradle.node.npm.task.NpmTask\n\nplugins {\n alias(libs.plugins.nodeGradle)\n base\n}\n\nval isCI = System.getenv("CI") !in arrayOf(null, "0", "false")\nnode {\n download = true\n version = libs.versions.nodejs.get()\n npmInstallCommand = if (isCI) "ci" else "install"\n}\n\nval sharedPackage = project(":shared").file("build/<%= formId %>-shared-$version.tgz")\n\nval npmInstallShared by tasks.registering(NpmTask::class) {\n group = "build"\n dependsOn(":shared:packJsPackage")\n npmCommand = listOf("install", "<%= formId %>-shared@file:$sharedPackage")\n\n inputs.file(sharedPackage)\n outputs.dir("node_modules/<%= formId %>-shared")\n}\n\ntasks.npmInstall {\n dependsOn(npmInstallShared)\n}\n\nval npmRunDev by tasks.registering(NpmTask::class) {\n group = "development"\n dependsOn(tasks.npmInstall)\n npmCommand = listOf("run", "dev")\n}\n\nprivate fun NpmTask.npmRunBuild(buildReason: String) {\n group = "build"\n dependsOn(tasks.npmInstall)\n npmCommand = listOf("run", "build")\n environment = mapOf("VITE_BUILD_REASON" to buildReason)\n\n inputs.dir("src")\n inputs.file(sharedPackage)\n inputs.file("index.html")\n inputs.file("package.json")\n inputs.file("tsconfig.json")\n inputs.file("tsconfig.app.json")\n inputs.file("tsconfig.node.json")\n inputs.file("vite.config.ts")\n outputs.dir("build/dist")\n}\n\nval npmRunBuild by tasks.registering(NpmTask::class) {\n npmRunBuild("production")\n}\n\nval npmRunBuildPreview by tasks.registering(NpmTask::class) {\n npmRunBuild("preview")\n}\n\nval npmRunPreview by tasks.registering(NpmTask::class) {\n group = "development"\n dependsOn(npmRunBuildPreview)\n npmCommand = listOf("run", "preview")\n}\n\nval npmRunLint by tasks.registering(NpmTask::class) {\n group = "verification"\n dependsOn(tasks.npmInstall)\n npmCommand = listOf("run", "lint")\n\n inputs.dir("src")\n inputs.file("eslint.config.js")\n inputs.file("package.json")\n inputs.file("tsconfig.json")\n inputs.file("tsconfig.app.json")\n inputs.file("tsconfig.node.json")\n outputs.upToDateWhen { true }\n}\n\ntasks.assemble {\n dependsOn(npmRunBuild)\n}\n';
1075
+ const settingsGradleKtsEjs = 'plugins {\n id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"\n}\n\nrootProject.name = "<%= formId %>"\n\ninclude("shared", "react-app")\n';
1076
+ const sharedBuildGradleKtsEjs = 'import com.github.gradle.node.npm.task.NpmTask\n\nplugins {\n alias(libs.plugins.kotlin.multiplatform)\n alias(libs.plugins.kotlin.serialization)\n alias(libs.plugins.nodeGradle)\n}\n\nkotlin {\n jvmToolchain(libs.versions.jvmToolchain.get().toInt())\n jvm {\n testRuns["test"].executionTask.configure { useJUnitPlatform() }\n }\n js {\n compilerOptions {\n target = "es2015"\n freeCompilerArgs.add("-Xes-long-as-bigint")\n freeCompilerArgs.add("-Xwarning-level=NON_EXPORTABLE_TYPE:disabled")\n }\n binaries.library()\n browser { testTask { useMocha() } }\n generateTypeScriptDefinitions()\n }\n\n sourceSets {\n all {\n // Opt in to the experimental `JsExport` annotation\n languageSettings.optIn("kotlin.js.ExperimentalJsExport")\n }\n\n commonMain.dependencies {\n api(libs.kform)\n <%_ if (usesKotlinxDatetime) { -%>\n api(libs.kotlinxDatetime)\n <%_ } -%>\n <%_ if (serializationFormat === "json") { -%>\n api(libs.kotlinxSerialization.json)\n <%_ } -%>\n <%_ if (usesKtMath) { -%>\n api(libs.ktMath)\n <%_ } -%>\n <%_ if (serializationFormat === "xml") { -%>\n api(libs.xmlutil.serialization)\n <%_ } -%>\n }\n commonTest.dependencies {\n implementation(kotlin("test"))\n implementation(libs.kotlinxCoroutines.test)\n }\n jvmTest.dependencies {\n implementation(libs.slf4j.simple)\n }\n jsMain.dependencies {\n implementation(libs.kform.jsBindings)\n <%_ if (usesKotlinxDatetime) { -%>\n implementation(npm("@js-joda/timezone", "2.3.0"))\n <%_ } -%>\n }\n }\n}\n\nval isCI = System.getenv("CI") !in arrayOf(null, "0", "false")\nnode {\n download = true\n version = libs.versions.nodejs.get()\n npmInstallCommand = if (isCI) "ci" else "install"\n}\n\n// Packs the result of the JS compilation, for consumption by the React app\nval packJsPackage by tasks.registering(NpmTask::class) {\n group = "build"\n dependsOn("jsBrowserProductionLibraryDistribution")\n\n val libraryDir = "build/dist/js/productionLibrary"\n npmCommand = listOf("pack", libraryDir, "--pack-destination", "build")\n\n inputs.dir(libraryDir)\n outputs.file("build/<%= formId %>-shared-${version}.tgz")\n}\n';
1077
+ const jsJodaTimeZoneKtEjs = 'package <%= filePackage %>\n\n// See: https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#note-about-time-zones-in-js\n@JsModule("@js-joda/timezone")\n@JsNonModule\nexternal object JsJodaTimeZoneModule\n\n@JsExport\nval jsJodaTz = JsJodaTimeZoneModule\n';
1078
+ function scaffoldGradleProject(schematic, data) {
1079
+ const ejsData = {
1080
+ group: data.currentPackage,
1081
+ filePackage: data.currentPackage,
1082
+ formId: kebabCase(schematic.name),
1083
+ formTitle: capitalCase(schematic.name),
1084
+ kFormVersion: "0.31.0",
1085
+ serializationFormat: data.serializationFormat ?? "json",
1086
+ usesKotlinxDatetime: usesKotlinxDatetime(schematic, data),
1087
+ usesKtMath: usesKtMath(schematic)
1088
+ };
1089
+ kformScaffolder.addEjsTemplateFile(data, "gradle.properties", gradlePropertiesEjs, ejsData);
1090
+ kformScaffolder.addEjsTemplateFile(
1091
+ data,
1092
+ "settings.gradle.kts",
1093
+ settingsGradleKtsEjs,
1094
+ ejsData
1095
+ );
1096
+ kformScaffolder.addEjsTemplateFile(
1097
+ data,
1098
+ "gradle/libs.versions.toml",
1099
+ libsVersionsTomlEjs,
1100
+ ejsData
1101
+ );
1102
+ kformScaffolder.addTemplateFile(data, "build.gradle.kts", buildGradleKts);
1103
+ kformScaffolder.addEjsTemplateFile(
1104
+ data,
1105
+ "shared/build.gradle.kts",
1106
+ sharedBuildGradleKtsEjs,
1107
+ ejsData
1108
+ );
1109
+ if (ejsData.usesKotlinxDatetime) {
1110
+ kformScaffolder.addEjsTemplateFile(
1111
+ data,
1112
+ "shared/src/jsMain/kotlin/JsJodaTimeZone.kt",
1113
+ jsJodaTimeZoneKtEjs,
1114
+ ejsData
1115
+ );
1116
+ }
1117
+ kformScaffolder.addEjsTemplateFile(
1118
+ data,
1119
+ "react-app/build.gradle.kts",
1120
+ reactAppBuildGradleKtsEjs,
1121
+ ejsData
1122
+ );
1123
+ }
1124
+ function usesKotlinxDatetime(schematic, data) {
1125
+ const schematicKind = data.schematicKinds.get(schematic.kind);
1126
+ return schematicKind?.package === "kotlinx.datetime" || schematic.children?.some((child) => usesKotlinxDatetime(child, data)) === true;
1127
+ }
1128
+ function usesKtMath(schematic) {
1129
+ return ["BigInteger", "BigDecimal"].includes(schematic.kind) || schematic.children?.some((child) => usesKtMath(child)) === true;
1130
+ }
1131
+ const gradleWrapperJar = "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AAAAAAAAAAAAAAAwDgAATUVUQS1JTkYvTUFOSUZFU1QuTUZVVAUAAQAAAABQSwECFAAUAAgICAAAACEAAsIE3yIBAABwAQAAMQAJAAAAAAAAAAAAAAD2DgAAb3JnL2dyYWRsZS9jbGkvQ29tbWFuZExpbmVBcmd1bWVudEV4Y2VwdGlvbi5jbGFzc1VUBQABAAAAAFBLAQIUABQACAgIAAAAIQBsZK5NbgIAALMDAAAmAAkAAAAAAAAAAAAAAIAQAABvcmcvZ3JhZGxlL2NsaS9Db21tYW5kTGluZU9wdGlvbi5jbGFzc1VUBQABAAAAAFBLAQIUABQACAgIAAAAIQBrrAeZWwIAALYEAAAzAAkAAAAAAAAAAAAAAEsTAABvcmcvZ3JhZGxlL2NsaS9Db21tYW5kTGluZVBhcnNlciRBZnRlck9wdGlvbnMuY2xhc3NVVAUAAQAAAABQSwECFAAUAAgICAAAACEABUgOxC4DAABdBwAAPAAJAAAAAAAAAAAAAAAQFgAAb3JnL2dyYWRsZS9jbGkvQ29tbWFuZExpbmVQYXJzZXIkQmVmb3JlRmlyc3RTdWJDb21tYW5kLmNsYXNzVVQFAAEAAAAAUEsBAhQAFAAICAgAAAAhAO+A7pzcBgAAYg4AAD0ACQAAAAAAAAAAAAAAsRkAAG9yZy9ncmFkbGUvY2xpL0NvbW1hbmRMaW5lUGFyc2VyJEtub3duT3B0aW9uUGFyc2VyU3RhdGUuY2xhc3NVVAUAAQAAAABQSwECFAAUAAgICAAAACEAxIDBO00CAACXBAAAPAAJAAAAAAAAAAAAAAABIQAAb3JnL2dyYWRsZS9jbGkvQ29tbWFuZExpbmVQYXJzZXIkTWlzc2luZ09wdGlvbkFyZ1N0YXRlLmNsYXNzVVQFAAEAAAAAUEsBAhQAFAAICAgAAAAhAKUEGSPYAgAASgUAAD0ACQAAAAAAAAAAAAAAwSMAAG9yZy9ncmFkbGUvY2xpL0NvbW1hbmRMaW5lUGFyc2VyJE9wdGlvbkF3YXJlUGFyc2VyU3RhdGUuY2xhc3NVVAUAAQAAAABQSwECFAAUAAgICAAAACEAIjgzfKIBAAB9AgAAOAAJAAAAAAAAAAAAAAANJwAAb3JnL2dyYWRsZS9jbGkvQ29tbWFuZExpbmVQYXJzZXIkT3B0aW9uUGFyc2Vy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";
1132
+ const gradleWrapperProperties = "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.14.2-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n";
1133
+ const gradlewBat = `@rem
1134
+ @rem Copyright 2015 the original author or authors.
1135
+ @rem
1136
+ @rem Licensed under the Apache License, Version 2.0 (the "License");
1137
+ @rem you may not use this file except in compliance with the License.
1138
+ @rem You may obtain a copy of the License at
1139
+ @rem
1140
+ @rem https://www.apache.org/licenses/LICENSE-2.0
1141
+ @rem
1142
+ @rem Unless required by applicable law or agreed to in writing, software
1143
+ @rem distributed under the License is distributed on an "AS IS" BASIS,
1144
+ @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1145
+ @rem See the License for the specific language governing permissions and
1146
+ @rem limitations under the License.
1147
+ @rem
1148
+ @rem SPDX-License-Identifier: Apache-2.0
1149
+ @rem
1150
+
1151
+ @if "%DEBUG%"=="" @echo off
1152
+ @rem ##########################################################################
1153
+ @rem
1154
+ @rem Gradle startup script for Windows
1155
+ @rem
1156
+ @rem ##########################################################################
1157
+
1158
+ @rem Set local scope for the variables with windows NT shell
1159
+ if "%OS%"=="Windows_NT" setlocal
1160
+
1161
+ set DIRNAME=%~dp0
1162
+ if "%DIRNAME%"=="" set DIRNAME=.
1163
+ @rem This is normally unused
1164
+ set APP_BASE_NAME=%~n0
1165
+ set APP_HOME=%DIRNAME%
1166
+
1167
+ @rem Resolve any "." and ".." in APP_HOME to make it shorter.
1168
+ for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
1169
+
1170
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
1171
+ set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
1172
+
1173
+ @rem Find java.exe
1174
+ if defined JAVA_HOME goto findJavaFromJavaHome
1175
+
1176
+ set JAVA_EXE=java.exe
1177
+ %JAVA_EXE% -version >NUL 2>&1
1178
+ if %ERRORLEVEL% equ 0 goto execute
1179
+
1180
+ echo. 1>&2
1181
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
1182
+ echo. 1>&2
1183
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
1184
+ echo location of your Java installation. 1>&2
1185
+
1186
+ goto fail
1187
+
1188
+ :findJavaFromJavaHome
1189
+ set JAVA_HOME=%JAVA_HOME:"=%
1190
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
1191
+
1192
+ if exist "%JAVA_EXE%" goto execute
1193
+
1194
+ echo. 1>&2
1195
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
1196
+ echo. 1>&2
1197
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
1198
+ echo location of your Java installation. 1>&2
1199
+
1200
+ goto fail
1201
+
1202
+ :execute
1203
+ @rem Setup the command line
1204
+
1205
+ set CLASSPATH=
1206
+
1207
+
1208
+ @rem Execute Gradle
1209
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar" %*
1210
+
1211
+ :end
1212
+ @rem End local scope for the variables with windows NT shell
1213
+ if %ERRORLEVEL% equ 0 goto mainEnd
1214
+
1215
+ :fail
1216
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
1217
+ rem the _cmd.exe /c_ return code!
1218
+ set EXIT_CODE=%ERRORLEVEL%
1219
+ if %EXIT_CODE% equ 0 set EXIT_CODE=1
1220
+ if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
1221
+ exit /b %EXIT_CODE%
1222
+
1223
+ :mainEnd
1224
+ if "%OS%"=="Windows_NT" endlocal
1225
+
1226
+ :omega
1227
+ `;
1228
+ const gradlew = `#!/bin/sh
1229
+
1230
+ #
1231
+ # Copyright © 2015-2021 the original authors.
1232
+ #
1233
+ # Licensed under the Apache License, Version 2.0 (the "License");
1234
+ # you may not use this file except in compliance with the License.
1235
+ # You may obtain a copy of the License at
1236
+ #
1237
+ # https://www.apache.org/licenses/LICENSE-2.0
1238
+ #
1239
+ # Unless required by applicable law or agreed to in writing, software
1240
+ # distributed under the License is distributed on an "AS IS" BASIS,
1241
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1242
+ # See the License for the specific language governing permissions and
1243
+ # limitations under the License.
1244
+ #
1245
+ # SPDX-License-Identifier: Apache-2.0
1246
+ #
1247
+
1248
+ ##############################################################################
1249
+ #
1250
+ # Gradle start up script for POSIX generated by Gradle.
1251
+ #
1252
+ # Important for running:
1253
+ #
1254
+ # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
1255
+ # noncompliant, but you have some other compliant shell such as ksh or
1256
+ # bash, then to run this script, type that shell name before the whole
1257
+ # command line, like:
1258
+ #
1259
+ # ksh Gradle
1260
+ #
1261
+ # Busybox and similar reduced shells will NOT work, because this script
1262
+ # requires all of these POSIX shell features:
1263
+ # * functions;
1264
+ # * expansions «$var», «\${var}», «\${var:-default}», «\${var+SET}»,
1265
+ # «\${var#prefix}», «\${var%suffix}», and «$( cmd )»;
1266
+ # * compound commands having a testable exit status, especially «case»;
1267
+ # * various built-in commands including «command», «set», and «ulimit».
1268
+ #
1269
+ # Important for patching:
1270
+ #
1271
+ # (2) This script targets any POSIX shell, so it avoids extensions provided
1272
+ # by Bash, Ksh, etc; in particular arrays are avoided.
1273
+ #
1274
+ # The "traditional" practice of packing multiple parameters into a
1275
+ # space-separated string is a well documented source of bugs and security
1276
+ # problems, so this is (mostly) avoided, by progressively accumulating
1277
+ # options in "$@", and eventually passing that to Java.
1278
+ #
1279
+ # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
1280
+ # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
1281
+ # see the in-line comments for details.
1282
+ #
1283
+ # There are tweaks for specific operating systems such as AIX, CygWin,
1284
+ # Darwin, MinGW, and NonStop.
1285
+ #
1286
+ # (3) This script is generated from the Groovy template
1287
+ # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
1288
+ # within the Gradle project.
1289
+ #
1290
+ # You can find Gradle at https://github.com/gradle/gradle/.
1291
+ #
1292
+ ##############################################################################
1293
+
1294
+ # Attempt to set APP_HOME
1295
+
1296
+ # Resolve links: $0 may be a link
1297
+ app_path=$0
1298
+
1299
+ # Need this for daisy-chained symlinks.
1300
+ while
1301
+ APP_HOME=\${app_path%"\${app_path##*/}"} # leaves a trailing /; empty if no leading path
1302
+ [ -h "$app_path" ]
1303
+ do
1304
+ ls=$( ls -ld "$app_path" )
1305
+ link=\${ls#*' -> '}
1306
+ case $link in #(
1307
+ /*) app_path=$link ;; #(
1308
+ *) app_path=$APP_HOME$link ;;
1309
+ esac
1310
+ done
1311
+
1312
+ # This is normally unused
1313
+ # shellcheck disable=SC2034
1314
+ APP_BASE_NAME=\${0##*/}
1315
+ # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
1316
+ APP_HOME=$( cd -P "\${APP_HOME:-./}" > /dev/null && printf '%s\\n' "$PWD" ) || exit
1317
+
1318
+ # Use the maximum available, or set MAX_FD != -1 to use that value.
1319
+ MAX_FD=maximum
1320
+
1321
+ warn () {
1322
+ echo "$*"
1323
+ } >&2
1324
+
1325
+ die () {
1326
+ echo
1327
+ echo "$*"
1328
+ echo
1329
+ exit 1
1330
+ } >&2
1331
+
1332
+ # OS specific support (must be 'true' or 'false').
1333
+ cygwin=false
1334
+ msys=false
1335
+ darwin=false
1336
+ nonstop=false
1337
+ case "$( uname )" in #(
1338
+ CYGWIN* ) cygwin=true ;; #(
1339
+ Darwin* ) darwin=true ;; #(
1340
+ MSYS* | MINGW* ) msys=true ;; #(
1341
+ NONSTOP* ) nonstop=true ;;
1342
+ esac
1343
+
1344
+ CLASSPATH="\\\\\\"\\\\\\""
1345
+
1346
+
1347
+ # Determine the Java command to use to start the JVM.
1348
+ if [ -n "$JAVA_HOME" ] ; then
1349
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
1350
+ # IBM's JDK on AIX uses strange locations for the executables
1351
+ JAVACMD=$JAVA_HOME/jre/sh/java
1352
+ else
1353
+ JAVACMD=$JAVA_HOME/bin/java
1354
+ fi
1355
+ if [ ! -x "$JAVACMD" ] ; then
1356
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
1357
+
1358
+ Please set the JAVA_HOME variable in your environment to match the
1359
+ location of your Java installation."
1360
+ fi
1361
+ else
1362
+ JAVACMD=java
1363
+ if ! command -v java >/dev/null 2>&1
1364
+ then
1365
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
1366
+
1367
+ Please set the JAVA_HOME variable in your environment to match the
1368
+ location of your Java installation."
1369
+ fi
1370
+ fi
1371
+
1372
+ # Increase the maximum file descriptors if we can.
1373
+ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
1374
+ case $MAX_FD in #(
1375
+ max*)
1376
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
1377
+ # shellcheck disable=SC2039,SC3045
1378
+ MAX_FD=$( ulimit -H -n ) ||
1379
+ warn "Could not query maximum file descriptor limit"
1380
+ esac
1381
+ case $MAX_FD in #(
1382
+ '' | soft) :;; #(
1383
+ *)
1384
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
1385
+ # shellcheck disable=SC2039,SC3045
1386
+ ulimit -n "$MAX_FD" ||
1387
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
1388
+ esac
1389
+ fi
1390
+
1391
+ # Collect all arguments for the java command, stacking in reverse order:
1392
+ # * args from the command line
1393
+ # * the main class name
1394
+ # * -classpath
1395
+ # * -D...appname settings
1396
+ # * --module-path (only if needed)
1397
+ # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
1398
+
1399
+ # For Cygwin or MSYS, switch paths to Windows format before running java
1400
+ if "$cygwin" || "$msys" ; then
1401
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
1402
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
1403
+
1404
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
1405
+
1406
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
1407
+ for arg do
1408
+ if
1409
+ case $arg in #(
1410
+ -*) false ;; # don't mess with options #(
1411
+ /?*) t=\${arg#/} t=/\${t%%/*} # looks like a POSIX filepath
1412
+ [ -e "$t" ] ;; #(
1413
+ *) false ;;
1414
+ esac
1415
+ then
1416
+ arg=$( cygpath --path --ignore --mixed "$arg" )
1417
+ fi
1418
+ # Roll the args list around exactly as many times as the number of
1419
+ # args, so each arg winds up back in the position where it started, but
1420
+ # possibly modified.
1421
+ #
1422
+ # NB: a \`for\` loop captures its iteration list before it begins, so
1423
+ # changing the positional parameters here affects neither the number of
1424
+ # iterations, nor the values presented in \`arg\`.
1425
+ shift # remove old arg
1426
+ set -- "$@" "$arg" # push replacement arg
1427
+ done
1428
+ fi
1429
+
1430
+
1431
+ # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
1432
+ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
1433
+
1434
+ # Collect all arguments for the java command:
1435
+ # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
1436
+ # and any embedded shellness will be escaped.
1437
+ # * For example: A user cannot expect \${Hostname} to be expanded, as it is an environment variable and will be
1438
+ # treated as '\${Hostname}' itself on the command line.
1439
+
1440
+ set -- \\
1441
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \\
1442
+ -classpath "$CLASSPATH" \\
1443
+ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \\
1444
+ "$@"
1445
+
1446
+ # Stop when "xargs" is not available.
1447
+ if ! command -v xargs >/dev/null 2>&1
1448
+ then
1449
+ die "xargs is not available"
1450
+ fi
1451
+
1452
+ # Use "xargs" to parse quoted args.
1453
+ #
1454
+ # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
1455
+ #
1456
+ # In Bash we could simply go:
1457
+ #
1458
+ # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
1459
+ # set -- "\${ARGS[@]}" "$@"
1460
+ #
1461
+ # but POSIX shell has neither arrays nor command substitution, so instead we
1462
+ # post-process each arg (as a line of input to sed) to backslash-escape any
1463
+ # character that might be a shell metacharacter, then use eval to reverse
1464
+ # that process (while maintaining the separation between arguments), and wrap
1465
+ # the whole thing up as a single "set" statement.
1466
+ #
1467
+ # This will of course break if any of these variables contains a newline or
1468
+ # an unmatched quote.
1469
+ #
1470
+
1471
+ eval "set -- $(
1472
+ printf '%s\\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
1473
+ xargs -n1 |
1474
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |
1475
+ tr '\\n' ' '
1476
+ )" '"$@"'
1477
+
1478
+ exec "$JAVACMD" "$@"
1479
+ `;
1480
+ function scaffoldGradleWrapper(_schematic, data) {
1481
+ kformScaffolder.addTemplateFile(data, "gradlew", gradlew, { executable: true });
1482
+ kformScaffolder.addTemplateFile(data, "gradlew.bat", gradlewBat);
1483
+ kformScaffolder.addTemplateFile(data, "gradle/wrapper/gradle-wrapper.jar", gradleWrapperJar, {
1484
+ base64: true
1485
+ });
1486
+ kformScaffolder.addTemplateFile(
1487
+ data,
1488
+ "gradle/wrapper/gradle-wrapper.properties",
1489
+ gradleWrapperProperties
1490
+ );
1491
+ }
1492
+ function scaffoldMain(schematic, data) {
1493
+ const fileName = kformScaffolder.joinPaths(data.currentDir, "main.tsx");
1494
+ let file = data.files.get(fileName);
1495
+ if (!file) {
1496
+ data.files.set(fileName, file = kformScaffolder.tsFile());
1497
+ }
1498
+ scaffoldMainFile(schematic, {
1499
+ kmpModuleName: `${kebabCase(schematic.name)}-shared`,
1500
+ ...data,
1501
+ currentFile: file
1502
+ });
1503
+ }
1504
+ function scaffoldMainFile(schematic, data) {
1505
+ data.currentFile.imports.push(
1506
+ { moduleName: "./index.scss" },
1507
+ { moduleName: "react-router-dom", name: "createHashRouter" }
1508
+ );
1509
+ data.currentFile.declarations.push(
1510
+ `const router = createHashRouter([${scaffoldRouteObject(schematic, data)}]);`
1511
+ );
1512
+ data.currentFile.imports.push(
1513
+ { moduleName: "react-dom/client", name: "createRoot" },
1514
+ { moduleName: "react", name: "StrictMode" },
1515
+ { moduleName: "react-router-dom", name: "RouterProvider" },
1516
+ {
1517
+ moduleName: data.kmpModuleName,
1518
+ name: `decode${schematic.name}ExternalContextsFromString`
1519
+ },
1520
+ {
1521
+ moduleName: `./${schematic.name}Context.ts`,
1522
+ name: `${schematic.name}Context`
1523
+ }
1524
+ );
1525
+ data.currentFile.declarations.push(kformScaffolder.code`
1526
+ declare global {
1527
+ function render${schematic.name}App(): void;
1528
+ }
1529
+ globalThis.render${schematic.name}App = () => {
1530
+ const root = document.getElementById("${kebabCase(schematic.name)}-app-root")!;
1531
+ const externalContexts = decode${schematic.name}ExternalContextsFromString(
1532
+ root.dataset.externalContexts!,
1533
+ );
1534
+
1535
+ createRoot(root).render(
1536
+ <StrictMode>
1537
+ <${schematic.name}Context.Provider value={{ externalContexts }}>
1538
+ <RouterProvider router={router} />
1539
+ </${schematic.name}Context.Provider>
1540
+ </StrictMode>,
1541
+ );
1542
+ };
1543
+ `);
1544
+ }
1545
+ function scaffoldRouteObject(schematic, data) {
1546
+ const layout = reactAppLayout(schematic, data);
1547
+ const formPages = layout.flatMap((annex) => annex.formPages);
1548
+ data.currentFile.imports.push({
1549
+ moduleName: `./${schematic.name}App.tsx`,
1550
+ name: `${schematic.name}App`
1551
+ });
1552
+ for (const formPage of formPages) {
1553
+ data.currentFile.imports.push({
1554
+ moduleName: `./${kformScaffolder.joinPaths(
1555
+ formPage.data.currentDir.slice(
1556
+ data.currentDir.length + (data.currentDir.endsWith("/") ? 0 : 1)
1557
+ ),
1558
+ pascalCase(formPage.schematic.name)
1559
+ )}.tsx`,
1560
+ name: pascalCase(formPage.schematic.name)
1561
+ });
1562
+ }
1563
+ const firstFormPage = formPages.find(
1564
+ (formPage) => !formPage.schematic.nullable && !formPage.data.currentPath.split("/").includes("*")
1565
+ );
1566
+ const routes = [
1567
+ firstFormPage && `{ path: "*", element: <${pascalCase(firstFormPage.schematic.name)} /> }`,
1568
+ ...formPages.filter((formPage) => formPage !== firstFormPage).map(
1569
+ (formPage) => `{ path: "${formPage.data.currentPath.split("/").map((f) => f === "*" ? ":id" : f).join(
1570
+ "/"
1571
+ )}", element: <${pascalCase(formPage.schematic.name)} /> }`
1572
+ )
1573
+ ];
1574
+ return kformScaffolder.code`
1575
+ {
1576
+ element: <${schematic.name}App />,
1577
+ children: [
1578
+ ${routes.filter((r) => r).join(",\n")}
1579
+ ]
1580
+ }
1581
+ `;
1582
+ }
1583
+ const editorconfig = "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[{*.kt,*.kts,*.md}]\nindent_size = 4\nmax_line_length = 100\n\n[{*.js,*.jsx,*.ts,*.tsx,*.json,*.html,*.css,*.scss,*.toml}]\nindent_size = 2\nmax_line_length = 80";
1584
+ const gitignore = "# Gradle\n.gradle/\nbuild/\n!**/src/**/build/\n\n# Kotlin\n.kotlin/\n\n# Node.js\nnode_modules/\n.npmrc\n\n# Typescript\n*.tsbuildinfo\n\n# Local env files\n.env*.local\n\n# Logs\nlogs\n*.log\n\n# IDEs and editors\n.vscode/\n.idea/\n.project\n.classpath\n.c9/\n*.launch\n.settings/\n*.sublime-workspace\nout/\n!**/src/**/out/\n\n# Misc\n.DS_Store\n*.pem\n";
1585
+ function scaffoldProjectMisc(_schematic, data) {
1586
+ kformScaffolder.addTemplateFile(data, ".gitignore", gitignore);
1587
+ kformScaffolder.addTemplateFile(data, ".editorconfig", editorconfig);
1588
+ }
1589
+ const responsesKt = 'package <%= filePackage %>\n\nimport io.kform.LocatedValidationIssue\nimport kotlin.js.JsExport\nimport kotlin.jvm.JvmOverloads\nimport kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@JsExport\n@Serializable\nsealed interface <%= formClass %>SubmitResponse\n\n@JsExport\n@Serializable\n@SerialName("success")\nclass <%= formClass %>SubmitSuccess(val redirectTo: String) : <%= formClass %>SubmitResponse\n\n@JsExport\n@Serializable\n@SerialName("error")\nclass <%= formClass %>SubmitError @JvmOverloads constructor(override val message: String? = null) :\n Throwable(message), <%= formClass %>SubmitResponse\n\n@JsExport\n@Serializable\n@SerialName("validationError")\nclass <%= formClass %>SubmitValidationError(val issues: List<LocatedValidationIssue>) :\n <%= formClass %>SubmitResponse\n';
1590
+ function scaffoldResponses(schematic, data) {
1591
+ const ejsData = {
1592
+ filePackage: data.currentPackage,
1593
+ formClass: schematic.name
1594
+ };
1595
+ kformScaffolder.addEjsTemplateFile(
1596
+ data,
1597
+ `${schematic.name}Responses.kt`,
1598
+ responsesKt,
1599
+ ejsData
1600
+ );
1601
+ }
1602
+ const jsonSerializerKt = "package <%= filePackage %>\n\nimport kotlin.js.JsExport\nimport kotlin.jvm.JvmOverloads\nimport kotlinx.serialization.json.Json\n\n/** Base JSON configuration. */\nprivate val JSON_CONFIG = Json.Default\n/** Pretty JSON configuration. */\nprivate val JSON_CONFIG_PRETTY = Json(JSON_CONFIG) { prettyPrint = true }\n\n/** JSON configuration. */\n@JvmOverloads\nfun jsonConfig(prettyPrint: Boolean = false): Json =\n if (prettyPrint) JSON_CONFIG_PRETTY else JSON_CONFIG\n\n/** Version of the serialization format. */\n@JsExport\nconst val <%= formConstant %>_SERIALIZATION_VERSION = 1\n\n@JsExport\n@JvmOverloads\nfun encode<%= formClass %>ToString(<%= formVar %>: <%= formClass %>, prettyPrint: Boolean = false): String =\n jsonConfig(prettyPrint).encodeToString(<%= formVar %>)\n\n@JsExport\nfun decode<%= formClass %>FromString(json: String): <%= formClass %> =\n jsonConfig().decodeFromString(json)\n\n@JvmOverloads\nfun encode<%= formClass %>ExternalContextsToString(externalContexts: <%= formClass %>ExternalContexts, prettyPrint: Boolean = false): String =\n jsonConfig(prettyPrint).encodeToString(externalContexts)\n\n@JsExport\nfun decode<%= formClass %>ExternalContextsFromString(json: String): <%= formClass %>ExternalContexts =\n jsonConfig().decodeFromString(json)\n\n@JvmOverloads\nfun encode<%= formClass %>SubmitResponseToString(response: <%= formClass %>SubmitResponse, prettyPrint: Boolean = false): String =\n jsonConfig(prettyPrint).encodeToString(response)\n\n@JsExport\nfun decode<%= formClass %>SubmitResponseFromString(json: String): <%= formClass %>SubmitResponse =\n jsonConfig().decodeFromString(json)\n";
1603
+ const xmlSerializerKt = "package <%= filePackage %>\n\nimport kotlin.js.JsExport\nimport kotlin.jvm.JvmOverloads\nimport kotlinx.serialization.decodeFromString\nimport kotlinx.serialization.encodeToString\nimport nl.adaptivity.xmlutil.ExperimentalXmlUtilApi\nimport nl.adaptivity.xmlutil.QName\nimport nl.adaptivity.xmlutil.XMLConstants\nimport nl.adaptivity.xmlutil.core.XmlVersion\nimport nl.adaptivity.xmlutil.serialization.DefaultXmlSerializationPolicy\nimport nl.adaptivity.xmlutil.serialization.OutputKind\nimport nl.adaptivity.xmlutil.serialization.XML\nimport nl.adaptivity.xmlutil.serialization.XmlSerializationPolicy\nimport nl.adaptivity.xmlutil.serialization.structure.SafeParentInfo\n\n/** Base XML configuration. */\nprivate val XML_CONFIG = XML {\n recommended_0_91_0 {\n xmlVersion = XmlVersion.XML10\n autoPolymorphic = false\n encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER\n }\n\n // Set policy on top of the current policy config\n @OptIn(ExperimentalXmlUtilApi::class)\n policy =\n object : DefaultXmlSerializationPolicy(policy) {\n // Serialize properties as elements instead of attributes by default\n override val defaultPrimitiveOutputKind: OutputKind = OutputKind.Element\n\n // Use property names as serial names by default\n override fun effectiveName(\n serializerParent: SafeParentInfo,\n tagParent: SafeParentInfo,\n outputKind: OutputKind,\n useName: XmlSerializationPolicy.DeclaredNameInfo,\n ): QName =\n useName.annotatedName\n ?: serializerParent.elementTypeDescriptor.typeQname\n ?: QName(\n if (outputKind == OutputKind.Element) tagParent.namespace.namespaceURI\n else XMLConstants.NULL_NS_URI,\n useName.serialName,\n )\n }\n}\n/** Pretty XML configuration. */\nprivate val XML_CONFIG_PRETTY = XML_CONFIG.copy { indent = 4 }\n\n/** XML configuration. */\n@JvmOverloads\nfun xmlConfig(prettyPrint: Boolean = false): XML =\n if (prettyPrint) XML_CONFIG_PRETTY else XML_CONFIG\n\n/** Version of the serialization format. */\n@JsExport\nconst val <%= formConstant %>_SERIALIZATION_VERSION = 1\n\n@JsExport\n@JvmOverloads\nfun encode<%= formClass %>ToString(<%= formVar %>: <%= formClass %>, prettyPrint: Boolean = false): String =\n xmlConfig(prettyPrint).encodeToString(<%= formVar %>)\n\n@JsExport\nfun decode<%= formClass %>FromString(xml: String): <%= formClass %> =\n xmlConfig().decodeFromString(xml)\n\n@JvmOverloads\nfun encode<%= formClass %>ExternalContextsToString(externalContexts: <%= formClass %>ExternalContexts, prettyPrint: Boolean = false): String =\n xmlConfig(prettyPrint).encodeToString(externalContexts)\n\n@JsExport\nfun decode<%= formClass %>ExternalContextsFromString(xml: String): <%= formClass %>ExternalContexts =\n xmlConfig().decodeFromString(xml)\n\n@JvmOverloads\nfun encode<%= formClass %>SubmitResponseToString(response: <%= formClass %>SubmitResponse, prettyPrint: Boolean = false): String =\n xmlConfig(prettyPrint).encodeToString(response)\n\n@JsExport\nfun decode<%= formClass %>SubmitResponseFromString(xml: String): <%= formClass %>SubmitResponse =\n xmlConfig().decodeFromString(xml)\n";
1604
+ function scaffoldSerializer(schematic, data) {
1605
+ const ejsData = {
1606
+ filePackage: data.currentPackage,
1607
+ formVar: camelCase(schematic.name),
1608
+ formClass: schematic.name,
1609
+ formConstant: constantCase(schematic.name)
1610
+ };
1611
+ kformScaffolder.addEjsTemplateFile(
1612
+ data,
1613
+ `${schematic.name}Serializer.kt`,
1614
+ data.serializationFormat === "xml" ? xmlSerializerKt : jsonSerializerKt,
1615
+ ejsData
1616
+ );
1617
+ }
1618
+ const indexScss = '@use "@ostack.tech/ui/scss" as ostack-ui;\n@use "@ostack.tech/ui-kform/scss" as ostack-ui-kform;\n';
1619
+ function scaffoldStyles(_schematic, data) {
1620
+ kformScaffolder.addTemplateFile(data, "index.scss", indexScss);
1621
+ }
1622
+ const eslintConfigJs = 'import js from "@eslint/js";\nimport { defineConfig, globalIgnores } from "eslint/config";\nimport reactHooks from "eslint-plugin-react-hooks";\nimport reactRefresh from "eslint-plugin-react-refresh";\nimport globals from "globals";\nimport tseslint from "typescript-eslint";\n\nexport default defineConfig([\n globalIgnores([".gradle", "build"]),\n {\n files: ["**/*.{ts,tsx}"],\n extends: [\n js.configs.recommended,\n tseslint.configs.recommended,\n reactHooks.configs["recommended-latest"],\n reactRefresh.configs.vite,\n ],\n languageOptions: {\n ecmaVersion: 2020,\n globals: globals.browser,\n },\n },\n]);\n';
1623
+ const indexHtmlEjs = '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <link rel="icon" type="image/svg+xml" href="/vite.svg" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title><%= formTitle %></title>\n </head>\n <body>\n <div\n id="<%= formId %>-app-root"\n data-external-contexts="<%= externalContextsData %>"\n ></div>\n <script type="module" src="/src/main.tsx"><\/script>\n <script type="module">\n render<%= formClass %>App();\n <\/script>\n </body>\n</html>\n';
1624
+ const packageJsonEjs = '{\n "name": "<%= formId %>-react-app",\n "private": true,\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "tsc -b && vite build",\n "lint": "eslint .",\n "preview": "vite preview"\n },\n "dependencies": {\n "@fortawesome/fontawesome-svg-core": "<%= dependencyVersions["@fortawesome/fontawesome-svg-core"] %>",\n "@fortawesome/free-regular-svg-icons": "<%= dependencyVersions["@fortawesome/free-regular-svg-icons"] %>",\n "@fortawesome/free-solid-svg-icons": "<%= dependencyVersions["@fortawesome/free-solid-svg-icons"] %>",\n "@ostack.tech/kform-react": "~<%= kFormVersion %>",\n "@ostack.tech/ui": "~<%= ostackUiVersion %>",\n "@ostack.tech/ui-kform": "~<%= ostackUiVersion %>",\n "date-fns": "<%= dependencyVersions["date-fns"] %>",\n "<%= formId %>-shared": "file:../shared/build/<%= formId %>-shared-0.0.1.tgz",\n "react": "<%= dependencyVersions.react %>",\n "react-dom": "<%= dependencyVersions["react-dom"] %>",\n "react-router": "<%= dependencyVersions["react-router"] %>",\n "react-router-dom": "<%= dependencyVersions["react-router-dom"] %>"\n },\n "devDependencies": {\n "@eslint/js": "<%= dependencyVersions["@eslint/js"] %>",\n "@types/node": "<%= dependencyVersions["@types/node"] %>",\n "@types/ostack.tech__kform": "npm:@ostack.tech/kform@~<%= kFormVersion %>",\n "@types/react": "<%= dependencyVersions["@types/react"] %>",\n "@types/react-dom": "<%= dependencyVersions["@types/react-dom"] %>",\n "@vitejs/plugin-react-swc": "<%= dependencyVersions["@vitejs/plugin-react-swc"] %>",\n "eslint": "<%= dependencyVersions.eslint %>",\n "eslint-plugin-react-hooks": "<%= dependencyVersions["eslint-plugin-react-hooks"] %>",\n "eslint-plugin-react-refresh": "<%= dependencyVersions["eslint-plugin-react-refresh"] %>",\n "globals": "<%= dependencyVersions.globals %>",\n "sass-embedded": "<%= dependencyVersions["sass-embedded"] %>",\n "typescript": "<%= dependencyVersions.typescript %>",\n "typescript-eslint": "<%= dependencyVersions["typescript-eslint"] %>",\n "vite": "<%= dependencyVersions.vite %>"\n }\n}\n';
1625
+ const viteSvg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>\n';
1626
+ const tsConfigAppJson = '{\n "compilerOptions": {\n "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",\n "target": "ES2022",\n "useDefineForClassFields": true,\n "lib": ["ES2022", "DOM", "DOM.Iterable"],\n "module": "ESNext",\n "types": ["vite/client"],\n "skipLibCheck": true,\n\n /* Bundler mode */\n "moduleResolution": "bundler",\n "allowImportingTsExtensions": true,\n "verbatimModuleSyntax": true,\n "moduleDetection": "force",\n "noEmit": true,\n "jsx": "react-jsx",\n\n /* Linting */\n "strict": true,\n "noUnusedLocals": true,\n "noUnusedParameters": true,\n "erasableSyntaxOnly": true,\n "noFallthroughCasesInSwitch": true,\n "noUncheckedSideEffectImports": true\n },\n "include": ["src"]\n}\n';
1627
+ const tsConfigJson = '{\n "files": [],\n "references": [\n { "path": "./tsconfig.app.json" },\n { "path": "./tsconfig.node.json" }\n ]\n}\n';
1628
+ const tsConfigNodeJson = '{\n "compilerOptions": {\n "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",\n "target": "ES2023",\n "lib": ["ES2023"],\n "module": "ESNext",\n "types": ["node"],\n "skipLibCheck": true,\n\n /* Bundler mode */\n "moduleResolution": "bundler",\n "allowImportingTsExtensions": true,\n "verbatimModuleSyntax": true,\n "moduleDetection": "force",\n "noEmit": true,\n\n /* Linting */\n "strict": true,\n "noUnusedLocals": true,\n "noUnusedParameters": true,\n "erasableSyntaxOnly": true,\n "noFallthroughCasesInSwitch": true,\n "noUncheckedSideEffectImports": true\n },\n "include": ["vite.config.ts"]\n}\n';
1629
+ const viteConfigTsEjs = 'import path from "node:path";\n\nimport react from "@vitejs/plugin-react-swc";\nimport { defineConfig } from "vite";\n\n// https://vite.dev/config/\nexport default defineConfig({\n plugins: [react()],\n build: {\n outDir: "build/dist",\n rollupOptions: {\n input: {\n "<%= formId %>-app":\n process.env.VITE_BUILD_REASON === "preview"\n ? "index.html"\n : "src/main.tsx",\n },\n output: {\n // Output files without hashes, making it easier to serve them in the\n // server. However, the server is expected to somehow "version" them for\n // cache busting purposes.\n entryFileNames: `assets/[name].js`,\n chunkFileNames: `assets/[name].js`,\n assetFileNames: `assets/[name].[ext]`,\n },\n },\n },\n resolve: {\n alias: [\n // Due to how Kotlin "bundles" dependencies, we need to use the\n // `@ostack.tech/kform` produced by the shared module.\n {\n find: "@ostack.tech/kform",\n replacement: path.resolve(\n import.meta.dirname,\n `node_modules/<%= formId %>-shared/ostack-kform.mjs`,\n ),\n },\n ],\n },\n server: {\n proxy: { "/api": "http://127.0.0.1:8080" },\n },\n});\n';
1630
+ function scaffoldViteProject(schematic, data) {
1631
+ const ejsData = {
1632
+ formId: kebabCase(schematic.name),
1633
+ formClass: schematic.name,
1634
+ formTitle: capitalCase(schematic.name),
1635
+ ostackUiVersion: "0.1.0",
1636
+ kFormVersion: "0.31.0",
1637
+ dependencyVersions: JSON.parse('{"@eslint/js":"^9.37.0","@fortawesome/fontawesome-svg-core":"^7.1.0","@fortawesome/free-brands-svg-icons":"^7.1.0","@fortawesome/free-regular-svg-icons":"^7.1.0","@fortawesome/free-solid-svg-icons":"^7.1.0","@ostack.tech/kform":"~0.31.0","@ostack.tech/kform-react":"~0.31.0","@ostack.tech/kform-scaffolder":"~0.31.0","@storybook/addon-docs":"^9.1.10","@storybook/addon-links":"^9.1.10","@storybook/react-vite":"^9.1.10","@types/node":"^22.18.9","@types/react":"^19.2.2","@types/react-dom":"^19.2.1","@vitejs/plugin-react-swc":"^4.1.0","colorjs.io":"^0.5.2","cpy-cli":"^6.0.0","date-fns":"^4.1.0","eslint":"^9.37.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","eslint-plugin-react-hooks":"^6.1.1","eslint-plugin-react-refresh":"^0.4.23","eslint-plugin-simple-import-sort":"^12.1.1","eslint-plugin-storybook":"^9.1.10","globals":"^16.4.0","happy-dom":"^20.0.0","http-server":"^14.1.1","lint-staged":"^16.2.3","prettier":"^3.6.2","prettier-plugin-jsdoc":"^1.3.3","react":"^19.2.0","react-dom":"^19.2.0","react-router":"^7.9.4","react-router-dom":"^7.9.4","rimraf":"^6.0.1","sass-embedded":"^1.93.2","simple-git-hooks":"^2.13.1","storybook":"^9.1.10","tslib":"^2.8.1","typescript":"~5.9.3","typescript-eslint":"^8.46.0","vite":"^7.1.9","vitest":"^3.2.4","zustand":"^5.0.8"}'),
1638
+ externalContextsData: data.serializationFormat === "json" ? "{}" : `<${schematic.name}ExternalContexts />`
1639
+ };
1640
+ kformScaffolder.addEjsTemplateFile(data, "react-app/package.json", packageJsonEjs, ejsData);
1641
+ kformScaffolder.addEjsTemplateFile(
1642
+ data,
1643
+ "react-app/vite.config.ts",
1644
+ viteConfigTsEjs,
1645
+ ejsData
1646
+ );
1647
+ kformScaffolder.addTemplateFile(data, "react-app/tsconfig.json", tsConfigJson);
1648
+ kformScaffolder.addTemplateFile(data, "react-app/tsconfig.app.json", tsConfigAppJson);
1649
+ kformScaffolder.addTemplateFile(data, "react-app/tsconfig.node.json", tsConfigNodeJson);
1650
+ kformScaffolder.addTemplateFile(data, "react-app/eslint.config.js", eslintConfigJs);
1651
+ kformScaffolder.addEjsTemplateFile(data, "react-app/index.html", indexHtmlEjs, ejsData);
1652
+ kformScaffolder.addTemplateFile(data, "react-app/public/vite.svg", viteSvg);
1653
+ }
1654
+ const kotlinMainData = {
1655
+ currentDir: "shared/src/commonMain/kotlin"
1656
+ };
1657
+ const kotlinTestData = {
1658
+ currentDir: "shared/src/commonTest/kotlin"
1659
+ };
1660
+ const reactAppData = {
1661
+ currentDir: "react-app/src"
1662
+ };
1663
+ function SchematicBuilder({
1664
+ name = "ostack-ui-kform",
1665
+ schematicKinds = defaultSchematicKinds,
1666
+ scaffolders = [
1667
+ scaffoldProjectMisc,
1668
+ scaffoldGradleWrapper,
1669
+ scaffoldGradleProject,
1670
+ scaffoldViteProject,
1671
+ kformScaffolder.configScaffolder(kformScaffolder.scaffoldSchemas, kotlinMainData),
1672
+ kformScaffolder.configScaffolder(kformScaffolder.scaffoldModels, kotlinMainData),
1673
+ kformScaffolder.configScaffolder(scaffoldResponses, kotlinMainData),
1674
+ kformScaffolder.configScaffolder(scaffoldExternalContexts, kotlinMainData),
1675
+ kformScaffolder.configScaffolder(scaffoldSerializer, kotlinMainData),
1676
+ kformScaffolder.configScaffolder(kformScaffolder.scaffoldValidator, kotlinTestData),
1677
+ kformScaffolder.configScaffolder(scaffoldMain, reactAppData),
1678
+ kformScaffolder.configScaffolder(scaffoldStyles, reactAppData),
1679
+ kformScaffolder.configScaffolder(scaffoldAppComponent, reactAppData),
1680
+ kformScaffolder.configScaffolder(scaffoldAppContext, reactAppData),
1681
+ kformScaffolder.configScaffolder(scaffoldActions, reactAppData),
1682
+ kformScaffolder.configScaffolder(scaffoldApi, reactAppData),
1683
+ kformScaffolder.configScaffolder(scaffoldFormPages, reactAppData)
1684
+ ],
1685
+ scaffoldingData = (schematic) => ({
1686
+ useFileBase64Serializer: true,
1687
+ ...schematic.config
1688
+ }),
1689
+ configs = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1690
+ /* @__PURE__ */ jsxRuntime.jsx(SerializationFormatConfig, {}),
1691
+ /* @__PURE__ */ jsxRuntime.jsx(UseTableValuesSerializerConfig, {})
1692
+ ] }),
1693
+ ...otherProps
1694
+ }) {
1695
+ return /* @__PURE__ */ jsxRuntime.jsx(
1696
+ kformScaffolder.SchematicBuilder,
1697
+ {
1698
+ name,
1699
+ schematicKinds,
1700
+ scaffolders,
1701
+ scaffoldingData,
1702
+ configs,
1703
+ ...otherProps
1704
+ }
1705
+ );
1706
+ }
1707
+ exports.SchematicBuilder = SchematicBuilder;
1708
+ exports.SerializationFormatConfig = SerializationFormatConfig;
1709
+ exports.UseTableValuesSerializerConfig = UseTableValuesSerializerConfig;
1710
+ exports.anySchematicKind = anySchematicKind;
1711
+ exports.bigDecimalSchematicKind = bigDecimalSchematicKind;
1712
+ exports.bigIntegerSchematicKind = bigIntegerSchematicKind;
1713
+ exports.booleanSchematicKind = booleanSchematicKind;
1714
+ exports.byteSchematicKind = byteSchematicKind;
1715
+ exports.classAnnexSchematicKind = classAnnexSchematicKind;
1716
+ exports.classFormPageSchematicKind = classFormPageSchematicKind;
1717
+ exports.classSchematicKind = classSchematicKind;
1718
+ exports.defaultSchematicKinds = defaultSchematicKinds;
1719
+ exports.doubleSchematicKind = doubleSchematicKind;
1720
+ exports.enumRadioGroupSchematicKind = enumRadioGroupSchematicKind;
1721
+ exports.enumSchematicKind = enumSchematicKind;
1722
+ exports.enumSelectSchematicKind = enumSelectSchematicKind;
1723
+ exports.fileSchematicKind = fileSchematicKind;
1724
+ exports.floatSchematicKind = floatSchematicKind;
1725
+ exports.intSchematicKind = intSchematicKind;
1726
+ exports.listCheckboxGroupSchematicKind = listCheckboxGroupSchematicKind;
1727
+ exports.listSelectMultipleSchematicKind = listSelectMultipleSchematicKind;
1728
+ exports.localDateSchematicKind = localDateSchematicKind;
1729
+ exports.longSchematicKind = longSchematicKind;
1730
+ exports.reactAppLayout = reactAppLayout;
1731
+ exports.scaffoldActions = scaffoldActions;
1732
+ exports.scaffoldAnnexesArray = scaffoldAnnexesArray;
1733
+ exports.scaffoldApi = scaffoldApi;
1734
+ exports.scaffoldAppComponent = scaffoldAppComponent;
1735
+ exports.scaffoldAppContext = scaffoldAppContext;
1736
+ exports.scaffoldExternalContexts = scaffoldExternalContexts;
1737
+ exports.scaffoldField = scaffoldField;
1738
+ exports.scaffoldFormPages = scaffoldFormPages;
1739
+ exports.scaffoldFormPagesByAnnexObject = scaffoldFormPagesByAnnexObject;
1740
+ exports.scaffoldGradleProject = scaffoldGradleProject;
1741
+ exports.scaffoldGradleWrapper = scaffoldGradleWrapper;
1742
+ exports.scaffoldIssueMessages = scaffoldIssueMessages;
1743
+ exports.scaffoldMain = scaffoldMain;
1744
+ exports.scaffoldProjectMisc = scaffoldProjectMisc;
1745
+ exports.scaffoldResponses = scaffoldResponses;
1746
+ exports.scaffoldRouteObject = scaffoldRouteObject;
1747
+ exports.scaffoldSerializer = scaffoldSerializer;
1748
+ exports.scaffoldStyles = scaffoldStyles;
1749
+ exports.scaffoldViteProject = scaffoldViteProject;
1750
+ exports.shortSchematicKind = shortSchematicKind;
1751
+ exports.stringSchematicKind = stringSchematicKind;
1752
+ exports.tableAnnexesSchematicKind = tableAnnexesSchematicKind;
1753
+ exports.tableSchematicKind = tableSchematicKind;
1754
+ //# sourceMappingURL=ostack-ui-kform-scaffolder.cjs.map