@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.
- package/.xunit +59 -57
- package/@types/src/forms/controls/form-control.d.ts +2 -1
- package/@types/src/forms/controls/table.d.ts +31 -4
- package/@types/src/forms/fields/table.d.ts +4 -2
- package/@types/src/templates/form.d.ts +5 -0
- package/@types/src/templates/shared/collection-create-form.d.ts +0 -2
- package/@types/src/templates/shared/handlers/boolean.d.ts +2 -0
- package/@types/src/templates/shared/handlers/date.d.ts +2 -0
- package/@types/src/templates/shared/handlers/deep-reverse-single-reference.d.ts +2 -0
- package/@types/src/templates/shared/handlers/default.d.ts +2 -0
- package/@types/src/templates/shared/handlers/enum.d.ts +2 -0
- package/@types/src/templates/shared/handlers/file.d.ts +2 -0
- package/@types/src/templates/shared/handlers/image.d.ts +2 -0
- package/@types/src/templates/shared/handlers/int.d.ts +2 -0
- package/@types/src/templates/shared/handlers/jdd.d.ts +2 -0
- package/@types/src/templates/shared/handlers/single-reference.d.ts +2 -0
- package/@types/src/templates/shared/handlers/structured-array.d.ts +2 -0
- package/@types/src/templates/shared/shared-crud-form-fields.d.ts +29 -6
- package/@types/src/utils/extract-fields-from-collection.d.ts +12 -2
- package/@types/src/utils/with-fallback.d.ts +1 -1
- package/lib/add-crud.js +5 -5
- package/lib/cli.js +2 -0
- package/lib/forms/controls/form-control.js +2 -2
- package/lib/forms/controls/multiple-photos.js +2 -1
- package/lib/forms/controls/single-reference.test.js +1 -1
- package/lib/forms/controls/table.js +114 -12
- package/lib/forms/fields/boolean.js +1 -1
- package/lib/forms/fields/field.js +4 -1
- package/lib/forms/fields/table.js +8 -3
- package/lib/forms/form.js +7 -6
- package/lib/page/default-list-filters.js +1 -0
- package/lib/templates/form.js +25 -16
- package/lib/templates/list.js +6 -167
- package/lib/templates/shared/collection-create-form.js +23 -83
- package/lib/templates/shared/collection-edit-form.js +53 -96
- package/lib/templates/shared/collection-list.js +21 -6
- package/lib/templates/shared/confirm-item-delete.js +7 -5
- package/lib/templates/shared/handlers/boolean.js +14 -0
- package/lib/templates/shared/handlers/date.js +8 -0
- package/lib/templates/shared/handlers/deep-reverse-single-reference.js +209 -0
- package/lib/templates/shared/handlers/default.js +50 -0
- package/lib/templates/shared/handlers/enum.js +19 -0
- package/lib/templates/shared/handlers/file.js +18 -0
- package/lib/templates/shared/handlers/image.js +32 -0
- package/lib/templates/shared/handlers/int.js +11 -0
- package/lib/templates/shared/handlers/jdd.js +10 -0
- package/lib/templates/shared/handlers/single-reference.js +12 -0
- package/lib/templates/shared/handlers/structured-array.js +33 -0
- package/lib/templates/shared/item-delete.js +5 -3
- package/lib/templates/shared/shared-crud-form-fields.js +72 -82
- package/lib/utils/extract-fields-from-collection.js +31 -5
- package/package.json +2 -1
- package/src/add-crud.ts +153 -0
- package/src/cli.ts +2 -0
- package/src/forms/controls/form-control.ts +3 -2
- package/src/forms/controls/multiple-photos.ts +1 -0
- package/src/forms/controls/single-reference.test.ts +1 -1
- package/src/forms/controls/table.ts +160 -30
- package/src/forms/fields/boolean.ts +1 -1
- package/src/forms/fields/field.ts +4 -1
- package/src/forms/fields/table.ts +25 -6
- package/src/forms/form.ts +13 -7
- package/src/page/default-list-filters.ts +1 -0
- package/src/templates/form.ts +24 -15
- package/src/templates/list.ts +6 -174
- package/src/templates/shared/collection-create-form.ts +121 -0
- package/src/templates/shared/collection-edit-form.ts +196 -0
- package/src/templates/shared/collection-list.ts +252 -0
- package/src/templates/shared/confirm-item-delete.ts +78 -0
- package/src/templates/shared/handlers/boolean.ts +18 -0
- package/src/templates/shared/handlers/date.ts +12 -0
- package/src/templates/shared/handlers/deep-reverse-single-reference.ts +244 -0
- package/src/templates/shared/handlers/default.ts +58 -0
- package/src/templates/shared/handlers/enum.ts +23 -0
- package/src/templates/shared/handlers/file.ts +22 -0
- package/src/templates/shared/handlers/image.ts +45 -0
- package/src/templates/shared/handlers/int.ts +15 -0
- package/src/templates/shared/handlers/jdd.ts +14 -0
- package/src/templates/shared/handlers/single-reference.ts +16 -0
- package/src/templates/shared/handlers/structured-array.ts +42 -0
- package/src/templates/shared/item-delete.ts +45 -0
- package/src/templates/shared/shared-crud-form-fields.ts +179 -0
- package/src/utils/extract-fields-from-collection.ts +45 -6
- package/src/utils/with-fallback.ts +1 -1
- 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<
|
|
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
|
-
|
|
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
|
-
|
|
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<
|
|
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
|
+
}
|