@sealcode/sealgen 0.19.26 → 0.19.29
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/@types/forms/controls/dropdown.d.ts +6 -6
- package/@types/forms/controls/single-reference.d.ts +9 -6
- package/@types/forms/fields/field.d.ts +2 -2
- package/@types/forms/fields/pick-from-list.d.ts +2 -2
- package/@types/forms/fields/simple-form-field.d.ts +1 -1
- package/@types/forms/multiform.d.ts +4 -3
- package/@types/page/stateful-page.d.ts +1 -1
- package/@types/src/add-collection.d.ts +1 -0
- package/@types/src/add-crud.d.ts +3 -0
- package/@types/src/add-crud.test.d.ts +1 -0
- package/@types/src/add-jdd-component.d.ts +1 -0
- package/@types/src/add-list-route.test.d.ts +1 -0
- package/@types/src/add-route.d.ts +3 -0
- package/@types/src/add-route.test.d.ts +1 -0
- package/@types/src/build.d.ts +3 -0
- package/@types/src/builders/backend-ts-builder.d.ts +7 -0
- package/@types/src/builders/builder.d.ts +11 -0
- package/@types/src/builders/colors-builder.d.ts +10 -0
- package/@types/src/builders/css-builder.d.ts +19 -0
- package/@types/src/builders/fonts-builder.d.ts +7 -0
- package/@types/src/builders/frontend-ts-builder.d.ts +11 -0
- package/@types/src/cli.d.ts +2 -0
- package/@types/src/components/components.d.ts +2 -0
- package/@types/src/components/tabs.d.ts +2 -0
- package/@types/src/components/toggle-modal.d.ts +6 -0
- package/@types/src/controllers/password-generate-button.stimulus.d.ts +5 -0
- package/@types/src/controllers/sealgen-table.stimulus.d.ts +13 -0
- package/@types/src/embeddable-file-extensions.d.ts +1 -0
- package/@types/src/esbuild-plugins/load-assets.d.ts +5 -0
- package/@types/src/esbuild-plugins/rewrite-asset-imports.d.ts +5 -0
- package/@types/src/example.test.d.ts +1 -0
- package/@types/src/forms/controls/array.d.ts +33 -0
- package/@types/src/forms/controls/autocomplete.d.ts +22 -0
- package/@types/src/forms/controls/big-radio-group.d.ts +14 -0
- package/@types/src/forms/controls/checkbox-group.d.ts +21 -0
- package/@types/src/forms/controls/checkbox.d.ts +17 -0
- package/@types/src/forms/controls/checkboxed-list-input.d.ts +21 -0
- package/@types/src/forms/controls/checkboxed-list-input.test.d.ts +1 -0
- package/@types/src/forms/controls/collapsible-checkbox-group.d.ts +11 -0
- package/@types/src/forms/controls/collapsible-field-group.d.ts +21 -0
- package/@types/src/forms/controls/controls.d.ts +32 -0
- package/@types/src/forms/controls/derived-frame.d.ts +19 -0
- package/@types/src/forms/controls/derived.d.ts +13 -0
- package/@types/src/forms/controls/dropdown.d.ts +30 -0
- package/@types/src/forms/controls/editable-collection-subset.d.ts +20 -0
- package/@types/src/forms/controls/field-group.d.ts +23 -0
- package/@types/src/forms/controls/file.d.ts +12 -0
- package/@types/src/forms/controls/file.test.d.ts +1 -0
- package/@types/src/forms/controls/form-control.d.ts +23 -0
- package/@types/src/forms/controls/form-field-control.d.ts +13 -0
- package/@types/src/forms/controls/form-header.d.ts +8 -0
- package/@types/src/forms/controls/form-paragraph.d.ts +7 -0
- package/@types/src/forms/controls/frame.d.ts +17 -0
- package/@types/src/forms/controls/hidden-input.d.ts +9 -0
- package/@types/src/forms/controls/html.d.ts +11 -0
- package/@types/src/forms/controls/hybrid.d.ts +10 -0
- package/@types/src/forms/controls/image.d.ts +19 -0
- package/@types/src/forms/controls/image.test.d.ts +1 -0
- package/@types/src/forms/controls/multiple-files.d.ts +42 -0
- package/@types/src/forms/controls/multiple-images.d.ts +19 -0
- package/@types/src/forms/controls/number.d.ts +13 -0
- package/@types/src/forms/controls/password-with-generator.d.ts +6 -0
- package/@types/src/forms/controls/radio.d.ts +16 -0
- package/@types/src/forms/controls/simple-input.d.ts +35 -0
- package/@types/src/forms/controls/single-reference.d.ts +14 -0
- package/@types/src/forms/controls/single-reference.test.d.ts +1 -0
- package/@types/src/forms/controls/table.d.ts +41 -0
- package/@types/src/forms/controls/textarea.d.ts +25 -0
- package/@types/src/forms/controls/tickable.d.ts +25 -0
- package/@types/src/forms/fields/boolean.d.ts +22 -0
- package/@types/src/forms/fields/boolean.test.d.ts +1 -0
- package/@types/src/forms/fields/checkboxed-list.d.ts +23 -0
- package/@types/src/forms/fields/collection-field.d.ts +22 -0
- package/@types/src/forms/fields/color.d.ts +4 -0
- package/@types/src/forms/fields/coordinates.d.ts +14 -0
- package/@types/src/forms/fields/date.d.ts +13 -0
- package/@types/src/forms/fields/datetime.d.ts +14 -0
- package/@types/src/forms/fields/deep-reverse-single-reference-list.d.ts +20 -0
- package/@types/src/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
- package/@types/src/forms/fields/email.d.ts +10 -0
- package/@types/src/forms/fields/email.test.d.ts +1 -0
- package/@types/src/forms/fields/enum-multiple-sealious.d.ts +16 -0
- package/@types/src/forms/fields/existing-sealious-value.d.ts +6 -0
- package/@types/src/forms/fields/field.d.ts +85 -0
- package/@types/src/forms/fields/field.test.d.ts +1 -0
- package/@types/src/forms/fields/fields.d.ts +34 -0
- package/@types/src/forms/fields/file.d.ts +25 -0
- package/@types/src/forms/fields/file.test.d.ts +1 -0
- package/@types/src/forms/fields/float.d.ts +4 -0
- package/@types/src/forms/fields/get-field-for-sealious.d.ts +33 -0
- package/@types/src/forms/fields/html.d.ts +6 -0
- package/@types/src/forms/fields/hybrid.d.ts +11 -0
- package/@types/src/forms/fields/image.d.ts +5 -0
- package/@types/src/forms/fields/int.d.ts +6 -0
- package/@types/src/forms/fields/item-draft.d.ts +20 -0
- package/@types/src/forms/fields/json.d.ts +13 -0
- package/@types/src/forms/fields/markdown.d.ts +6 -0
- package/@types/src/forms/fields/multiple-files.d.ts +16 -0
- package/@types/src/forms/fields/number.d.ts +25 -0
- package/@types/src/forms/fields/number.test.d.ts +1 -0
- package/@types/src/forms/fields/password.d.ts +10 -0
- package/@types/src/forms/fields/phone-number-with-country-code.d.ts +13 -0
- package/@types/src/forms/fields/phone-number.d.ts +17 -0
- package/@types/src/forms/fields/pick-from-list-sealious.d.ts +11 -0
- package/@types/src/forms/fields/pick-from-list.d.ts +15 -0
- package/@types/src/forms/fields/pick-from-list.test.d.ts +1 -0
- package/@types/src/forms/fields/proxy-field.d.ts +15 -0
- package/@types/src/forms/fields/regexp.d.ts +21 -0
- package/@types/src/forms/fields/regexp.test.d.ts +1 -0
- package/@types/src/forms/fields/simple-form-field.d.ts +31 -0
- package/@types/src/forms/fields/single-reference.d.ts +19 -0
- package/@types/src/forms/fields/structured-array.d.ts +23 -0
- package/@types/src/forms/fields/table.d.ts +16 -0
- package/@types/src/forms/fields/text.d.ts +6 -0
- package/@types/src/forms/fields/url.d.ts +6 -0
- package/@types/src/forms/form-types.d.ts +28 -0
- package/@types/src/forms/form.d.ts +34 -0
- package/@types/src/forms/form.test.d.ts +6 -0
- package/@types/src/forms/multiform.d.ts +23 -0
- package/@types/src/forms/multiform.test.d.ts +1 -0
- package/@types/src/generate-collections.d.ts +2 -0
- package/@types/src/generate-components.d.ts +1 -0
- package/@types/src/generate-routes.d.ts +5 -0
- package/@types/src/generate-routes.test.d.ts +1 -0
- package/@types/src/generate-stimulus.d.ts +1 -0
- package/@types/src/get-fonts.d.ts +2 -0
- package/@types/src/index.d.ts +48 -0
- package/@types/src/make-env.d.ts +1 -0
- package/@types/src/make-hidden-inputs.d.ts +5 -0
- package/@types/src/mount.d.ts +6 -0
- package/@types/src/notifier.d.ts +2 -0
- package/@types/src/page/access-control.d.ts +6 -0
- package/@types/src/page/default-list-filters.d.ts +18 -0
- package/@types/src/page/list.d.ts +49 -0
- package/@types/src/page/mountable-with-fields.d.ts +49 -0
- package/@types/src/page/mountable-with-fields.test.d.ts +1 -0
- package/@types/src/page/mountable.d.ts +10 -0
- package/@types/src/page/page.d.ts +18 -0
- package/@types/src/page/props-parser.d.ts +15 -0
- package/@types/src/page/sealious-list.d.ts +20 -0
- package/@types/src/page/sealious-list.test.d.ts +1 -0
- package/@types/src/page/stateful-page.d.ts +63 -0
- package/@types/src/page/stateful-page.test.d.ts +1 -0
- package/@types/src/register-external.d.ts +2 -0
- package/@types/src/register-external.test.d.ts +1 -0
- package/@types/src/run.d.ts +1 -0
- package/@types/src/sanitize.d.ts +1 -0
- package/@types/src/target-locreq.d.ts +4 -0
- package/@types/src/templates/collection.d.ts +1 -0
- package/@types/src/templates/form.d.ts +14 -0
- package/@types/src/templates/form.test.d.ts +1 -0
- package/@types/src/templates/jdd-component.d.ts +1 -0
- package/@types/src/templates/jdd-editor.d.ts +1 -0
- package/@types/src/templates/list.d.ts +1 -0
- package/@types/src/templates/long-running-process.d.ts +1 -0
- package/@types/src/templates/multiform.d.ts +1 -0
- package/@types/src/templates/page.d.ts +1 -0
- package/@types/src/templates/post.d.ts +1 -0
- package/@types/src/templates/redirect.d.ts +1 -0
- package/@types/src/templates/route-test.d.ts +1 -0
- package/@types/src/templates/shared/collection-create-form.d.ts +1 -0
- package/@types/src/templates/shared/collection-edit-form.d.ts +1 -0
- package/@types/src/templates/shared/collection-list.d.ts +16 -0
- package/@types/src/templates/shared/item-delete.d.ts +1 -0
- package/@types/src/templates/shared/shared-crud-form-fields.d.ts +1 -0
- package/@types/src/templates/stateful-page.d.ts +1 -0
- package/@types/src/templates/stimulus-controller.d.ts +1 -0
- package/@types/src/templates/templates.d.ts +1 -0
- package/@types/src/test_utils/exec_async.d.ts +1 -0
- package/@types/src/test_utils/locator_is_visible.d.ts +2 -0
- package/@types/src/test_utils/test-on-real-app.d.ts +26 -0
- package/@types/src/utils/assert-throws.d.ts +1 -0
- package/@types/src/utils/base64.d.ts +2 -0
- package/@types/src/utils/browser-creator.d.ts +1 -0
- package/@types/src/utils/escape-url-params.d.ts +2 -0
- package/@types/src/utils/exec.d.ts +5 -0
- package/@types/src/utils/extract-fields-from-collection.d.ts +14 -0
- package/@types/src/utils/format-external-url.d.ts +1 -0
- package/@types/src/utils/import-path.d.ts +2 -0
- package/@types/src/utils/input-wrapper.d.ts +5 -0
- package/@types/src/utils/list-collections.d.ts +1 -0
- package/@types/src/utils/make-slug.d.ts +1 -0
- package/@types/src/utils/module-dirname.d.ts +1 -0
- package/@types/src/utils/natural-numbers.d.ts +1 -0
- package/@types/src/utils/prettier.d.ts +3 -0
- package/@types/src/utils/question.d.ts +1 -0
- package/@types/src/utils/render-attributes.d.ts +1 -0
- package/@types/src/utils/sleep.d.ts +1 -0
- package/@types/src/utils/translate.d.ts +4 -0
- package/@types/src/utils/url-with-new-params.d.ts +2 -0
- package/@types/src/utils/utils.d.ts +17 -0
- package/@types/src/utils/walk.d.ts +1 -0
- package/@types/src/utils/with-fallback.d.ts +2 -0
- package/@types/src/utils/wrap-attributes.d.ts +3 -0
- package/@types/src/utils/write-file.d.ts +1 -0
- package/lib/add-route.js +1 -3
- package/lib/builders/colors-builder.js +4 -5
- package/lib/forms/controls/file.js +1 -1
- package/lib/forms/controls/multiple-files.js +6 -5
- package/lib/forms/controls/single-reference.js +4 -1
- package/lib/forms/controls/tickable.js +1 -1
- package/lib/forms/fields/file.js +5 -5
- package/lib/forms/fields/image.js +1 -3
- package/lib/forms/fields/phone-number-with-country-code.js +0 -1
- package/lib/forms/fields/simple-form-field.js +1 -1
- package/lib/forms/fields/structured-array.js +1 -2
- package/lib/get-fonts.js +5 -1
- package/lib/page/mountable-with-fields.js +1 -2
- package/lib/page/mountable-with-fields.test.js +1 -1
- package/lib/page/sealious-list.js +3 -1
- package/package.json +2 -2
- package/src/build.ts +1 -2
- package/src/cli.ts +4 -5
- package/src/forms/controls/controls.ts +0 -1
- package/src/forms/controls/dropdown.ts +15 -13
- package/src/forms/controls/file.ts +1 -1
- package/src/forms/controls/html.ts +4 -3
- package/src/forms/controls/multiple-files.ts +9 -12
- package/src/forms/controls/number.ts +8 -8
- package/src/forms/controls/single-reference.ts +25 -12
- package/src/forms/controls/table.ts +2 -2
- package/src/forms/controls/textarea.ts +4 -3
- package/src/forms/controls/tickable.ts +2 -2
- package/src/forms/fields/deep-reverse-single-reference-list.ts +2 -5
- package/src/forms/fields/deep-reverse-single-reference-table.ts +16 -14
- package/src/forms/fields/field.ts +4 -4
- package/src/forms/fields/file.ts +27 -21
- package/src/forms/fields/image.ts +1 -5
- package/src/forms/fields/phone-number-with-country-code.ts +1 -2
- package/src/forms/fields/pick-from-list.ts +2 -2
- package/src/forms/fields/simple-form-field.ts +3 -3
- package/src/forms/fields/structured-array.ts +2 -3
- package/src/forms/fields/table.ts +4 -7
- package/src/forms/multiform.ts +9 -6
- package/src/generate-routes.ts +3 -3
- package/src/get-fonts.ts +7 -3
- package/src/notifier.ts +1 -2
- package/src/page/list.ts +4 -4
- package/src/page/mountable-with-fields.test.ts +1 -1
- package/src/page/mountable-with-fields.ts +4 -4
- package/src/page/sealious-list.ts +17 -8
- package/src/page/stateful-page.ts +1 -1
- package/src/templates/jdd-editor.ts +1 -1
- package/src/test_utils/test-on-real-app.ts +5 -5
- package/tsconfig.json +2 -0
- package/src/forms/controls/big-radio-group.ts +0 -48
|
@@ -59,15 +59,15 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
59
59
|
label: this.label || this.name,
|
|
60
60
|
allow_adding: false,
|
|
61
61
|
subfield_controls: {
|
|
62
|
-
selected: this.columns.selected
|
|
62
|
+
selected: this.columns.selected!.getControl(),
|
|
63
63
|
[this.sealious_field.referencing_field]: new HiddenInput(
|
|
64
|
-
this.columns[this.sealious_field.referencing_field]
|
|
64
|
+
this.columns[this.sealious_field.referencing_field]!
|
|
65
65
|
),
|
|
66
66
|
[this.sealious_field.intermediary_field_that_points_there]:
|
|
67
67
|
new HiddenInput(
|
|
68
68
|
this.columns[
|
|
69
69
|
this.sealious_field.intermediary_field_that_points_there
|
|
70
|
-
]
|
|
70
|
+
]!
|
|
71
71
|
),
|
|
72
72
|
...Object.fromEntries(
|
|
73
73
|
Object.values(getReferencingFields(this.sealious_field))
|
|
@@ -80,7 +80,7 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
80
80
|
)
|
|
81
81
|
.map((field) => [
|
|
82
82
|
field.name,
|
|
83
|
-
this.columns[field.name]
|
|
83
|
+
this.columns[field.name]!.getControl(),
|
|
84
84
|
])
|
|
85
85
|
),
|
|
86
86
|
},
|
|
@@ -99,8 +99,7 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
99
99
|
// First, we remove links refering to current item
|
|
100
100
|
const { items: to_delete } = await ctx.$app.collections[
|
|
101
101
|
"${toKebabCase(referencing_collection)}"
|
|
102
|
-
]
|
|
103
|
-
.list(ctx.$context)
|
|
102
|
+
]!.list(ctx.$context)
|
|
104
103
|
.filter({ "${referencing_field}": created_item.id })
|
|
105
104
|
.fetch();
|
|
106
105
|
await Promise.all(to_delete.map((item) => item.remove(ctx.$context)));
|
|
@@ -119,7 +118,7 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
119
118
|
.map(async (link_info) => {
|
|
120
119
|
await ctx.$app.collections[
|
|
121
120
|
"${toKebabCase(referencing_collection)}"
|
|
122
|
-
]
|
|
121
|
+
]!.create(ctx.$context, {
|
|
123
122
|
"${referencing_field}": created_item.id,
|
|
124
123
|
"${intermediary_field_that_points_there}": String(
|
|
125
124
|
link_info["${intermediary_field_that_points_there}"]
|
|
@@ -167,13 +166,16 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
167
166
|
targets
|
|
168
167
|
.map((target) => {
|
|
169
168
|
return {
|
|
170
|
-
selected:
|
|
171
|
-
(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
selected:
|
|
170
|
+
(
|
|
171
|
+
(
|
|
172
|
+
(item.get(
|
|
173
|
+
this.sealious_field.name
|
|
174
|
+
) as string[]) || []
|
|
175
|
+
).includes(target.id)
|
|
176
|
+
) ?
|
|
177
|
+
"on"
|
|
178
|
+
: "off",
|
|
177
179
|
[this.sealious_field.referencing_field]: item.id,
|
|
178
180
|
[this.sealious_field
|
|
179
181
|
.intermediary_field_that_points_there]:
|
|
@@ -60,15 +60,15 @@ export type FieldParseResult<T> =
|
|
|
60
60
|
|
|
61
61
|
export abstract class FormField<
|
|
62
62
|
Required extends boolean = boolean,
|
|
63
|
-
ParsedValue =
|
|
63
|
+
ParsedValue = any,
|
|
64
64
|
DefaultFormControl extends FormControl = FormControl,
|
|
65
65
|
SealiousValue = any,
|
|
66
66
|
> {
|
|
67
|
-
name
|
|
68
|
-
label
|
|
67
|
+
name!: string;
|
|
68
|
+
label!: string;
|
|
69
69
|
constructor(public readonly required: Required) {}
|
|
70
70
|
predicate: Predicate = predicates.unknown;
|
|
71
|
-
mapToFilter: (parsed: ParsedValue) =>
|
|
71
|
+
mapToFilter: (parsed: ParsedValue) => any = (value) => value;
|
|
72
72
|
disabled = false;
|
|
73
73
|
|
|
74
74
|
async init(): Promise<void> {}
|
package/src/forms/fields/file.ts
CHANGED
|
@@ -39,31 +39,37 @@ export class File<Required extends boolean> extends FormField<
|
|
|
39
39
|
parsable: false as const,
|
|
40
40
|
};
|
|
41
41
|
} else {
|
|
42
|
-
const old_file =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
raw_value.old as string | FilePointer
|
|
42
|
+
const old_file =
|
|
43
|
+
(
|
|
44
|
+
hasFieldOfType(
|
|
45
|
+
raw_value,
|
|
46
|
+
"old",
|
|
47
|
+
predicates.instanceOf(PathFilePointer)
|
|
49
48
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
) ?
|
|
50
|
+
await ctx.$app.fileManager.toPointer(raw_value.old)
|
|
51
|
+
: null;
|
|
52
|
+
const new_file =
|
|
53
|
+
(
|
|
54
|
+
hasFieldOfType(
|
|
55
|
+
raw_value,
|
|
56
|
+
"new",
|
|
57
|
+
predicates.or(
|
|
58
|
+
predicates.array(
|
|
59
|
+
predicates.instanceOf(PathFilePointer)
|
|
60
|
+
),
|
|
61
|
+
predicates.instanceOf(PathFilePointer)
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
) ?
|
|
65
|
+
Array.isArray(raw_value.new) ?
|
|
66
|
+
raw_value.new[0]
|
|
67
|
+
: raw_value.new
|
|
68
|
+
: null;
|
|
63
69
|
result = {
|
|
64
70
|
parsable: true as const,
|
|
65
71
|
error: null,
|
|
66
|
-
parsed_value: { old: old_file, new: new_file },
|
|
72
|
+
parsed_value: { old: old_file, new: new_file || null },
|
|
67
73
|
};
|
|
68
74
|
}
|
|
69
75
|
return result;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { Image as ImageControl } from "../controls/image.js";
|
|
2
2
|
import { File as FileField } from "./file.js";
|
|
3
|
-
import { FileContainer } from "../fields/file.js";
|
|
4
|
-
import { FormField } from "./field.js";
|
|
5
3
|
|
|
6
4
|
export class Image<Required extends boolean> extends FileField<Required> {
|
|
7
5
|
getControl(): ImageControl {
|
|
8
|
-
return new ImageControl(
|
|
9
|
-
this as unknown as FormField<boolean, FileContainer>
|
|
10
|
-
);
|
|
6
|
+
return new ImageControl(this);
|
|
11
7
|
}
|
|
12
8
|
}
|
|
@@ -6,7 +6,7 @@ import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
|
6
6
|
|
|
7
7
|
export class PickFromListField<
|
|
8
8
|
Required extends boolean,
|
|
9
|
-
> extends TextBasedSimpleField<Required, Dropdown
|
|
9
|
+
> extends TextBasedSimpleField<Required, Dropdown<Required>> {
|
|
10
10
|
constructor(
|
|
11
11
|
public required: Required,
|
|
12
12
|
public generateOptions: (ctx: Context) => Promise<DropdownOption[]>,
|
|
@@ -50,7 +50,7 @@ export class PickFromListField<
|
|
|
50
50
|
return "";
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
getControl(): Dropdown {
|
|
53
|
+
getControl(): Dropdown<Required> {
|
|
54
54
|
return new Dropdown(this);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -14,7 +14,7 @@ export abstract class SimpleFormField<
|
|
|
14
14
|
Parsed = string,
|
|
15
15
|
> extends FormField<Required, Parsed, DefaultControl> {
|
|
16
16
|
predicate = predicates.string;
|
|
17
|
-
public placeholder
|
|
17
|
+
public placeholder!: string;
|
|
18
18
|
|
|
19
19
|
constructor(
|
|
20
20
|
required: Required,
|
|
@@ -31,7 +31,7 @@ export abstract class SimpleFormField<
|
|
|
31
31
|
return "";
|
|
32
32
|
}
|
|
33
33
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
34
|
-
return String(value)
|
|
34
|
+
return String(value);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
setPlaceholder(placeholder: string) {
|
|
@@ -77,7 +77,7 @@ export class TextBasedSimpleField<
|
|
|
77
77
|
): Promise<void> {}
|
|
78
78
|
|
|
79
79
|
async postSealiousEdit(
|
|
80
|
-
|
|
80
|
+
_ctx: Context,
|
|
81
81
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
82
|
_edited_item: CollectionItem<any>,
|
|
83
83
|
_formData: FormData
|
|
@@ -53,7 +53,7 @@ export class StructuredArray<
|
|
|
53
53
|
[name in keyof SealiousFields]: SealiousToFormField<
|
|
54
54
|
SealiousFields[name]
|
|
55
55
|
>;
|
|
56
|
-
}>(this
|
|
56
|
+
}>(this, {
|
|
57
57
|
label: this.label || this.name,
|
|
58
58
|
subfield_controls: Object.fromEntries(
|
|
59
59
|
Object.entries(this.columns).map(([column_name, subfield]) => [
|
|
@@ -98,8 +98,7 @@ export class StructuredArray<
|
|
|
98
98
|
key,
|
|
99
99
|
await form_subfield.sealiousValueToForm(
|
|
100
100
|
ctx,
|
|
101
|
-
value
|
|
102
|
-
{} as any
|
|
101
|
+
value
|
|
103
102
|
),
|
|
104
103
|
];
|
|
105
104
|
})
|
|
@@ -9,11 +9,9 @@ import {
|
|
|
9
9
|
import { FormControl } from "../controls/form-control.js";
|
|
10
10
|
|
|
11
11
|
export type ExtractFormFieldParsed<Field extends FormField> =
|
|
12
|
-
Field extends FormField<true, infer T>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
? T
|
|
16
|
-
: never;
|
|
12
|
+
Field extends FormField<true, infer T> ? NonNullable<T>
|
|
13
|
+
: Field extends FormField<true, infer T> ? T
|
|
14
|
+
: never;
|
|
17
15
|
|
|
18
16
|
export type TableFieldParsed<F extends Record<string, FormField>> = {
|
|
19
17
|
[field_name in keyof F]: ExtractFormFieldParsed<F[field_name]>;
|
|
@@ -87,8 +85,7 @@ export class Table<F extends Record<string, FormField>> extends FormField<
|
|
|
87
85
|
parsed_value: null,
|
|
88
86
|
};
|
|
89
87
|
}
|
|
90
|
-
|
|
91
|
-
parsed_row[key] = parse_result.parsed_value as any;
|
|
88
|
+
parsed_row[key] = parse_result.parsed_value;
|
|
92
89
|
}
|
|
93
90
|
result.push(parsed_row as { [field_name in keyof F]: unknown });
|
|
94
91
|
}
|
package/src/forms/multiform.ts
CHANGED
|
@@ -3,17 +3,20 @@ import Router from "@koa/router";
|
|
|
3
3
|
import { is, predicates } from "@sealcode/ts-predicates";
|
|
4
4
|
import { Context } from "koa";
|
|
5
5
|
import { FlatTemplatable, tempstream } from "tempstream";
|
|
6
|
-
import {
|
|
6
|
+
import { MountableWithFields } from "../page/mountable-with-fields.js";
|
|
7
7
|
import { attribute } from "../sanitize.js";
|
|
8
8
|
import type { FormDataValue, FormMessage } from "./form-types.js";
|
|
9
9
|
import { Form } from "./form.js";
|
|
10
|
+
import { FormField } from "./fields/field.js";
|
|
10
11
|
|
|
11
12
|
const FIELD_PREFIX_SEPARATOR = "___";
|
|
12
13
|
|
|
13
|
-
export class Multiform
|
|
14
|
+
export class Multiform<
|
|
15
|
+
Forms extends Record<string, Form<Record<string, FormField>, any>> = any,
|
|
16
|
+
> extends MountableWithFields {
|
|
14
17
|
getControls = () => [];
|
|
15
|
-
public name
|
|
16
|
-
public forms
|
|
18
|
+
public name!: string;
|
|
19
|
+
public forms!: Forms;
|
|
17
20
|
|
|
18
21
|
init(path: string, router: Router): void {
|
|
19
22
|
if (this.initialized) {
|
|
@@ -97,11 +100,11 @@ export class Multiform extends MountableWithFields {
|
|
|
97
100
|
show_field_errors: boolean
|
|
98
101
|
): Promise<FlatTemplatable> {
|
|
99
102
|
const form = this.forms[sub_form_name];
|
|
100
|
-
const result = await form
|
|
103
|
+
const result = await form!.canAccess(ctx);
|
|
101
104
|
if (!result.canAccess) {
|
|
102
105
|
return result.message;
|
|
103
106
|
}
|
|
104
|
-
return form
|
|
107
|
+
return form!.render(
|
|
105
108
|
ctx,
|
|
106
109
|
{
|
|
107
110
|
raw_values: await this.getSubformRawValues(ctx, sub_form_name),
|
package/src/generate-routes.ts
CHANGED
|
@@ -51,10 +51,10 @@ export function sortRoutes<T extends { url: string }>(urls: T[]): T[] {
|
|
|
51
51
|
const [segments1, segments2] = [url1, url2].map((url) =>
|
|
52
52
|
url.split("/")
|
|
53
53
|
);
|
|
54
|
-
if (segments1
|
|
54
|
+
if (segments1!.length < segments2!.length) {
|
|
55
55
|
return -1;
|
|
56
56
|
}
|
|
57
|
-
if (segments1
|
|
57
|
+
if (segments1!.length > segments2!.length) {
|
|
58
58
|
return 1;
|
|
59
59
|
}
|
|
60
60
|
// if they are the same length, map each url to a string like 00010
|
|
@@ -63,7 +63,7 @@ export function sortRoutes<T extends { url: string }>(urls: T[]): T[] {
|
|
|
63
63
|
const [encoded1, encoded2] = [url1, url2].map((url) =>
|
|
64
64
|
url.split("/").map((e) => (e.startsWith(":") ? "1" : "0"))
|
|
65
65
|
);
|
|
66
|
-
return encoded1 < encoded2 ? -1 : 1;
|
|
66
|
+
return encoded1! < encoded2! ? -1 : 1;
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
|
package/src/get-fonts.ts
CHANGED
|
@@ -61,11 +61,11 @@ export async function getFonts(_: Record<string, string | boolean> = {}) {
|
|
|
61
61
|
|
|
62
62
|
await Promise.all(
|
|
63
63
|
Object.keys(squirrel_fonts).map((font) => {
|
|
64
|
-
if (squirrel_fonts[font]
|
|
64
|
+
if (squirrel_fonts[font]!.length) {
|
|
65
65
|
return execPromise(
|
|
66
66
|
`node ${path_to_fonsta} install ${font}:${squirrel_fonts[
|
|
67
67
|
font
|
|
68
|
-
]
|
|
68
|
+
]!.join(",")}`,
|
|
69
69
|
{
|
|
70
70
|
cwd: target_locreq.resolve("public"),
|
|
71
71
|
}
|
|
@@ -93,7 +93,11 @@ export async function getFonts(_: Record<string, string | boolean> = {}) {
|
|
|
93
93
|
content.replace(/@font-face {/g, "@font-face {\nfont-display: swap;")
|
|
94
94
|
);
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
try {
|
|
97
|
+
await unlink("public/fonsta.config.json");
|
|
98
|
+
} catch {
|
|
99
|
+
console.info("No fonsta config present, using just google fonts");
|
|
100
|
+
}
|
|
97
101
|
await rmdir("public/tmp");
|
|
98
102
|
console.info("Downloaded new fonts pack from Font Squirrel");
|
|
99
103
|
|
package/src/notifier.ts
CHANGED
|
@@ -77,8 +77,7 @@ async function wait_for_app_restart(app_port: number) {
|
|
|
77
77
|
restart_promise = wait_for_run_id_to_change(app_port);
|
|
78
78
|
await restart_promise;
|
|
79
79
|
} catch (e) {
|
|
80
|
-
|
|
81
|
-
if (e.message !== APP_DOWN_ERROR_MESSAGE) {
|
|
80
|
+
if ((e as Error).message !== APP_DOWN_ERROR_MESSAGE) {
|
|
82
81
|
throw e;
|
|
83
82
|
}
|
|
84
83
|
}
|
package/src/page/list.ts
CHANGED
|
@@ -31,7 +31,7 @@ function decodeSort(s: unknown): ListSort | null {
|
|
|
31
31
|
return null;
|
|
32
32
|
}
|
|
33
33
|
let order = s.split(SORT_SEPARATOR)[1];
|
|
34
|
-
const field = s.split(SORT_SEPARATOR)[0]
|
|
34
|
+
const field = s.split(SORT_SEPARATOR)[0]!;
|
|
35
35
|
if (order !== "asc" && order !== "desc") {
|
|
36
36
|
order = "asc";
|
|
37
37
|
return {
|
|
@@ -151,7 +151,7 @@ export abstract class ListPage<
|
|
|
151
151
|
ctx,
|
|
152
152
|
this.propsParser.overwriteProp(ctx, {
|
|
153
153
|
page: n,
|
|
154
|
-
}
|
|
154
|
+
})
|
|
155
155
|
)}"
|
|
156
156
|
${page === n ? "selected" : ""}
|
|
157
157
|
>
|
|
@@ -177,7 +177,7 @@ export abstract class ListPage<
|
|
|
177
177
|
ctx,
|
|
178
178
|
this.propsParser.overwriteProp(ctx, {
|
|
179
179
|
page,
|
|
180
|
-
}
|
|
180
|
+
})
|
|
181
181
|
)}"
|
|
182
182
|
>${text}</a
|
|
183
183
|
>`;
|
|
@@ -187,7 +187,7 @@ export abstract class ListPage<
|
|
|
187
187
|
const filter = {} as Record<string, unknown>;
|
|
188
188
|
const raw_values = await this.extractRawValues(ctx);
|
|
189
189
|
for (const [fieldname, field] of Object.entries(this.filterFields)) {
|
|
190
|
-
// eslint-disable-next-line no-await-in-loop
|
|
190
|
+
// eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-unsafe-assignment
|
|
191
191
|
const { parsed } = await field.getParsedValue(ctx, raw_values);
|
|
192
192
|
filter[fieldname] = field.mapToFilter(parsed);
|
|
193
193
|
}
|
|
@@ -18,7 +18,7 @@ describe("mountable-with-fields", () => {
|
|
|
18
18
|
// this should not throw a Typescript error
|
|
19
19
|
data.not_required?.trim();
|
|
20
20
|
// this should work without the optional chaining:
|
|
21
|
-
data.required.trim();
|
|
21
|
+
(data.required || "").trim();
|
|
22
22
|
const { parsed: data2 } = await this.fields.not_required.getParsedValue(
|
|
23
23
|
ctx,
|
|
24
24
|
form_values.raw_values
|
|
@@ -28,17 +28,17 @@ type ParsedValue<T extends FormField> = Resolved<
|
|
|
28
28
|
export abstract class MountableWithFields<
|
|
29
29
|
F extends Fields = Fields,
|
|
30
30
|
> extends Mountable {
|
|
31
|
-
getFields
|
|
31
|
+
getFields!: () => F;
|
|
32
32
|
fields: F;
|
|
33
33
|
initialized = false;
|
|
34
34
|
field_names_prefix = ""; // useful for multiform, where many forms are merged into one and field assignment is made using the prefix
|
|
35
35
|
form_id = ""; // all fields within this mountable will be tied to form of this id
|
|
36
36
|
abstract getControls: (fields: F) => FormControl[];
|
|
37
|
-
controls
|
|
37
|
+
controls!: FormControl[];
|
|
38
38
|
|
|
39
39
|
constructor() {
|
|
40
40
|
super();
|
|
41
|
-
|
|
41
|
+
this.fields = {} as F;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** most routes should be setup using .mount(), but mount runs before
|
|
@@ -113,7 +113,7 @@ export abstract class MountableWithFields<
|
|
|
113
113
|
|
|
114
114
|
await Promise.all(
|
|
115
115
|
Object.keys(this.fields).map(async (key: keyof F) => {
|
|
116
|
-
const field = this.fields[key]
|
|
116
|
+
const field = this.fields[key]!;
|
|
117
117
|
const { valid: fieldvalid, message: fieldmessage } =
|
|
118
118
|
await field.getParsedValue(ctx, values, true);
|
|
119
119
|
if (!fieldvalid) {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
CollectionItem,
|
|
10
10
|
ItemList,
|
|
11
11
|
Context as SealiousContext,
|
|
12
|
-
|
|
12
|
+
ExtractFilterParams,
|
|
13
13
|
} from "sealious";
|
|
14
14
|
import { FlatTemplatable, Templatable, tempstream } from "tempstream";
|
|
15
15
|
import { peopleWhoCan } from "./access-control.js";
|
|
@@ -44,7 +44,13 @@ export abstract class SealiousItemListPage<
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
if (Object.keys(filters).length) {
|
|
47
|
-
list.filter(
|
|
47
|
+
list.filter(
|
|
48
|
+
filters as Partial<{
|
|
49
|
+
[FieldName in keyof C["fields"]]: ExtractFilterParams<
|
|
50
|
+
C["fields"][FieldName]
|
|
51
|
+
> | null;
|
|
52
|
+
}>
|
|
53
|
+
);
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
56
|
|
|
@@ -74,12 +80,15 @@ export abstract class SealiousItemListPage<
|
|
|
74
80
|
async getFilterValues(ctx: Context) {
|
|
75
81
|
const query_params = qs.parse(ctx.search.slice(1));
|
|
76
82
|
const _filter_values = query_params?.filter || {};
|
|
77
|
-
const filter_values: Record<string, string | undefined> =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const filter_values: Record<string, string | undefined> =
|
|
84
|
+
(
|
|
85
|
+
is(
|
|
86
|
+
_filter_values,
|
|
87
|
+
predicates.record(predicates.string, predicates.string)
|
|
88
|
+
)
|
|
89
|
+
) ?
|
|
90
|
+
_filter_values
|
|
91
|
+
: {};
|
|
83
92
|
for (const key in filter_values) {
|
|
84
93
|
if (filter_values[key] == "") {
|
|
85
94
|
delete filter_values[key];
|
|
@@ -53,7 +53,7 @@ export type ExtractStatefulPageActionArgs<X> =
|
|
|
53
53
|
|
|
54
54
|
export abstract class StatefulPage<
|
|
55
55
|
State extends Record<string, unknown>,
|
|
56
|
-
Actions extends Record<string, StatefulPageAction<State>>,
|
|
56
|
+
Actions extends Record<string, StatefulPageAction<State, any>>,
|
|
57
57
|
> extends Mountable {
|
|
58
58
|
abstract actions: Actions;
|
|
59
59
|
abstract getInitialState(ctx: Context): State | Promise<State>;
|
|
@@ -27,7 +27,7 @@ export async function jddEditorTemplate(actionName: string) {
|
|
|
27
27
|
|
|
28
28
|
let field_name = "";
|
|
29
29
|
if (jdd_fields.length == 1) {
|
|
30
|
-
field_name = jdd_fields[0]
|
|
30
|
+
field_name = jdd_fields[0]!.name;
|
|
31
31
|
console.info(
|
|
32
32
|
`Only one field of type JDD found: ${field_name}, so skipping the question...`
|
|
33
33
|
);
|
|
@@ -20,11 +20,11 @@ const sealious_minimal_url =
|
|
|
20
20
|
const sealious_minimal_commit = "77e3794";
|
|
21
21
|
|
|
22
22
|
export class RealAppTest {
|
|
23
|
-
public node_pid
|
|
24
|
-
public app_port
|
|
25
|
-
public mongo_port
|
|
26
|
-
public app_path
|
|
27
|
-
public container_name
|
|
23
|
+
public node_pid!: number;
|
|
24
|
+
public app_port!: number;
|
|
25
|
+
public mongo_port!: number;
|
|
26
|
+
public app_path!: string;
|
|
27
|
+
public container_name!: string;
|
|
28
28
|
public emitter = new EventEmitter();
|
|
29
29
|
|
|
30
30
|
static async init(): Promise<RealAppTest> {
|
package/tsconfig.json
CHANGED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { FlatTemplatable, tempstream } from "tempstream";
|
|
2
|
-
import { FormField } from "../fields/field.js";
|
|
3
|
-
import { FormControlContext } from "./form-control.js";
|
|
4
|
-
import { FormFieldControl } from "./form-field-control.js";
|
|
5
|
-
|
|
6
|
-
export class BigRadioGroup extends FormFieldControl {
|
|
7
|
-
constructor(
|
|
8
|
-
public field: FormField,
|
|
9
|
-
public options: Record<
|
|
10
|
-
string,
|
|
11
|
-
{
|
|
12
|
-
description:
|
|
13
|
-
| FlatTemplatable
|
|
14
|
-
| ((fctx: FormControlContext) => FlatTemplatable);
|
|
15
|
-
}
|
|
16
|
-
>
|
|
17
|
-
) {
|
|
18
|
-
super([field]);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async render(fctx: FormControlContext): Promise<FlatTemplatable> {
|
|
22
|
-
const { raw: current_value } = await this.field.getParsedValue(
|
|
23
|
-
fctx.ctx,
|
|
24
|
-
fctx.data.raw_values
|
|
25
|
-
);
|
|
26
|
-
return tempstream /* HTML */ `<div class="bigradios">
|
|
27
|
-
${Object.entries(this.options).map(([key, { description }]) => {
|
|
28
|
-
const id = `${this.field.name}-radio-${key}`;
|
|
29
|
-
return tempstream /* HTML */ `<input
|
|
30
|
-
type="radio"
|
|
31
|
-
name="${this.field.name}"
|
|
32
|
-
value="${key}"
|
|
33
|
-
id="${id}"
|
|
34
|
-
style="display: none"
|
|
35
|
-
${fctx.form_id ? `form=${fctx.form_id}` : ""}
|
|
36
|
-
${this.field.required ? "required" : ""}
|
|
37
|
-
${key == current_value ? "checked" : ""}
|
|
38
|
-
/>
|
|
39
|
-
<div class="bigradio">
|
|
40
|
-
${typeof description == "function"
|
|
41
|
-
? description(fctx)
|
|
42
|
-
: description}
|
|
43
|
-
<label class="bigradio__cta" for="${id}">Wybierz</label>
|
|
44
|
-
</div>`;
|
|
45
|
-
})}
|
|
46
|
-
</div>`;
|
|
47
|
-
}
|
|
48
|
-
}
|