@sealcode/sealgen 0.15.35 → 0.15.37

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 +24 -5
  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 +168 -31
  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,244 @@
1
+ import { toKebabCase, toPascalCase } from "js-convert-case";
2
+ import extract_fields_from_collection from "../../../utils/extract-fields-from-collection.js";
3
+ import {
4
+ FieldHandler,
5
+ FieldHandlerResult,
6
+ } from "../shared-crud-form-fields.js";
7
+
8
+ export const deep_reverse_single_reference_handler: FieldHandler<
9
+ FieldHandlerResult,
10
+ Partial<FieldHandlerResult>
11
+ > = async (
12
+ collection_name,
13
+ {
14
+ name,
15
+ target,
16
+ referencing_collection,
17
+ intermediary_field_that_points_there,
18
+ referencing_field,
19
+ },
20
+ ___,
21
+ { is_required_expr, fields_var }
22
+ ) => {
23
+ if (
24
+ !referencing_collection ||
25
+ !target ||
26
+ !intermediary_field_that_points_there ||
27
+ !referencing_field
28
+ ) {
29
+ console.warn(
30
+ "missing referencing_collection, target, intermediary_field_that_points_there, or referencing_field member in extracted field info"
31
+ );
32
+ return { field: "" };
33
+ }
34
+ const referencing_fields = await extract_fields_from_collection(
35
+ referencing_collection
36
+ );
37
+ if (referencing_fields.length == 2) {
38
+ // just a regular n-to-n intermediary collection
39
+ const post_create = (get_id: string) => `{
40
+ const item_id = ${get_id};
41
+ // First, we remove links refering to current item
42
+ const {items: existing_links } = (await ctx.$app.collections["${referencing_collection}"]
43
+ .list(ctx.$context)
44
+ .filter({"${referencing_field}": item_id})
45
+ .fetch()
46
+ )
47
+ const should_exist_ids = Object.entries(
48
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
49
+ (data["${name}"] as unknown as Record<string, string>) || {}
50
+ )
51
+ .filter(([, value]) => value === "on")
52
+ .map(([key]) => key);
53
+ const to_delete = existing_links.filter(
54
+ (link) => !should_exist_ids.includes(link.get("${intermediary_field_that_points_there}"))
55
+ );
56
+ const to_create_ids = should_exist_ids.filter(
57
+ (id) => !existing_links.map(({ id }) => id).includes(id)
58
+ );
59
+ await Promise.all(to_delete.map((item) => item.remove(ctx.$context)));
60
+ // Then, we iterate over all selected values and insert appropriate missing links
61
+ const promises = to_create_ids.map(async (id) => {
62
+ await ctx.$app.collections["${toKebabCase(referencing_collection)}"].create(
63
+ ctx.$context,
64
+ {
65
+ "${referencing_field}": item_id,
66
+ "${intermediary_field_that_points_there}": id,
67
+ }
68
+ );
69
+ });
70
+ await Promise.all(promises);
71
+ }`;
72
+ return {
73
+ field: `${name}: new Fields.CheckboxedListField(${is_required_expr}, async (ctx) => {
74
+ const { items } = await ctx.$app.collections["${target}"]
75
+ .list(ctx.$context)
76
+ .fetch();
77
+
78
+ return items.map((s) => ({
79
+ label: s.get("name"),
80
+ value: s.id,
81
+ }));
82
+ })`,
83
+ controls: `new Controls.CheckboxedListInput(${fields_var}.${name}, {
84
+ label: "${name}",
85
+ })`,
86
+ post_edit: post_create(`await this.getID(ctx)`),
87
+ post_create: post_create(`created.id`),
88
+ initial_value_edit: `Object.fromEntries((item.get("${name}") || []).map(id=>[id, "on"]))`,
89
+ sealious_value: () => "",
90
+ };
91
+ } else {
92
+ // probably an n-to-n intermediary collection with an additional attribute
93
+ const initial_value_function_name = `get${toPascalCase(
94
+ name
95
+ )}TableInitialValues`;
96
+ const post_create = (get_id: string) => `{
97
+ const item_id = ${get_id};
98
+ // First, we remove links refering to current item
99
+ const { items: to_delete } = await ctx.$app.collections[
100
+ "${toKebabCase(referencing_collection)}"
101
+ ]
102
+ .list(ctx.$context)
103
+ .filter({ "${referencing_field}": item_id })
104
+ .fetch();
105
+ await Promise.all(to_delete.map((item) => item.remove(ctx.$context)));
106
+
107
+ // Then, we iterate over all selected values and insert appropriate entries for the subcategories relation
108
+
109
+ const promises = data["${name}"]
110
+ .filter((s) => s.selected == true)
111
+ .map(async (link_info) => {
112
+ await ctx.$app.collections["${toKebabCase(referencing_collection)}"].create(
113
+ ctx.$context,
114
+ {
115
+ "${referencing_field}": item_id,
116
+ "${intermediary_field_that_points_there}": String(link_info["${intermediary_field_that_points_there}"]),
117
+ ${referencing_fields
118
+ .filter(
119
+ ({ type }) => type !== "single-reference"
120
+ )
121
+ .map(
122
+ (field) =>
123
+ `"${field.name}": link_info["${field.name}"]`
124
+ )
125
+ .join(",\n")}
126
+ }
127
+ );
128
+ });
129
+
130
+ await Promise.all(promises);
131
+ }`;
132
+ const initial_value = `(await ${initial_value_function_name}(ctx,item)) as unknown as FormDataValue`;
133
+ return {
134
+ imports: {
135
+ shared: `import type { CollectionItem } from "sealious"; import type { Context } from "koa";`,
136
+ edit: `import {${initial_value_function_name}} from "../shared.js"; import type { FormDataValue } from "@sealcode/sealgen";`,
137
+ },
138
+ field: `
139
+ ${name}: new Fields.Table({
140
+ selected: new Fields.Boolean(false),
141
+ "${referencing_field}": new Fields.SimpleFormField(true),
142
+ "${intermediary_field_that_points_there}": new Fields.SimpleFormField(true),
143
+ ${referencing_fields
144
+ .filter(({ type }) => type !== "single-reference")
145
+ .map(
146
+ (field) =>
147
+ `${field.name}: new Fields.SimpleFormField(true)`
148
+ )
149
+ .join(",\n")}
150
+ })`,
151
+ controls: `
152
+ new Controls.Table(${fields_var}.${name}, {
153
+ render_fields: {
154
+ selected: (fctx, name, value) => /* HTML */ \`<input
155
+ type="checkbox"
156
+ name=\${name}
157
+ \${value?.toString() == "true" ? "checked" : ""}
158
+ form="\${fctx.form_id}"
159
+ autocomplete="off"
160
+ />\`,
161
+ "${referencing_field}": (fctx, name, value) => /* HTML */ \`<input
162
+ type="hidden"
163
+ name=\${name}
164
+ value="\${value}"
165
+ form="\${fctx.form_id}"
166
+ />\`,
167
+ "${intermediary_field_that_points_there}": (fctx, name, value) => /* HTML */ \`<input
168
+ type="hidden"
169
+ name=\${name}
170
+ value="\${value}"
171
+ form="\${fctx.form_id}"
172
+ />\`,
173
+ ${referencing_fields
174
+ .filter(
175
+ ({ type }) => type !== "single-reference"
176
+ )
177
+ .map(
178
+ (field) =>
179
+ `${field.name}: (fctx, name, value) => /* HTML */ \`<input
180
+ name=\${name}
181
+ value="\${value}"
182
+ form="\${fctx.form_id}"
183
+ autocomplete="off"
184
+ />\``
185
+ )
186
+ .join(",\n")}
187
+ },
188
+ allow_adding: false,
189
+ })`,
190
+ top_level_shared: `export async function ${initial_value_function_name}(
191
+ ctx: Context,
192
+ item: CollectionItem<typeof ${toPascalCase(
193
+ collection_name
194
+ )}>
195
+ ) {
196
+ // convert from an array to array-like object
197
+ return Object.fromEntries(
198
+ await Promise.all([
199
+ ctx.$app.collections["${toKebabCase(target)}"].list(ctx.$context).fetch(),
200
+ ctx.$app.collections["${toKebabCase(
201
+ referencing_collection
202
+ )}"].list(ctx.$context).fetch(),
203
+ ]).then(([{ items: targets }, { items: links }]) =>
204
+ targets
205
+ .map((target) => {
206
+ return {
207
+ selected: (item.get("${name}") || []).includes(
208
+ target.id
209
+ )
210
+ ? "on"
211
+ : "off",
212
+ "${referencing_field}": item.id,
213
+ "${intermediary_field_that_points_there}": target.id,
214
+ ${referencing_fields
215
+ .filter(
216
+ ({ type }) =>
217
+ type !== "single-reference"
218
+ )
219
+ .map(
220
+ (
221
+ field
222
+ ) => `"${field.name}": links
223
+ .find(
224
+ (e) =>
225
+ e.get("${intermediary_field_that_points_there}") == target.id &&
226
+ e.get("${referencing_field}") == item.id
227
+ )
228
+ ?.get("rank") || 0,`
229
+ )
230
+ .join(",\n")}
231
+ };
232
+ })
233
+ .entries()
234
+ )
235
+ );
236
+ }`,
237
+
238
+ initial_value_edit: initial_value,
239
+ initial_value_create: initial_value,
240
+ post_edit: post_create(`await this.getID(ctx)`),
241
+ post_create: post_create(`created.id`),
242
+ };
243
+ }
244
+ };
@@ -0,0 +1,58 @@
1
+ import { toPascalCase } from "js-convert-case";
2
+ import {
3
+ FieldHandler,
4
+ FieldHandlerResult,
5
+ } from "../shared-crud-form-fields.js";
6
+
7
+ export const default_handler: FieldHandler<
8
+ Record<string, never>,
9
+ FieldHandlerResult
10
+ > = async (collection_name, { name, is_readonly, is_required }) => {
11
+ const required_s = `${toPascalCase(
12
+ collection_name
13
+ )}.fields.${name}.required`;
14
+ const fields_var = `${toPascalCase(collection_name)}FormFields`;
15
+ const fallback_value_initial = `""`;
16
+ const fallback_value_sealious = `""`;
17
+
18
+ const main_value_initial = `item.get("${name}")`;
19
+ const main_value_sealious = `data["${name}"]`;
20
+ const parsed_value = main_value_initial;
21
+
22
+ return {
23
+ is_required,
24
+ name,
25
+ post_create: "",
26
+ imports: { shared: "", edit: "" },
27
+ hide_field: is_readonly,
28
+ field: `${name}: new Fields.CollectionField(${required_s}, ${toPascalCase(
29
+ collection_name
30
+ )}.fields.${name})`,
31
+ hide_control: is_readonly,
32
+ controls: `new Controls.SimpleInput(${fields_var}.${name}, { label: "${name}"})`,
33
+ is_required_expr: `${toPascalCase(
34
+ collection_name
35
+ )}.fields.${name}.required`,
36
+ fields_var,
37
+ top_level_shared: "",
38
+ hide_initial_value_edit: is_readonly,
39
+ initial_value_edit: {
40
+ fallback_value: fallback_value_initial,
41
+ main_value: main_value_initial,
42
+ parsed_value,
43
+ },
44
+ hide_initial_value_create: is_readonly,
45
+ initial_value_create: "",
46
+ pre_edit: "",
47
+ post_edit: "",
48
+ pre_create: "",
49
+ main_value_sealious,
50
+ fallback_value_sealious,
51
+ sealious_value: (result: FieldHandlerResult) => {
52
+ return result.is_required
53
+ ? `${result.name}: ${result.main_value_sealious}`
54
+ : `${result.name}: ${result.main_value_sealious} != null ? ${result.main_value_sealious} : ${result.fallback_value_sealious}`;
55
+ },
56
+ hide_sealious_value: is_readonly,
57
+ };
58
+ };
@@ -0,0 +1,23 @@
1
+ import { toPascalCase } from "js-convert-case";
2
+ import {
3
+ FieldHandler,
4
+ FieldHandlerResult,
5
+ } from "../shared-crud-form-fields.js";
6
+
7
+ export const enum_handler: FieldHandler<
8
+ FieldHandlerResult,
9
+ Partial<FieldHandlerResult>
10
+ > = async (collection_name, { name }, _, { fields_var }) => ({
11
+ // this assertion and import is only necessary because required fields
12
+ // in Sealious lose the type information. Once this is fixed, we can remove this import here
13
+ imports: { shared: `import type { FieldTypes } from "sealious";` },
14
+ field: `${name}: new Fields.PickFromListField(
15
+ ${toPascalCase(collection_name)}.fields["${name}"].required,
16
+ async (ctx) =>
17
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
18
+ (${toPascalCase(collection_name)}.fields["${name}"])
19
+ .getAllowedValues(ctx.$app)
20
+ .map((value) => ({ value, label: value }))
21
+ )`,
22
+ controls: `new Controls.Dropdown(${fields_var}.${name}, { label: "${name}"})`,
23
+ });
@@ -0,0 +1,22 @@
1
+ import { toCamelCase } from "js-convert-case";
2
+ import {
3
+ FieldHandler,
4
+ FieldHandlerResult,
5
+ } from "../shared-crud-form-fields.js";
6
+
7
+ export const file_handler: FieldHandler<
8
+ FieldHandlerResult,
9
+ Partial<FieldHandlerResult>
10
+ > = async (_, { name, is_required }, __, { is_required_expr }) => {
11
+ const tempname = toCamelCase("prepared-" + name);
12
+ return {
13
+ field: `${name}: new Fields.File(${is_required_expr}, TheFileManager)`,
14
+ initial_value_edit: `${name}: {old: item.get("${name}")}`,
15
+ pre_edit: `const ${tempname} = data.${name}.new || data.${name}.old;
16
+ if(!${tempname}){
17
+ throw new Error("Missing field: ${name}")
18
+ }`,
19
+ fallback_value_sealious: "null",
20
+ ...(is_required ? { main_value_sealious: tempname } : {}),
21
+ };
22
+ };
@@ -0,0 +1,45 @@
1
+ import { toCamelCase } from "js-convert-case";
2
+ import {
3
+ FieldHandler,
4
+ FieldHandlerResult,
5
+ } from "../shared-crud-form-fields.js";
6
+
7
+ export const image_handler: FieldHandler<
8
+ FieldHandlerResult,
9
+ Partial<FieldHandlerResult>
10
+ > = async (
11
+ _,
12
+ { name, is_required },
13
+ importPath,
14
+ { is_required_expr, fields_var }
15
+ ) => {
16
+ const tempname = toCamelCase("prepared-" + name);
17
+ return {
18
+ imports: {
19
+ shared: `import { imageRouter } from "${importPath(
20
+ "src/back/image-router.js"
21
+ )}";
22
+ import { TheFileManager } from "${importPath(
23
+ "src/back/file-manager.js"
24
+ )}";`,
25
+ },
26
+ field: `${name}: new Fields.File(${is_required_expr}, TheFileManager)`,
27
+ controls: `new Controls.Photo(${fields_var}.${name}, imageRouter, {
28
+ label: "${name}",
29
+ })`,
30
+ initial_value_edit: `{old: item.get("${name}")}`,
31
+ pre_edit:
32
+ `const ${tempname} = data.${name}.new || data.${name}.old ` +
33
+ (is_required
34
+ ? `; if(!${tempname}){
35
+ throw new Error("Missing field: ${name}")
36
+ }`
37
+ : " || undefined;"),
38
+ pre_create: `const ${tempname} = data.${name}.new || data.${name}.old;
39
+ if(!${tempname}){
40
+ throw new Error("Missing field: ${name}")
41
+ }`,
42
+ fallback_value_sealious: "null",
43
+ sealious_value: () => `${name}: ${tempname}`,
44
+ };
45
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ FieldHandler,
3
+ FieldHandlerResult,
4
+ } from "../shared-crud-form-fields.js";
5
+
6
+ export const int_handler: FieldHandler<
7
+ FieldHandlerResult,
8
+ Partial<FieldHandlerResult>
9
+ > = async (_, { name }, __, { is_required_expr, fields_var }) => ({
10
+ field: `${name}: new Fields.NumberField(${is_required_expr}, 0)`,
11
+ controls: `new Controls.Number(${fields_var}.${name}, { label: "${name}" })`,
12
+ initial_value_edit: {
13
+ parsed_value: `String(item.get("${name}"))`,
14
+ },
15
+ });
@@ -0,0 +1,14 @@
1
+ import {
2
+ FieldHandler,
3
+ FieldHandlerResult,
4
+ } from "../shared-crud-form-fields.js";
5
+
6
+ export const jdd_handler: FieldHandler<
7
+ FieldHandlerResult,
8
+ Partial<FieldHandlerResult>
9
+ > = async (_, { name }) => ({
10
+ field: ``,
11
+ initial_value_edit: "",
12
+ controls: "",
13
+ sealious_value: () => `${name}: []`,
14
+ });
@@ -0,0 +1,16 @@
1
+ import {
2
+ FieldHandler,
3
+ FieldHandlerResult,
4
+ } from "../shared-crud-form-fields.js";
5
+
6
+ export const single_reference_handler: FieldHandler<
7
+ FieldHandlerResult,
8
+ Partial<FieldHandlerResult>
9
+ > = async (_, { name }, __, { fields_var }) => {
10
+ return {
11
+ controls: `new Controls.SingleReferenceDropdown(${fields_var}.${name}, {
12
+ label: "${name}",
13
+ getLabel: (item)=>item.id
14
+ })`,
15
+ };
16
+ };
@@ -0,0 +1,42 @@
1
+ import {
2
+ FieldHandler,
3
+ FieldHandlerResult,
4
+ } from "../shared-crud-form-fields.js";
5
+
6
+ export const structured_array_handler: FieldHandler<
7
+ FieldHandlerResult,
8
+ Partial<FieldHandlerResult>
9
+ > = async (_, { name, subfields }, __, { fields_var }) => ({
10
+ field: `${name}: new Fields.Table({
11
+ ${subfields
12
+ .map(
13
+ (subfield) =>
14
+ `${subfield.name}: new Fields.SimpleFormField(true)`
15
+ )
16
+ .join(",\n")}
17
+ })`,
18
+ controls: `new Controls.Table(${fields_var}.${name}, {
19
+ label: "${name}",
20
+ render_fields: {
21
+ ${subfields
22
+ .map(
23
+ ({
24
+ name,
25
+ }) => `"${name}": (fctx, name, value) => /* HTML */ \`<input
26
+ name="\${name}"
27
+ value="\${value}"
28
+ form="\${fctx.form_id}"
29
+ autocomplete="off"
30
+ />\``
31
+ )
32
+ .join(",\n")}
33
+
34
+ },
35
+ allow_adding: true,
36
+ allow_removing: true,
37
+ make_new_row: async () => ({
38
+ ${subfields.map(({ name }) => `"${name}": ""`).join(",\n")}
39
+ }),
40
+ })`,
41
+ fallback_value_sealious: `[]`,
42
+ });
@@ -0,0 +1,45 @@
1
+ import { toKebabCase, toPascalCase } from "js-convert-case";
2
+ import { curryImportPath } from "../../utils/import-path.js";
3
+ import { formatWithPrettier } from "../../utils/prettier.js";
4
+
5
+ export function itemDeleteTemplate(
6
+ delete_action_name: string,
7
+ collection_name: string,
8
+ newfilefullpath: string,
9
+ list_action_name: string
10
+ ): Promise<string> {
11
+ const importPath = curryImportPath(newfilefullpath);
12
+ const result = `import type { Context } from "koa";
13
+ import { Mountable } from "@sealcode/sealgen";
14
+ import type Router from "@koa/router";
15
+
16
+ import { ${toPascalCase(collection_name)} } from "${importPath(
17
+ "src/back/collections/collections.js"
18
+ )}";
19
+
20
+ import { ${list_action_name}URL } from "${importPath(
21
+ "src/back/routes/urls.js"
22
+ )}";
23
+
24
+ export const actionName = "${delete_action_name}";
25
+
26
+ export default new (class ${delete_action_name}Redirect extends Mountable {
27
+ canAccess = async (ctx: Context) => {
28
+ const policy = ${toPascalCase(collection_name)}.getPolicy("edit");
29
+ const response = await policy.check(ctx.$context);
30
+ return { canAccess: response?.allowed || false, message: response?.reason || "" };
31
+ };
32
+
33
+ mount(router: Router, path: string) {
34
+ router.get(path, async (ctx) => {
35
+ await ctx.$app.collections["${toKebabCase(
36
+ collection_name
37
+ )}"].removeByID(ctx.$context, ctx.params.id);
38
+ ctx.status = 302;
39
+ ctx.redirect(${list_action_name}URL);
40
+ });
41
+ }
42
+ })();
43
+ `;
44
+ return formatWithPrettier(result);
45
+ }