@sealcode/sealgen 0.19.0 → 0.19.3
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/fields/deep-reverse-single-reference-list.d.ts +1 -5
- package/@types/forms/fields/file.d.ts +1 -1
- package/@types/forms/fields/password.d.ts +1 -2
- package/@types/forms/fields/simple-form-field.d.ts +4 -4
- package/@types/forms/fields/single-reference.d.ts +1 -1
- package/@types/register-external.d.ts +2 -2
- package/@types/templates/form.d.ts +1 -3
- package/@types/templates/jdd-component.d.ts +1 -1
- package/@types/templates/page.d.ts +1 -1
- package/@types/templates/shared/shared-crud-form-fields.d.ts +1 -1
- package/@types/templates/templates.d.ts +1 -21
- package/eslint.config.mjs +56 -0
- package/lib/add-crud.js +1 -4
- package/lib/add-jdd-component.js +3 -3
- package/lib/add-route.js +2 -2
- package/lib/build.js +3 -3
- package/lib/builders/backend-ts-builder.js +0 -1
- package/lib/builders/colors-builder.js +11 -8
- package/lib/builders/fonts-builder.js +0 -1
- package/lib/builders/frontend-ts-builder.js +0 -1
- package/lib/cli.js +2 -2
- package/lib/components/tabs.js +36 -36
- package/lib/esbuild-plugins/rewrite-asset-imports.js +7 -10
- package/lib/forms/controls/array.js +5 -6
- package/lib/forms/controls/checkboxed-list-input.js +1 -2
- package/lib/forms/controls/checkboxed-list-input.test.js +6 -6
- package/lib/forms/controls/derived-frame.js +3 -3
- package/lib/forms/controls/dropdown.js +1 -2
- package/lib/forms/controls/file.test.js +1 -1
- package/lib/forms/controls/form-control.js +1 -1
- package/lib/forms/controls/image.test.js +2 -2
- package/lib/forms/controls/single-reference.test.js +1 -1
- package/lib/forms/controls/table.js +10 -15
- package/lib/forms/controls/textarea.js +1 -1
- package/lib/forms/fields/deep-reverse-single-reference-list.js +1 -1
- package/lib/forms/fields/field.test.js +3 -3
- package/lib/forms/fields/file.js +1 -1
- package/lib/forms/fields/file.test.js +1 -1
- package/lib/forms/fields/password.js +1 -1
- package/lib/forms/fields/simple-form-field.js +4 -3
- package/lib/forms/fields/single-reference.js +1 -1
- package/lib/forms/fields/structured-array.js +0 -2
- package/lib/forms/fields/table.js +1 -1
- package/lib/forms/form.js +0 -1
- package/lib/forms/form.test.js +2 -3
- package/lib/forms/multiform.js +6 -7
- package/lib/forms/multiform.test.js +2 -2
- package/lib/generate-collections.js +2 -3
- package/lib/generate-components.js +2 -3
- package/lib/generate-routes.js +3 -5
- package/lib/generate-routes.test.js +7 -16
- package/lib/generate-stimulus.js +4 -5
- package/lib/get-fonts.js +29 -27
- package/lib/make-env.js +1 -1
- package/lib/make-hidden-inputs.js +4 -4
- package/lib/mount.js +0 -1
- package/lib/notifier.js +3 -3
- package/lib/page/list.js +5 -7
- package/lib/page/mountable.js +0 -1
- package/lib/page/page.js +0 -1
- package/lib/register-external.js +4 -4
- package/lib/templates/form.js +1 -1
- package/lib/templates/jdd-component.js +1 -1
- package/lib/templates/jdd-editor.js +1 -1
- package/lib/templates/page.js +1 -1
- package/lib/templates/shared/collection-create-form.js +4 -5
- package/lib/templates/shared/collection-edit-form.js +4 -5
- package/lib/templates/shared/collection-list.js +2 -2
- package/lib/templates/shared/shared-crud-form-fields.js +3 -5
- package/lib/test_utils/exec_async.js +3 -3
- package/lib/test_utils/test-on-real-app.js +9 -11
- package/lib/utils/write-file.js +1 -1
- package/package.json +9 -8
- package/src/add-collection.ts +1 -3
- package/src/add-crud.ts +2 -7
- package/src/add-jdd-component.ts +4 -5
- package/src/add-route.ts +3 -6
- package/src/build.ts +3 -3
- package/src/builders/backend-ts-builder.ts +0 -1
- package/src/builders/builder.ts +4 -1
- package/src/builders/colors-builder.ts +11 -9
- package/src/builders/css-builder.ts +4 -1
- package/src/builders/fonts-builder.ts +0 -1
- package/src/builders/frontend-ts-builder.ts +0 -1
- package/src/cli.ts +2 -2
- package/src/components/tabs.ts +38 -37
- package/src/components/toggle-modal.ts +1 -1
- package/src/controllers/table-add-button.stimulus.ts +1 -1
- package/src/esbuild-plugins/rewrite-asset-imports.ts +7 -10
- package/src/forms/controls/array.ts +12 -16
- package/src/forms/controls/autocomplete.ts +1 -1
- package/src/forms/controls/big-radio-group.ts +2 -2
- package/src/forms/controls/checkbox-group.ts +1 -1
- package/src/forms/controls/checkboxed-list-input.test.ts +6 -6
- package/src/forms/controls/checkboxed-list-input.ts +18 -22
- package/src/forms/controls/derived-frame.ts +11 -10
- package/src/forms/controls/derived.ts +6 -5
- package/src/forms/controls/dropdown.ts +8 -11
- package/src/forms/controls/editable-collection-subset.ts +2 -1
- package/src/forms/controls/field-group.ts +1 -1
- package/src/forms/controls/file.test.ts +1 -1
- package/src/forms/controls/file.ts +4 -7
- package/src/forms/controls/form-control.ts +1 -1
- package/src/forms/controls/hidden-input.ts +1 -0
- package/src/forms/controls/html.ts +1 -0
- package/src/forms/controls/image.test.ts +2 -2
- package/src/forms/controls/image.ts +1 -1
- package/src/forms/controls/multiple-files.ts +5 -7
- package/src/forms/controls/multiple-images.ts +1 -1
- package/src/forms/controls/simple-input.ts +8 -4
- package/src/forms/controls/single-reference.test.ts +1 -1
- package/src/forms/controls/single-reference.ts +1 -1
- package/src/forms/controls/table.ts +16 -21
- package/src/forms/controls/textarea.ts +1 -1
- package/src/forms/controls/tickable.ts +0 -2
- package/src/forms/fields/boolean.ts +4 -1
- package/src/forms/fields/checkboxed-list.ts +1 -1
- package/src/forms/fields/collection-field.ts +5 -2
- package/src/forms/fields/color.ts +1 -1
- package/src/forms/fields/coordinates.ts +2 -2
- package/src/forms/fields/deep-reverse-single-reference-list.ts +2 -8
- package/src/forms/fields/deep-reverse-single-reference-table.ts +1 -1
- package/src/forms/fields/email.ts +1 -1
- package/src/forms/fields/enum-multiple-sealious.ts +1 -1
- package/src/forms/fields/existing-sealious-value.ts +1 -1
- package/src/forms/fields/field.test.ts +3 -3
- package/src/forms/fields/field.ts +6 -5
- package/src/forms/fields/file.test.ts +1 -1
- package/src/forms/fields/file.ts +2 -2
- package/src/forms/fields/float.ts +1 -1
- package/src/forms/fields/get-field-for-sealious.ts +97 -64
- package/src/forms/fields/int.ts +1 -1
- package/src/forms/fields/number.ts +2 -2
- package/src/forms/fields/password.ts +2 -6
- package/src/forms/fields/pick-from-list-sealious.ts +1 -1
- package/src/forms/fields/pick-from-list.ts +1 -1
- package/src/forms/fields/proxy-field.ts +1 -0
- package/src/forms/fields/simple-form-field.ts +19 -9
- package/src/forms/fields/single-reference.ts +2 -2
- package/src/forms/fields/structured-array.ts +2 -6
- package/src/forms/fields/table.ts +7 -15
- package/src/forms/fields/text.ts +1 -1
- package/src/forms/fields/url.ts +1 -1
- package/src/forms/form-types.ts +3 -4
- package/src/forms/form.test.ts +2 -3
- package/src/forms/form.ts +5 -7
- package/src/forms/multiform.test.ts +6 -6
- package/src/forms/multiform.ts +10 -10
- package/src/generate-collections.ts +2 -3
- package/src/generate-components.ts +2 -3
- package/src/generate-routes.test.ts +7 -16
- package/src/generate-routes.ts +6 -10
- package/src/generate-stimulus.ts +4 -6
- package/src/get-fonts.ts +32 -30
- package/src/make-env.ts +1 -1
- package/src/make-hidden-inputs.ts +8 -7
- package/src/mount.ts +2 -7
- package/src/notifier.ts +4 -6
- package/src/page/default-list-filters.ts +1 -0
- package/src/page/list.ts +18 -20
- package/src/page/mountable-with-fields.ts +3 -3
- package/src/page/mountable.ts +0 -1
- package/src/page/page.ts +2 -3
- package/src/page/props-parser.ts +1 -1
- package/src/page/sealious-list.ts +1 -1
- package/src/page/stateful-page.ts +6 -10
- package/src/register-external.ts +4 -4
- package/src/templates/form.ts +1 -2
- package/src/templates/jdd-component.ts +1 -1
- package/src/templates/jdd-editor.ts +2 -4
- package/src/templates/list.ts +0 -1
- package/src/templates/page.ts +1 -4
- package/src/templates/shared/collection-create-form.ts +5 -6
- package/src/templates/shared/collection-edit-form.ts +5 -6
- package/src/templates/shared/collection-list.ts +2 -2
- package/src/templates/shared/shared-crud-form-fields.ts +4 -9
- package/src/templates/templates.ts +5 -1
- package/src/test_utils/exec_async.ts +3 -4
- package/src/test_utils/test-on-real-app.ts +9 -11
- package/src/utils/browser-creator.js +0 -1
- package/src/utils/exec.ts +0 -1
- package/src/utils/input-wrapper.ts +1 -1
- package/src/utils/wrap-attributes.ts +1 -1
- package/src/utils/write-file.ts +1 -1
- package/.eslintrc.cjs +0 -44
|
@@ -9,19 +9,11 @@ import {
|
|
|
9
9
|
import { FormControl } from "../controls/form-control.js";
|
|
10
10
|
|
|
11
11
|
export type ExtractFormFieldParsed<Field extends FormField> =
|
|
12
|
-
Field extends FormField<
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
-
true,
|
|
15
|
-
infer T
|
|
16
|
-
>
|
|
12
|
+
Field extends FormField<true, infer T>
|
|
17
13
|
? NonNullable<T>
|
|
18
|
-
: Field extends FormField<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
infer T
|
|
22
|
-
>
|
|
23
|
-
? T
|
|
24
|
-
: never;
|
|
14
|
+
: Field extends FormField<true, infer T>
|
|
15
|
+
? T
|
|
16
|
+
: never;
|
|
25
17
|
|
|
26
18
|
export type TableFieldParsed<F extends Record<string, FormField>> = {
|
|
27
19
|
[field_name in keyof F]: ExtractFormFieldParsed<F[field_name]>;
|
|
@@ -66,9 +58,10 @@ export class Table<F extends Record<string, FormField>> extends FormField<
|
|
|
66
58
|
const row_data = raw_value[row_number];
|
|
67
59
|
const parsed_row: Record<string, unknown> = {};
|
|
68
60
|
if (!is(row_data, predicates.object)) {
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
69
62
|
throw new Error(`Expected object, got ${String(row_data)}`);
|
|
70
63
|
}
|
|
71
|
-
for (const key
|
|
64
|
+
for (const key of Object.keys(row_data)) {
|
|
72
65
|
const field = this.columns[key];
|
|
73
66
|
if (field == undefined) {
|
|
74
67
|
return {
|
|
@@ -94,10 +87,9 @@ export class Table<F extends Record<string, FormField>> extends FormField<
|
|
|
94
87
|
parsed_value: null,
|
|
95
88
|
};
|
|
96
89
|
}
|
|
97
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
91
|
parsed_row[key] = parse_result.parsed_value as any;
|
|
99
92
|
}
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
101
93
|
result.push(parsed_row as { [field_name in keyof F]: unknown });
|
|
102
94
|
}
|
|
103
95
|
const ret = { parsed_value: result, parsable: true, error: null };
|
package/src/forms/fields/text.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { FormControlContext } from "../controls/form-control.js";
|
|
|
2
2
|
import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
3
3
|
|
|
4
4
|
export class Text<
|
|
5
|
-
Required extends boolean
|
|
5
|
+
Required extends boolean,
|
|
6
6
|
> extends TextBasedSimpleField<Required> {
|
|
7
7
|
constructor(required: Required) {
|
|
8
8
|
super(required, "text");
|
package/src/forms/fields/url.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { FormControlContext } from "../controls/form-control.js";
|
|
|
2
2
|
import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
3
3
|
|
|
4
4
|
export class URLField<
|
|
5
|
-
Required extends boolean
|
|
5
|
+
Required extends boolean,
|
|
6
6
|
> extends TextBasedSimpleField<Required> {
|
|
7
7
|
constructor(required: Required) {
|
|
8
8
|
super(required, "text");
|
package/src/forms/form-types.ts
CHANGED
|
@@ -14,12 +14,11 @@ export type FormDataValue =
|
|
|
14
14
|
| FormDataPrimitive
|
|
15
15
|
| Record<string, FormDataPrimitive>;
|
|
16
16
|
|
|
17
|
-
export type FieldValueType<F extends FormField> =
|
|
18
|
-
? R
|
|
19
|
-
: never;
|
|
17
|
+
export type FieldValueType<F extends FormField> =
|
|
18
|
+
F extends FormField<infer R> ? R : never;
|
|
20
19
|
|
|
21
20
|
export type FormFieldsToValues<
|
|
22
|
-
F extends Record<string, FormField<boolean, keyof F
|
|
21
|
+
F extends Record<string, FormField<boolean, keyof F>>,
|
|
23
22
|
> = {
|
|
24
23
|
[Property in keyof F]: FieldValueType<F[Property]>;
|
|
25
24
|
};
|
package/src/forms/form.test.ts
CHANGED
|
@@ -36,7 +36,7 @@ export function form_factory(canAccessFun?: Mountable["canAccess"]): Form<typeof
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const port = await getPort();
|
|
39
|
-
console.
|
|
39
|
+
console.info("Using port " + port + " for form.test.ts");
|
|
40
40
|
|
|
41
41
|
describe("form test", () => {
|
|
42
42
|
let page: Page;
|
|
@@ -91,7 +91,6 @@ describe("form test", () => {
|
|
|
91
91
|
},
|
|
92
92
|
}
|
|
93
93
|
);
|
|
94
|
-
console.log(res_axios.data);
|
|
95
94
|
if (!res_axios.data.includes("Some fields are invalid")) {
|
|
96
95
|
throw new Error("when sending a empty request with axios, the error didnt appear");
|
|
97
96
|
}
|
|
@@ -348,7 +347,7 @@ describe("form test", () => {
|
|
|
348
347
|
await page.getByPlaceholder("text").click();
|
|
349
348
|
await page.getByPlaceholder("text").fill("yes@an.email");
|
|
350
349
|
await page.getByRole("button", { name: "Submit" }).click();
|
|
351
|
-
assertThrowsAsync(async () => {
|
|
350
|
+
await assertThrowsAsync(async () => {
|
|
352
351
|
return page
|
|
353
352
|
.getByText("Please enter a proper email address")
|
|
354
353
|
.click({ timeout: 500 });
|
package/src/forms/form.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { Errors as SealiousErrors } from "sealious";
|
|
|
29
29
|
|
|
30
30
|
export abstract class Form<
|
|
31
31
|
F extends Fields,
|
|
32
|
-
SubmitResult
|
|
32
|
+
SubmitResult,
|
|
33
33
|
> extends MountableWithFields<F> {
|
|
34
34
|
defaultSuccessMessage = "Done";
|
|
35
35
|
submitButtonText = "Wyślij";
|
|
@@ -38,7 +38,6 @@ export abstract class Form<
|
|
|
38
38
|
form_id = randomUUID() as string;
|
|
39
39
|
|
|
40
40
|
async canAccess(
|
|
41
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
42
41
|
_: Context
|
|
43
42
|
): Promise<{ canAccess: boolean; message: string }> {
|
|
44
43
|
return { canAccess: true, message: "" };
|
|
@@ -48,7 +47,7 @@ export abstract class Form<
|
|
|
48
47
|
_: Context,
|
|
49
48
|
error: PageErrorMessage
|
|
50
49
|
): Promise<JSX.Element | Readable> {
|
|
51
|
-
return tempstream/* HTML */ `<div>${error.message}</div>`;
|
|
50
|
+
return tempstream /* HTML */ `<div>${error.message}</div>`;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
makeSubmitButton(): JSX.Element {
|
|
@@ -65,7 +64,7 @@ export abstract class Form<
|
|
|
65
64
|
data: FormData,
|
|
66
65
|
show_field_errors: boolean
|
|
67
66
|
): Promise<JSX.Element | Readable> {
|
|
68
|
-
return tempstream/* HTML */ `<div class="form-container">
|
|
67
|
+
return tempstream /* HTML */ `<div class="form-container">
|
|
69
68
|
${this.makeOpenFormTag(ctx)}
|
|
70
69
|
${!this.controls.some((control) => control.role == "messages")
|
|
71
70
|
? this.renderMessages(ctx, data)
|
|
@@ -80,7 +79,6 @@ export abstract class Form<
|
|
|
80
79
|
</div>`;
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
84
82
|
public async makeFormClasses(_ctx: Context): Promise<string[]> {
|
|
85
83
|
return [];
|
|
86
84
|
}
|
|
@@ -223,8 +221,8 @@ export abstract class Form<
|
|
|
223
221
|
hasFieldOfType(e, "message", predicates.string)
|
|
224
222
|
? e?.message
|
|
225
223
|
: is(e, predicates.string)
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
? e
|
|
225
|
+
: "Wystąpił błąd";
|
|
228
226
|
|
|
229
227
|
return this.onError(
|
|
230
228
|
ctx,
|
|
@@ -19,7 +19,7 @@ import { EmailField } from "./fields/email.js";
|
|
|
19
19
|
import getPort from "get-port";
|
|
20
20
|
|
|
21
21
|
const port = await getPort();
|
|
22
|
-
console.
|
|
22
|
+
console.info(`Using port ${port} form multiform.test.ts`);
|
|
23
23
|
|
|
24
24
|
const fields1 = {
|
|
25
25
|
email: new TextBasedSimpleField(true),
|
|
@@ -58,7 +58,7 @@ function multiform_factory(
|
|
|
58
58
|
form2: form_factory(canAccessFun2),
|
|
59
59
|
};
|
|
60
60
|
async render(...args: Parameters<Multiform["render"]>): Promise<FlatTemplatable> {
|
|
61
|
-
return tempstream/* HTML */ `<!DOCTYPE html>
|
|
61
|
+
return tempstream /* HTML */ `<!DOCTYPE html>
|
|
62
62
|
<html>
|
|
63
63
|
<head>
|
|
64
64
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -147,7 +147,7 @@ async function individual_field_validation_e2e_tests(javaScriptEnabled: boolean)
|
|
|
147
147
|
await page.getByPlaceholder("text").click();
|
|
148
148
|
await page.getByPlaceholder("text").fill("yes@an.email");
|
|
149
149
|
await page.locator("#multiform_test_form1_submit").click();
|
|
150
|
-
assertThrowsAsync(async () => {
|
|
150
|
+
await assertThrowsAsync(async () => {
|
|
151
151
|
return page.getByText("Please enter a proper email address").click({ timeout: 500 });
|
|
152
152
|
});
|
|
153
153
|
});
|
|
@@ -173,7 +173,7 @@ describe("multiform test", () => {
|
|
|
173
173
|
prerenderedForms?: Record<string, FlatTemplatable | undefined>,
|
|
174
174
|
show_field_errors = true
|
|
175
175
|
): Promise<FlatTemplatable> {
|
|
176
|
-
return tempstream/* HTML */ `<!DOCTYPE html>
|
|
176
|
+
return tempstream /* HTML */ `<!DOCTYPE html>
|
|
177
177
|
<html>
|
|
178
178
|
<head>
|
|
179
179
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -455,7 +455,7 @@ describe("multiform test", () => {
|
|
|
455
455
|
async render(
|
|
456
456
|
...args: Parameters<Multiform["render"]>
|
|
457
457
|
): Promise<FlatTemplatable> {
|
|
458
|
-
return tempstream/* HTML */ `<!DOCTYPE html>
|
|
458
|
+
return tempstream /* HTML */ `<!DOCTYPE html>
|
|
459
459
|
<html>
|
|
460
460
|
<head>
|
|
461
461
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -518,7 +518,7 @@ describe("multiform test", () => {
|
|
|
518
518
|
async render(
|
|
519
519
|
...args: Parameters<Multiform["render"]>
|
|
520
520
|
): Promise<FlatTemplatable> {
|
|
521
|
-
return tempstream/* HTML */ `<!DOCTYPE html>
|
|
521
|
+
return tempstream /* HTML */ `<!DOCTYPE html>
|
|
522
522
|
<html>
|
|
523
523
|
<head>
|
|
524
524
|
<title>Multiform Test - Sealgen</title>
|
package/src/forms/multiform.ts
CHANGED
|
@@ -35,13 +35,14 @@ export class Multiform extends MountableWithFields {
|
|
|
35
35
|
this.getSubformRawValues(context, key);
|
|
36
36
|
const submit_button_id = this.name + "_" + key + "_submit";
|
|
37
37
|
|
|
38
|
-
form.makeSubmitButton = () =>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
form.makeSubmitButton = () =>
|
|
39
|
+
/* HTML */ `<input
|
|
40
|
+
type="submit"
|
|
41
|
+
value="${form.submitButtonText}"
|
|
42
|
+
formaction="${form.action}"
|
|
43
|
+
id="${submit_button_id}"
|
|
44
|
+
${form.form_id ? `form="${form.form_id}"` : ""}
|
|
45
|
+
/> `;
|
|
45
46
|
}
|
|
46
47
|
for (const form of Object.values(this.forms)) {
|
|
47
48
|
for (const field of Object.values(form.fields)) {
|
|
@@ -68,7 +69,6 @@ export class Multiform extends MountableWithFields {
|
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
72
|
getSubformsToRender(
|
|
73
73
|
ctx: Context
|
|
74
74
|
): Array<readonly [string, Form<any, unknown>]> {
|
|
@@ -132,7 +132,7 @@ export class Multiform extends MountableWithFields {
|
|
|
132
132
|
prerenderedForms: Record<string, FlatTemplatable | undefined> = {},
|
|
133
133
|
show_field_errors: boolean
|
|
134
134
|
): Promise<FlatTemplatable> {
|
|
135
|
-
return tempstream/* HTML */ `${this.renderMessages(ctx, {
|
|
135
|
+
return tempstream /* HTML */ `${this.renderMessages(ctx, {
|
|
136
136
|
raw_values: {},
|
|
137
137
|
messages,
|
|
138
138
|
field_messages: {},
|
|
@@ -149,7 +149,7 @@ export class Multiform extends MountableWithFields {
|
|
|
149
149
|
${this.getSubformsToRender(ctx).map(([form_name]) => {
|
|
150
150
|
const frame_form_id =
|
|
151
151
|
this.name + "_" + form_name + "_frame_form";
|
|
152
|
-
return tempstream/* HTML */ `<turbo-frame
|
|
152
|
+
return tempstream /* HTML */ `<turbo-frame
|
|
153
153
|
id="${form_name}"
|
|
154
154
|
contains-subform
|
|
155
155
|
subform-id="${frame_form_id}"
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import _locreq from "locreq";
|
|
2
|
-
import * as prettier from "prettier";
|
|
3
2
|
import { promises as fs } from "fs";
|
|
4
3
|
import { assertType, predicates } from "@sealcode/ts-predicates";
|
|
5
|
-
import {
|
|
4
|
+
import { formatWithPrettier } from "./utils/prettier.js";
|
|
6
5
|
|
|
7
6
|
const target_locreq = _locreq(process.cwd());
|
|
8
7
|
|
|
@@ -69,7 +68,7 @@ ${file_data
|
|
|
69
68
|
};`;
|
|
70
69
|
await fs.writeFile(
|
|
71
70
|
target_locreq.resolve("src/back/collections/collections.ts"),
|
|
72
|
-
|
|
71
|
+
await formatWithPrettier(content)
|
|
73
72
|
);
|
|
74
73
|
// eslint-disable-next-line no-console
|
|
75
74
|
console.log(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _locreq from "locreq";
|
|
2
|
-
import * as prettier from "prettier";
|
|
3
2
|
import { promises as fs } from "fs";
|
|
4
|
-
import {
|
|
3
|
+
import { formatWithPrettier } from "./utils/prettier.js";
|
|
5
4
|
import recursive from "recursive-readdir";
|
|
6
5
|
import path from "path";
|
|
7
6
|
import { toKebabCase, toPascalCase } from "js-convert-case";
|
|
@@ -40,7 +39,7 @@ ${component_data
|
|
|
40
39
|
const target = "src/back/jdd-components/components.ts";
|
|
41
40
|
await fs.writeFile(
|
|
42
41
|
target_locreq.resolve(target),
|
|
43
|
-
|
|
42
|
+
await formatWithPrettier(content)
|
|
44
43
|
);
|
|
45
44
|
// eslint-disable-next-line no-console
|
|
46
45
|
console.log(`Successfuly generated new ${target} file`);
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { generateURL, sortRoutes } from "./generate-routes.js";
|
|
2
|
-
import
|
|
3
|
-
import { getPrettierConfig } from "./utils/prettier.js";
|
|
2
|
+
import { formatWithPrettier } from "./utils/prettier.js";
|
|
4
3
|
import assert from "node:assert";
|
|
5
4
|
|
|
6
5
|
describe("generate routes", () => {
|
|
7
6
|
it("handles a url with params", async () => {
|
|
8
7
|
assert.strictEqual(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
await getPrettierConfig()
|
|
12
|
-
),
|
|
13
|
-
prettier.format(
|
|
8
|
+
await formatWithPrettier(generateURL("EditUser", "/admin/users/:id/edit/")),
|
|
9
|
+
await formatWithPrettier(
|
|
14
10
|
`export const EditUserURL = (id: string) => \`/admin/users/\${id}/edit/\`;
|
|
15
11
|
EditUserURL.params = ["id"];
|
|
16
|
-
EditUserURL.rawURL = "/admin/users/:id/edit/"
|
|
17
|
-
await getPrettierConfig()
|
|
12
|
+
EditUserURL.rawURL = "/admin/users/:id/edit/";`
|
|
18
13
|
)
|
|
19
14
|
);
|
|
20
15
|
});
|
|
@@ -28,15 +23,11 @@ EditUserURL.rawURL = "/admin/users/:id/edit/";`,
|
|
|
28
23
|
|
|
29
24
|
it("handles a url with params and diacritics", async () => {
|
|
30
25
|
assert.strictEqual(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
await getPrettierConfig()
|
|
34
|
-
),
|
|
35
|
-
prettier.format(
|
|
26
|
+
await formatWithPrettier(generateURL("EditUser", "/admin/użytkownicy/:id/edit/")),
|
|
27
|
+
await formatWithPrettier(
|
|
36
28
|
`export const EditUserURL = (id: string) => \`/admin/u%C5%BCytkownicy/\${id}/edit/\`;
|
|
37
29
|
EditUserURL.params = ["id"];
|
|
38
|
-
EditUserURL.rawURL = "/admin/u%C5%BCytkownicy/:id/edit/"
|
|
39
|
-
await getPrettierConfig()
|
|
30
|
+
EditUserURL.rawURL = "/admin/u%C5%BCytkownicy/:id/edit/";`
|
|
40
31
|
)
|
|
41
32
|
);
|
|
42
33
|
});
|
package/src/generate-routes.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { promises as fs } from "fs";
|
|
2
|
-
import * as prettier from "prettier";
|
|
3
2
|
import { relative, resolve, basename } from "path";
|
|
4
3
|
import _locreq from "locreq";
|
|
5
4
|
import { walkDir } from "./utils/walk.js";
|
|
6
5
|
import { importPath } from "./utils/import-path.js";
|
|
7
6
|
import { assertType, predicates } from "@sealcode/ts-predicates";
|
|
8
7
|
import { unescape_url_params } from "./utils/escape-url-params.js";
|
|
9
|
-
import {
|
|
8
|
+
import { formatWithPrettier } from "./utils/prettier.js";
|
|
10
9
|
import { Templates } from "./templates/templates.js";
|
|
11
10
|
|
|
12
11
|
const target_locreq = _locreq(process.cwd());
|
|
@@ -42,8 +41,8 @@ export function generateURL(actionName: string, url: string) {
|
|
|
42
41
|
)
|
|
43
42
|
.join("/")}\`;
|
|
44
43
|
${actionName}URL.params = [${params
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
.map((param) => `"${param}"`)
|
|
45
|
+
.join(",")}];
|
|
47
46
|
${actionName}URL.rawURL = "${encodeURI(url)}";`;
|
|
48
47
|
}
|
|
49
48
|
|
|
@@ -70,9 +69,7 @@ export function sortRoutes<T extends { url: string }>(urls: T[]): T[] {
|
|
|
70
69
|
|
|
71
70
|
export async function generateRoutes(): Promise<void> {
|
|
72
71
|
const files = await Promise.all(
|
|
73
|
-
(
|
|
74
|
-
await walkDir(target_locreq.resolve("src/back/routes"))
|
|
75
|
-
)
|
|
72
|
+
(await walkDir(target_locreq.resolve("src/back/routes")))
|
|
76
73
|
.filter((f) =>
|
|
77
74
|
Object.keys(Templates).some(
|
|
78
75
|
(key) =>
|
|
@@ -129,15 +126,14 @@ ${sortRoutes(files)
|
|
|
129
126
|
.join("\n")}
|
|
130
127
|
`;
|
|
131
128
|
|
|
132
|
-
const prettier_config = await getPrettierConfig();
|
|
133
129
|
await fs.writeFile(
|
|
134
130
|
target_locreq.resolve("src/back/routes/routes.ts"),
|
|
135
|
-
|
|
131
|
+
await formatWithPrettier(routes_content)
|
|
136
132
|
);
|
|
137
133
|
|
|
138
134
|
await fs.writeFile(
|
|
139
135
|
target_locreq.resolve("src/back/routes/urls.ts"),
|
|
140
|
-
|
|
136
|
+
await formatWithPrettier(urls_content)
|
|
141
137
|
);
|
|
142
138
|
// eslint-disable-next-line no-console
|
|
143
139
|
console.log(
|
package/src/generate-stimulus.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _locreq from "locreq";
|
|
2
|
-
import * as prettier from "prettier";
|
|
3
2
|
import { promises as fs } from "fs";
|
|
4
|
-
import {
|
|
3
|
+
import { formatWithPrettier } from "./utils/prettier.js";
|
|
5
4
|
import recursive from "recursive-readdir";
|
|
6
5
|
import path, { dirname } from "path";
|
|
7
6
|
import { toKebabCase, toPascalCase } from "js-convert-case";
|
|
@@ -16,7 +15,7 @@ export async function generateStimulusControllers(
|
|
|
16
15
|
target_locreq.resolve("src/"),
|
|
17
16
|
...controller_dirs,
|
|
18
17
|
];
|
|
19
|
-
console.
|
|
18
|
+
console.info("Looking for controllers in ", stimulus_search_dirs);
|
|
20
19
|
const controller_names = (
|
|
21
20
|
await Promise.all(stimulus_search_dirs.map((dir) => recursive(dir)))
|
|
22
21
|
)
|
|
@@ -54,8 +53,7 @@ export { Turbo };
|
|
|
54
53
|
|
|
55
54
|
await fs.writeFile(
|
|
56
55
|
target_locreq.resolve(output_file),
|
|
57
|
-
|
|
56
|
+
await formatWithPrettier(content)
|
|
58
57
|
);
|
|
59
|
-
|
|
60
|
-
console.log(`Successfuly generated new ${output_file} file`);
|
|
58
|
+
console.info(`Successfuly generated new ${output_file} file`);
|
|
61
59
|
}
|
package/src/get-fonts.ts
CHANGED
|
@@ -34,12 +34,12 @@ export async function getFonts(_: Record<string, string | boolean> = {}) {
|
|
|
34
34
|
});
|
|
35
35
|
await downloader.execute();
|
|
36
36
|
|
|
37
|
-
console.
|
|
37
|
+
console.info("Downloaded new fonts pack from google fonts");
|
|
38
38
|
|
|
39
39
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
40
40
|
const squirrel_fonts = fonts_config.fontSquirrel;
|
|
41
41
|
if (
|
|
42
|
-
|
|
42
|
+
is(
|
|
43
43
|
squirrel_fonts,
|
|
44
44
|
predicates.record(
|
|
45
45
|
predicates.string,
|
|
@@ -47,39 +47,41 @@ export async function getFonts(_: Record<string, string | boolean> = {}) {
|
|
|
47
47
|
)
|
|
48
48
|
)
|
|
49
49
|
) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
await mkdir(target_locreq.resolve("public/dist/fontsquirrel/"), {
|
|
54
|
-
recursive: true,
|
|
55
|
-
});
|
|
50
|
+
await mkdir(target_locreq.resolve("public/dist/fontsquirrel/"), {
|
|
51
|
+
recursive: true,
|
|
52
|
+
});
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
const config_file = `{
|
|
58
55
|
"tmpDir": "/tmp/fonts",
|
|
59
56
|
"fontsDir": "/dist/fontsquirrel/fonts",
|
|
60
57
|
"cssDir": "/dist/fontsquirrel/css",
|
|
61
58
|
"cssFile": "fonts.css"
|
|
62
59
|
}`;
|
|
63
|
-
|
|
60
|
+
await writeFile("public/fonsta.config.json", config_file);
|
|
61
|
+
|
|
62
|
+
await Promise.all(
|
|
63
|
+
Object.keys(squirrel_fonts).map((font) => {
|
|
64
|
+
if (squirrel_fonts[font].length) {
|
|
65
|
+
return execPromise(
|
|
66
|
+
`node ${path_to_fonsta} install ${font}:${squirrel_fonts[
|
|
67
|
+
font
|
|
68
|
+
].join(",")}`,
|
|
69
|
+
{
|
|
70
|
+
cwd: target_locreq.resolve("public"),
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
return execPromise(
|
|
75
|
+
`node ${path_to_fonsta} install ${font}`,
|
|
76
|
+
{
|
|
77
|
+
cwd: target_locreq.resolve("public"),
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
}
|
|
64
84
|
|
|
65
|
-
await Promise.all(
|
|
66
|
-
Object.keys(squirrel_fonts).map((font) => {
|
|
67
|
-
if (squirrel_fonts[font].length) {
|
|
68
|
-
return execPromise(
|
|
69
|
-
`node ${path_to_fonsta} install ${font}:${squirrel_fonts[
|
|
70
|
-
font
|
|
71
|
-
].join(",")}`,
|
|
72
|
-
{
|
|
73
|
-
cwd: target_locreq.resolve("public"),
|
|
74
|
-
}
|
|
75
|
-
);
|
|
76
|
-
} else {
|
|
77
|
-
return execPromise(`node ${path_to_fonsta} install ${font}`, {
|
|
78
|
-
cwd: target_locreq.resolve("public"),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
);
|
|
83
85
|
const fonts_css_file_path = resolve(
|
|
84
86
|
target_locreq.resolve("public/dist/fonts"),
|
|
85
87
|
"fonts.css"
|
|
@@ -93,7 +95,7 @@ export async function getFonts(_: Record<string, string | boolean> = {}) {
|
|
|
93
95
|
|
|
94
96
|
await unlink("public/fonsta.config.json");
|
|
95
97
|
await rmdir("public/tmp");
|
|
96
|
-
console.
|
|
98
|
+
console.info("Downloaded new fonts pack from Font Squirrel");
|
|
97
99
|
|
|
98
|
-
console.
|
|
100
|
+
console.info("Downloaded new fonts pack");
|
|
99
101
|
}
|
package/src/make-env.ts
CHANGED
|
@@ -13,12 +13,13 @@ export function makeHiddenInputs(
|
|
|
13
13
|
return tempstream`${Object.entries(fields)
|
|
14
14
|
.filter(([key]) => !fields_to_skip.includes(key))
|
|
15
15
|
.map(
|
|
16
|
-
([key, field]) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
([key, field]) =>
|
|
17
|
+
tempstream /* HTML */ `<input
|
|
18
|
+
type="hidden"
|
|
19
|
+
name="${key}"
|
|
20
|
+
value="${field
|
|
21
|
+
.getParsedValue(ctx, values)
|
|
22
|
+
.then((r) => attribute(JSON.stringify(r.raw) || ""))}"
|
|
23
|
+
/>`
|
|
23
24
|
)}`;
|
|
24
25
|
}
|
package/src/mount.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
|
|
|
9
9
|
async function handleHtmlPromise(ctx: Context, next: Koa.Next) {
|
|
10
10
|
await next();
|
|
11
11
|
if (ctx.body instanceof Promise) {
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
13
12
|
ctx.body = await ctx.body;
|
|
14
13
|
}
|
|
15
14
|
ctx.set("content-type", "text/html;charset=utf-8");
|
|
@@ -52,31 +51,27 @@ export function mount(
|
|
|
52
51
|
{
|
|
53
52
|
get: (_target: any, prop: any) => {
|
|
54
53
|
if (prop === "info") {
|
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
56
54
|
return () => {};
|
|
57
55
|
} else {
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
59
56
|
return () => {};
|
|
60
57
|
}
|
|
61
58
|
},
|
|
62
59
|
}
|
|
63
60
|
),
|
|
64
61
|
getString: (x: string) => x,
|
|
65
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
62
|
} as any;
|
|
67
63
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
68
64
|
await next();
|
|
69
65
|
},
|
|
70
66
|
SealiousMiddlewares.parseBody(file_manager),
|
|
71
67
|
handleHtmlPromise,
|
|
72
|
-
|
|
68
|
+
]
|
|
73
69
|
: [
|
|
74
70
|
SealiousMiddlewares.extractContext(),
|
|
75
71
|
SealiousMiddlewares.parseBody(file_manager),
|
|
76
72
|
handleHtmlPromise,
|
|
77
|
-
|
|
73
|
+
];
|
|
78
74
|
|
|
79
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
80
75
|
router.use(raw_url, ...args);
|
|
81
76
|
mountable.init();
|
|
82
77
|
|
package/src/notifier.ts
CHANGED
|
@@ -12,7 +12,6 @@ async function get_status(
|
|
|
12
12
|
app_port: number
|
|
13
13
|
): Promise<{ started_at: number; status: string }> {
|
|
14
14
|
const r = await fetch(`http://127.0.0.1:${app_port}/status.json`);
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
16
15
|
return (await r.json()) as { started_at: number; status: string };
|
|
17
16
|
}
|
|
18
17
|
|
|
@@ -21,7 +20,7 @@ async function wait_for_run_id_to_change(app_port: number) {
|
|
|
21
20
|
try {
|
|
22
21
|
const { started_at } = await get_status(app_port);
|
|
23
22
|
first_timestamp = started_at;
|
|
24
|
-
} catch (
|
|
23
|
+
} catch (_e) {
|
|
25
24
|
await wait_for_app_to_be_stable(app_port);
|
|
26
25
|
return;
|
|
27
26
|
}
|
|
@@ -30,7 +29,6 @@ async function wait_for_run_id_to_change(app_port: number) {
|
|
|
30
29
|
throw new Error(APP_DOWN_ERROR_MESSAGE);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
// eslint-disable-next-line no-constant-condition
|
|
34
32
|
while (true) {
|
|
35
33
|
// eslint-disable-next-line no-await-in-loop
|
|
36
34
|
const { started_at } = await get_status(app_port).catch(() => ({
|
|
@@ -48,7 +46,7 @@ async function wait_for_app_to_be_stable(app_port: number, n = 3) {
|
|
|
48
46
|
// eslint-disable-next-line no-console
|
|
49
47
|
console.log("Waiting for app to be stable....");
|
|
50
48
|
let counter = 0;
|
|
51
|
-
|
|
49
|
+
|
|
52
50
|
while (true) {
|
|
53
51
|
// eslint-disable-next-line no-await-in-loop
|
|
54
52
|
const { status } = await get_status(app_port).catch(() => ({
|
|
@@ -103,8 +101,8 @@ export function make_notifier(port: number, app_port: number) {
|
|
|
103
101
|
});
|
|
104
102
|
});
|
|
105
103
|
|
|
106
|
-
console.
|
|
107
|
-
"
|
|
104
|
+
console.info(
|
|
105
|
+
"🔔 Build notifier listening on websocket at port " + port.toString()
|
|
108
106
|
);
|
|
109
107
|
return function notify(message: string) {
|
|
110
108
|
sockets.forEach((s) => s.send(message));
|