@sealcode/sealgen 0.15.35 → 0.15.36

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 (85) hide show
  1. package/.xunit +59 -57
  2. package/@types/src/forms/controls/form-control.d.ts +2 -1
  3. package/@types/src/forms/controls/table.d.ts +31 -4
  4. package/@types/src/forms/fields/table.d.ts +4 -2
  5. package/@types/src/templates/form.d.ts +5 -0
  6. package/@types/src/templates/shared/collection-create-form.d.ts +0 -2
  7. package/@types/src/templates/shared/handlers/boolean.d.ts +2 -0
  8. package/@types/src/templates/shared/handlers/date.d.ts +2 -0
  9. package/@types/src/templates/shared/handlers/deep-reverse-single-reference.d.ts +2 -0
  10. package/@types/src/templates/shared/handlers/default.d.ts +2 -0
  11. package/@types/src/templates/shared/handlers/enum.d.ts +2 -0
  12. package/@types/src/templates/shared/handlers/file.d.ts +2 -0
  13. package/@types/src/templates/shared/handlers/image.d.ts +2 -0
  14. package/@types/src/templates/shared/handlers/int.d.ts +2 -0
  15. package/@types/src/templates/shared/handlers/jdd.d.ts +2 -0
  16. package/@types/src/templates/shared/handlers/single-reference.d.ts +2 -0
  17. package/@types/src/templates/shared/handlers/structured-array.d.ts +2 -0
  18. package/@types/src/templates/shared/shared-crud-form-fields.d.ts +29 -6
  19. package/@types/src/utils/extract-fields-from-collection.d.ts +12 -2
  20. package/@types/src/utils/with-fallback.d.ts +1 -1
  21. package/lib/add-crud.js +5 -5
  22. package/lib/cli.js +2 -0
  23. package/lib/forms/controls/form-control.js +2 -2
  24. package/lib/forms/controls/multiple-photos.js +2 -1
  25. package/lib/forms/controls/single-reference.test.js +1 -1
  26. package/lib/forms/controls/table.js +114 -12
  27. package/lib/forms/fields/boolean.js +1 -1
  28. package/lib/forms/fields/field.js +4 -1
  29. package/lib/forms/fields/table.js +8 -3
  30. package/lib/forms/form.js +7 -6
  31. package/lib/page/default-list-filters.js +1 -0
  32. package/lib/templates/form.js +25 -16
  33. package/lib/templates/list.js +6 -167
  34. package/lib/templates/shared/collection-create-form.js +23 -83
  35. package/lib/templates/shared/collection-edit-form.js +53 -96
  36. package/lib/templates/shared/collection-list.js +21 -6
  37. package/lib/templates/shared/confirm-item-delete.js +7 -5
  38. package/lib/templates/shared/handlers/boolean.js +14 -0
  39. package/lib/templates/shared/handlers/date.js +8 -0
  40. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +209 -0
  41. package/lib/templates/shared/handlers/default.js +50 -0
  42. package/lib/templates/shared/handlers/enum.js +19 -0
  43. package/lib/templates/shared/handlers/file.js +18 -0
  44. package/lib/templates/shared/handlers/image.js +32 -0
  45. package/lib/templates/shared/handlers/int.js +11 -0
  46. package/lib/templates/shared/handlers/jdd.js +10 -0
  47. package/lib/templates/shared/handlers/single-reference.js +12 -0
  48. package/lib/templates/shared/handlers/structured-array.js +33 -0
  49. package/lib/templates/shared/item-delete.js +5 -3
  50. package/lib/templates/shared/shared-crud-form-fields.js +72 -82
  51. package/lib/utils/extract-fields-from-collection.js +31 -5
  52. package/package.json +2 -1
  53. package/src/add-crud.ts +153 -0
  54. package/src/cli.ts +2 -0
  55. package/src/forms/controls/form-control.ts +3 -2
  56. package/src/forms/controls/multiple-photos.ts +1 -0
  57. package/src/forms/controls/single-reference.test.ts +1 -1
  58. package/src/forms/controls/table.ts +160 -30
  59. package/src/forms/fields/boolean.ts +1 -1
  60. package/src/forms/fields/field.ts +4 -1
  61. package/src/forms/fields/table.ts +25 -6
  62. package/src/forms/form.ts +13 -7
  63. package/src/page/default-list-filters.ts +1 -0
  64. package/src/templates/form.ts +24 -15
  65. package/src/templates/list.ts +6 -174
  66. package/src/templates/shared/collection-create-form.ts +121 -0
  67. package/src/templates/shared/collection-edit-form.ts +196 -0
  68. package/src/templates/shared/collection-list.ts +252 -0
  69. package/src/templates/shared/confirm-item-delete.ts +78 -0
  70. package/src/templates/shared/handlers/boolean.ts +18 -0
  71. package/src/templates/shared/handlers/date.ts +12 -0
  72. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +244 -0
  73. package/src/templates/shared/handlers/default.ts +58 -0
  74. package/src/templates/shared/handlers/enum.ts +23 -0
  75. package/src/templates/shared/handlers/file.ts +22 -0
  76. package/src/templates/shared/handlers/image.ts +45 -0
  77. package/src/templates/shared/handlers/int.ts +15 -0
  78. package/src/templates/shared/handlers/jdd.ts +14 -0
  79. package/src/templates/shared/handlers/single-reference.ts +16 -0
  80. package/src/templates/shared/handlers/structured-array.ts +42 -0
  81. package/src/templates/shared/item-delete.ts +45 -0
  82. package/src/templates/shared/shared-crud-form-fields.ts +179 -0
  83. package/src/utils/extract-fields-from-collection.ts +45 -6
  84. package/src/utils/with-fallback.ts +1 -1
  85. package/src/utils/write-file.ts +8 -0
@@ -0,0 +1,179 @@
1
+ import { toPascalCase } from "js-convert-case";
2
+ import { extractCollectionClassname } from "../../generate-collections.js";
3
+ import extract_fields_from_collection, {
4
+ ExtractedFieldInfo,
5
+ } from "../../utils/extract-fields-from-collection.js";
6
+
7
+ import _locreq from "locreq";
8
+ import { curryImportPath } from "../../utils/import-path.js";
9
+ import { formatWithPrettier } from "../../utils/prettier.js";
10
+ import { default_handler } from "./handlers/default.js";
11
+ import { enum_handler } from "./handlers/enum.js";
12
+ import { image_handler } from "./handlers/image.js";
13
+ import { file_handler } from "./handlers/file.js";
14
+ import { int_handler } from "./handlers/int.js";
15
+ import { boolean_handler } from "./handlers/boolean.js";
16
+ import { jdd_handler } from "./handlers/jdd.js";
17
+ import { date_handler } from "./handlers/date.js";
18
+ import { deep_reverse_single_reference_handler } from "./handlers/deep-reverse-single-reference.js";
19
+ import { structured_array_handler } from "./handlers/structured-array.js";
20
+ const target_locreq = _locreq(process.cwd());
21
+
22
+ export type FieldHandlerResult = {
23
+ imports: Partial<{ shared: string; edit: string }>;
24
+ hide_field: boolean;
25
+ field: string;
26
+ hide_control: boolean;
27
+ controls: string;
28
+ is_required: boolean;
29
+ is_required_expr: string;
30
+ fields_var: string;
31
+ top_level_shared: string;
32
+ name: string;
33
+ hide_initial_value_edit: boolean;
34
+ initial_value_edit:
35
+ | Partial<{
36
+ main_value: string;
37
+ parsed_value: string;
38
+ fallback_value: string;
39
+ }>
40
+ | string;
41
+ hide_initial_value_create: boolean;
42
+ initial_value_create: string;
43
+ pre_edit: string;
44
+ post_edit: string;
45
+ pre_create: string;
46
+ post_create: string;
47
+ sealious_value: (
48
+ result: Exclude<FieldHandlerResult, "sealious_value">
49
+ ) => string;
50
+ hide_sealious_value: boolean;
51
+ fallback_value_sealious: string;
52
+ main_value_sealious: string;
53
+ };
54
+
55
+ export type FieldHandler<
56
+ Defaults extends Partial<FieldHandlerResult>,
57
+ Result extends Partial<FieldHandlerResult>
58
+ > = (
59
+ collection_name: string,
60
+ field: ExtractedFieldInfo,
61
+ importPath: (path: string) => string,
62
+ defaults: Defaults
63
+ ) => Promise<Result>;
64
+
65
+ export const field_handlers: Record<
66
+ Exclude<string, "default">,
67
+ FieldHandler<FieldHandlerResult, Partial<FieldHandlerResult>> | undefined
68
+ > & {
69
+ default: FieldHandler<Record<string, never>, FieldHandlerResult>;
70
+ } = {
71
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
72
+ default: default_handler as any,
73
+ enum: enum_handler,
74
+ image: image_handler,
75
+ file: file_handler,
76
+ int: int_handler,
77
+ boolean: boolean_handler,
78
+ jdd: jdd_handler,
79
+ date: date_handler,
80
+ "deep-reverse-single-reference": deep_reverse_single_reference_handler,
81
+ "structured-array": structured_array_handler,
82
+ };
83
+
84
+ export async function getFieldHandler(
85
+ collection_name: string,
86
+ field: ExtractedFieldInfo,
87
+ importPath: (path: string) => string
88
+ ) {
89
+ const defaults = await field_handlers.default(
90
+ collection_name,
91
+ field,
92
+ importPath,
93
+ {}
94
+ );
95
+ const result = {
96
+ ...defaults,
97
+ ...((await field_handlers[field.type]?.(
98
+ collection_name,
99
+ field,
100
+ importPath,
101
+ defaults
102
+ )) || {}),
103
+ };
104
+ const result_initial_value_edit = result.initial_value_edit;
105
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
106
+ result.initial_value_edit =
107
+ typeof result_initial_value_edit == "string"
108
+ ? result_initial_value_edit
109
+ : {
110
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
+ ...(defaults.initial_value_edit as any),
112
+ ...result_initial_value_edit,
113
+ };
114
+ return result;
115
+ }
116
+
117
+ export async function sharedCrudFormFields(
118
+ collection_name: string,
119
+ newfilefullpath: string
120
+ ) {
121
+ const [uppercase_collection, collection_fields] = await Promise.all([
122
+ extractCollectionClassname(
123
+ target_locreq.resolve(
124
+ "src/back/collections/" + collection_name + ".ts"
125
+ )
126
+ ),
127
+ extract_fields_from_collection(collection_name),
128
+ ]);
129
+ const importPath = curryImportPath(newfilefullpath);
130
+
131
+ const field_handler_results = await Promise.all(
132
+ collection_fields.map(async (field) => {
133
+ return getFieldHandler(collection_name, field, importPath);
134
+ })
135
+ );
136
+
137
+ const result = `import { Controls, Fields } from "@sealcode/sealgen";
138
+ import { ${uppercase_collection} } from "${importPath(
139
+ "src/back/collections/collections.js"
140
+ )}";
141
+
142
+ ${Array.from(
143
+ new Set(
144
+ field_handler_results
145
+ .filter(
146
+ ({ hide_field, hide_control }) => !hide_field && !hide_control
147
+ )
148
+ .map(({ imports }) => imports.shared || "")
149
+ )
150
+ ).join("\n")}
151
+
152
+
153
+
154
+ export const ${toPascalCase(collection_name)}FormFields = <const>
155
+ {
156
+ ${field_handler_results
157
+ .filter(({ hide_field }) => !hide_field)
158
+ .map(({ field }) => field)
159
+ .filter((e) => e != "")
160
+ .join(",\n")}
161
+ };
162
+
163
+ export const ${toPascalCase(collection_name)}FormControls = [
164
+ ${field_handler_results
165
+ .filter(({ hide_control }) => !hide_control)
166
+ .map(({ controls }) => controls)
167
+ .filter((e) => e != "")
168
+ .join(",\n")}
169
+ ];
170
+
171
+ ${Array.from(
172
+ new Set(
173
+ field_handler_results.map(({ top_level_shared }) => top_level_shared)
174
+ )
175
+ ).join("\n")}
176
+
177
+ `;
178
+ return formatWithPrettier(result);
179
+ }
@@ -4,24 +4,62 @@ const target_locreq = _locreq(process.cwd());
4
4
  import { promises as fs } from "fs";
5
5
  import { is, predicates } from "@sealcode/ts-predicates";
6
6
 
7
+ export type ExtractedFieldInfo = {
8
+ name: string;
9
+ type: string;
10
+ target: string | null;
11
+ referencing_collection: string | null;
12
+ referencing_field: string | null;
13
+ intermediary_field_that_points_there: string | null;
14
+ is_readonly: boolean;
15
+ is_required: boolean;
16
+ subfields: { name: string }[];
17
+ };
18
+
19
+ const counter = (function* () {
20
+ let i = 0;
21
+ while (true) {
22
+ yield i++;
23
+ }
24
+ })();
25
+
7
26
  export default async function extract_fields_from_collection(
8
27
  collection_name: string
9
- ): Promise<{ name: string; type: string }[]> {
28
+ ): Promise<ExtractedFieldInfo[]> {
10
29
  const extractor_code = `import {default as the_app} from "./app.js";
11
30
  const c = new the_app().collections["${collection_name}"];
12
31
  const fields = [];
13
32
  for (const field_name in c.fields){
14
33
  const field = c.fields[field_name];
15
34
  let type = field.typeName;
35
+ let target = null;
36
+ let referencing_collection = null;
37
+ let referencing_field = null;
38
+ let intermediary_field_that_points_there = null;
39
+ let is_readonly = false;
40
+ let is_required = field.required;
41
+ let subfields = [];
16
42
  if(["derived-value", "cached-value"].includes(type)){
17
- type = field.virtual_field.typeName
43
+ type = field.virtual_field.typeName;
44
+ }
45
+ if(["derived-value", "cached-value", "reverse-single-reference"].includes(field.typeName)){
46
+ is_readonly = true;
47
+ }
48
+ if(type == "deep-reverse-single-reference" || type =="reverse-single-reference"){
49
+ target = field.target_collection;
50
+ referencing_collection = field.referencing_collection;
51
+ referencing_field = field.referencing_field;
52
+ intermediary_field_that_points_there = field.intermediary_field_that_points_there
53
+ }
54
+ if( type == "structured-array" ) {
55
+ subfields = Object.keys(field.subfields).map(key=>({name: key}));
18
56
  }
19
- fields.push({name: field_name, type})
57
+ fields.push({ name: field_name, type, target, referencing_collection, referencing_field, intermediary_field_that_points_there, is_readonly, is_required, subfields })
20
58
  }
21
- console.log(JSON.stringify(fields));
59
+ console.log(JSON.stringify(fields));
22
60
  `;
23
61
  const extractor_code_path = target_locreq.resolve(
24
- "dist/back/___extract_fields.js"
62
+ `dist/back/___extract_fields--${counter.next().value || 0}.js`
25
63
  );
26
64
  await fs.writeFile(extractor_code_path, extractor_code);
27
65
  const { stdout } = await exec("node", [extractor_code_path]);
@@ -34,6 +72,7 @@ console.log(JSON.stringify(fields));
34
72
  predicates.shape({
35
73
  name: predicates.string,
36
74
  type: predicates.string,
75
+ is_readonly: predicates.boolean,
37
76
  })
38
77
  )
39
78
  )
@@ -43,5 +82,5 @@ console.log(JSON.stringify(fields));
43
82
  stdout
44
83
  );
45
84
  }
46
- return ret;
85
+ return ret as ExtractedFieldInfo[];
47
86
  }
@@ -16,7 +16,7 @@ export function withFallback<T1, T2, T3 extends NonNullable<unknown>>(
16
16
  value1: T1,
17
17
  value2: T2,
18
18
  value3?: T3
19
- ): NonNullable<T1> | NonNullable<T2> | T3;
19
+ ): NonNullable<T2> | T3;
20
20
  export function withFallback<T1, T2, T3 extends NonNullable<unknown>>(
21
21
  value1: T1,
22
22
  value2: T2,
@@ -0,0 +1,8 @@
1
+ import { promises as fs } from "node:fs";
2
+ import { resolve } from "path";
3
+
4
+ export async function writeFile(path: string, content: string) {
5
+ await fs.mkdir(resolve(path, "../"), { recursive: true });
6
+ await fs.writeFile(path, content);
7
+ console.log(`${path} created`);
8
+ }