@sealcode/sealgen 0.4.2 → 0.5.2
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/checkboxed-list-input.d.ts +2 -2
- package/@types/forms/controls/controls.d.ts +1 -0
- package/@types/forms/controls/dropdown.d.ts +2 -2
- package/@types/forms/controls/editable-collection-subset.d.ts +2 -2
- package/@types/forms/controls/form-control.d.ts +2 -2
- package/@types/forms/controls/form-field-control.d.ts +2 -2
- package/@types/forms/controls/form-header.d.ts +4 -4
- package/@types/forms/controls/html.d.ts +9 -0
- package/@types/forms/controls/simple-input.d.ts +4 -2
- package/@types/forms/fields/checkboxed-list.d.ts +7 -7
- package/@types/forms/fields/collection-field.d.ts +3 -3
- package/@types/forms/fields/field.d.ts +6 -6
- package/@types/forms/fields/number.d.ts +3 -3
- package/@types/forms/fields/pick-from-list.d.ts +7 -7
- package/@types/forms/fields/simple-form-field.d.ts +2 -2
- package/@types/forms/form.d.ts +9 -9
- package/@types/index.d.ts +2 -2
- package/@types/make-hidden-inputs.d.ts +4 -3
- package/@types/page/access-control.d.ts +2 -2
- package/@types/page/list.d.ts +14 -14
- package/@types/page/mountable.d.ts +8 -8
- package/@types/page/page.d.ts +5 -5
- package/@types/page/props-parser.d.ts +4 -4
- package/@types/utils/get-prettier-config.d.ts +2 -0
- package/@types/utils/prettier.d.ts +2 -0
- package/@types/utils/translate.d.ts +2 -2
- package/@types/utils/url-with-new-params.d.ts +2 -2
- package/lib/build.js +3 -2
- package/lib/build.js.map +1 -1
- package/lib/forms/controls/checkboxed-list-input.js.map +1 -1
- package/lib/forms/controls/controls.js +3 -1
- package/lib/forms/controls/controls.js.map +1 -1
- package/lib/forms/controls/dropdown.js.map +1 -1
- package/lib/forms/controls/editable-collection-subset.js.map +1 -1
- package/lib/forms/controls/form-header.js.map +1 -1
- package/lib/forms/controls/html.js +19 -0
- package/lib/forms/controls/html.js.map +1 -0
- package/lib/forms/controls/simple-input.js +3 -1
- package/lib/forms/controls/simple-input.js.map +1 -1
- package/lib/forms/fields/checkboxed-list.js.map +1 -1
- package/lib/forms/fields/collection-field.js.map +1 -1
- package/lib/forms/fields/field.js.map +1 -1
- package/lib/forms/fields/number.js.map +1 -1
- package/lib/forms/fields/pick-from-list.js.map +1 -1
- package/lib/forms/fields/simple-form-field.js.map +1 -1
- package/lib/forms/form.js.map +1 -1
- package/lib/generate-collections.js +22 -1
- package/lib/generate-collections.js.map +1 -1
- package/lib/generate-routes.js +35 -11
- package/lib/generate-routes.js.map +1 -1
- package/lib/index.js +15 -2
- package/lib/index.js.map +1 -1
- package/lib/make-hidden-inputs.js.map +1 -1
- package/lib/page/access-control.js.map +1 -1
- package/lib/page/list.js.map +1 -1
- package/lib/page/mountable.js.map +1 -1
- package/lib/page/page.js.map +1 -1
- package/lib/page/props-parser.js.map +1 -1
- package/lib/templates/form.js +9 -16
- package/lib/templates/form.js.map +1 -1
- package/lib/templates/list.js +4 -4
- package/lib/templates/list.js.map +1 -1
- package/lib/templates/page.js +3 -3
- package/lib/templates/route-test.js +1 -1
- package/lib/templates/route-test.js.map +1 -1
- package/lib/utils/get-prettier-config.js +36 -0
- package/lib/utils/get-prettier-config.js.map +1 -0
- package/lib/utils/prettier.js +36 -0
- package/lib/utils/prettier.js.map +1 -0
- package/lib/utils/translate.js.map +1 -1
- package/lib/utils/url-with-new-params.js.map +1 -1
- package/package.json +4 -3
- package/src/build.ts +3 -2
- package/src/forms/controls/checkboxed-list-input.ts +2 -2
- package/src/forms/controls/controls.ts +1 -0
- package/src/forms/controls/dropdown.ts +2 -2
- package/src/forms/controls/editable-collection-subset.ts +2 -2
- package/src/forms/controls/form-control.ts +2 -2
- package/src/forms/controls/form-field-control.ts +2 -2
- package/src/forms/controls/form-header.ts +3 -3
- package/src/forms/controls/html.ts +18 -0
- package/src/forms/controls/simple-input.ts +6 -5
- package/src/forms/fields/checkboxed-list.ts +5 -5
- package/src/forms/fields/collection-field.ts +3 -3
- package/src/forms/fields/field.ts +6 -6
- package/src/forms/fields/number.ts +3 -3
- package/src/forms/fields/pick-from-list.ts +5 -5
- package/src/forms/fields/simple-form-field.ts +2 -2
- package/src/forms/form.ts +9 -9
- package/src/generate-collections.ts +3 -1
- package/src/generate-routes.ts +31 -13
- package/src/index.ts +2 -2
- package/src/make-hidden-inputs.ts +4 -3
- package/src/page/access-control.ts +2 -2
- package/src/page/list.ts +14 -23
- package/src/page/mountable.ts +9 -9
- package/src/page/page.ts +5 -5
- package/src/page/props-parser.ts +4 -7
- package/src/templates/form.ts +9 -16
- package/src/templates/list.ts +4 -4
- package/src/templates/page.ts +3 -3
- package/src/templates/route-test.ts +1 -1
- package/src/utils/prettier.ts +13 -0
- package/src/utils/translate.ts +2 -2
- package/src/utils/url-with-new-params.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/koa__router": "^8.0.4",
|
|
20
20
|
"@types/mocha": "^9.0.0",
|
|
21
|
+
"@types/prettier": "^2.7.0",
|
|
21
22
|
"@types/prompts": "^2.0.14",
|
|
22
23
|
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
|
23
24
|
"@typescript-eslint/parser": "^4.29.3",
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"mocha": "^9.1.1",
|
|
29
30
|
"mri": "^1.1.6",
|
|
30
31
|
"nyc": "^15.1.0",
|
|
31
|
-
"prettier": "^2.
|
|
32
|
+
"prettier": "^2.7.1",
|
|
32
33
|
"source-map-support": "^0.5.19",
|
|
33
34
|
"ts-node": "^10.2.1",
|
|
34
35
|
"typescript": "^4.3.5"
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"@koa/router": "^10.1.1",
|
|
39
40
|
"@sealcode/ts-predicates": "^0.4.0",
|
|
40
|
-
"esbuild": "^0.
|
|
41
|
+
"esbuild": "^0.15.5",
|
|
41
42
|
"esbuild-sass-plugin": "^2.3.1",
|
|
42
43
|
"koa": "^2.13.0",
|
|
43
44
|
"locreq": "^2.0.2",
|
package/src/build.ts
CHANGED
|
@@ -19,7 +19,7 @@ async function build_ts() {
|
|
|
19
19
|
outdir: "./dist/back",
|
|
20
20
|
logLevel: "info",
|
|
21
21
|
platform: "node",
|
|
22
|
-
target: "
|
|
22
|
+
target: "es2022",
|
|
23
23
|
format: "cjs",
|
|
24
24
|
});
|
|
25
25
|
}
|
|
@@ -48,7 +48,8 @@ async function complex_build(watch: boolean): Promise<void> {
|
|
|
48
48
|
if (
|
|
49
49
|
path.endsWith(".ts") &&
|
|
50
50
|
!path.endsWith("src/back/collections.ts") &&
|
|
51
|
-
!path.endsWith("src/back/routes/routes.ts")
|
|
51
|
+
!path.endsWith("src/back/routes/routes.ts") &&
|
|
52
|
+
!path.endsWith("src/back/routes/urls.ts")
|
|
52
53
|
) {
|
|
53
54
|
await build_ts();
|
|
54
55
|
console.log(`Finished TS build [on ${path}]`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from "koa";
|
|
3
3
|
import { tempstream } from "tempstream";
|
|
4
4
|
import { ChekboxedListField } from "../fields/field";
|
|
5
5
|
import { FormDataValue } from "../form";
|
|
@@ -13,7 +13,7 @@ export class CheckboxedListInput extends FormFieldControl {
|
|
|
13
13
|
super([field]);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
async render(ctx:
|
|
16
|
+
async render(ctx: Context, data: Record<string, FormDataValue>) {
|
|
17
17
|
const { parsed: pickedValues } = await this.field.getValue(ctx, data);
|
|
18
18
|
if (!is(pickedValues, predicates.array(predicates.string))) {
|
|
19
19
|
throw new Error("picked values is not an array of strings");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { tempstream } from "tempstream";
|
|
3
3
|
import { FormField, PickFromListField } from "../fields/field";
|
|
4
4
|
import { FormDataValue } from "../form";
|
|
@@ -21,7 +21,7 @@ export class Dropdown extends FormFieldControl {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async render<Fields extends Record<string, FormField>>(
|
|
24
|
-
ctx:
|
|
24
|
+
ctx: Context,
|
|
25
25
|
data: Record<string, FormDataValue>
|
|
26
26
|
) {
|
|
27
27
|
const { parsed: picked_value } = await this.field.getValue(ctx, data);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FlatTemplatable, tempstream } from "tempstream";
|
|
3
3
|
import { PickFromListField } from "../fields/field";
|
|
4
4
|
import { FormDataValue } from "../form";
|
|
@@ -22,7 +22,7 @@ export class EditableCollectionSubset extends FormFieldControl {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async render(
|
|
25
|
-
ctx:
|
|
25
|
+
ctx: Context,
|
|
26
26
|
data: Record<string, FormDataValue>
|
|
27
27
|
): Promise<FlatTemplatable> {
|
|
28
28
|
const { parsed: values } = await this.field.getValue(ctx, data);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FlatTemplatable } from "tempstream";
|
|
3
3
|
import { FormDataValue, FormMessage } from "../form";
|
|
4
4
|
|
|
5
5
|
export abstract class FormControl {
|
|
6
6
|
abstract render(
|
|
7
|
-
ctx:
|
|
7
|
+
ctx: Context,
|
|
8
8
|
data: Record<string, FormDataValue>,
|
|
9
9
|
messages: FormMessage[]
|
|
10
10
|
): FlatTemplatable | Promise<FlatTemplatable>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FlatTemplatable } from "tempstream";
|
|
3
3
|
import { FormField } from "../fields/field";
|
|
4
4
|
import { FieldValueType, FormDataValue } from "../form";
|
|
@@ -17,7 +17,7 @@ export abstract class FormFieldControl extends FormControl {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
abstract render(
|
|
20
|
-
ctx:
|
|
20
|
+
ctx: Context,
|
|
21
21
|
data: Record<string, FormDataValue>
|
|
22
22
|
): FlatTemplatable | Promise<FlatTemplatable>;
|
|
23
23
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FormControl } from "./controls";
|
|
3
3
|
|
|
4
4
|
export class FormHeader extends FormControl {
|
|
5
5
|
role = <const>"decoration";
|
|
6
6
|
constructor(
|
|
7
7
|
public text: string,
|
|
8
|
-
public isVisible: (ctx:
|
|
8
|
+
public isVisible: (ctx: Context) => Promise<boolean> = async () => true
|
|
9
9
|
) {
|
|
10
10
|
super();
|
|
11
11
|
}
|
|
12
|
-
async render(ctx:
|
|
12
|
+
async render(ctx: Context) {
|
|
13
13
|
const isVsbl = await this.isVisible(ctx);
|
|
14
14
|
return isVsbl ? `<h2>${this.text}</h2>` : "";
|
|
15
15
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context } from "koa";
|
|
2
|
+
import { FlatTemplatable } from "tempstream";
|
|
3
|
+
import { FormControl } from "./controls";
|
|
4
|
+
|
|
5
|
+
export class HTML extends FormControl {
|
|
6
|
+
role = <const>"decoration";
|
|
7
|
+
|
|
8
|
+
constructor(public renderer: ((ctx: Context) => FlatTemplatable) | string) {
|
|
9
|
+
super();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async render(ctx: Context): Promise<FlatTemplatable> {
|
|
13
|
+
if (typeof this.renderer === "string") {
|
|
14
|
+
return this.renderer;
|
|
15
|
+
}
|
|
16
|
+
return this.renderer(ctx);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FormField } from "../fields/field";
|
|
3
|
-
import { NumberField } from "../fields/number";
|
|
4
|
-
import { SimpleFormField } from "../fields/simple-form-field";
|
|
5
3
|
import { FormDataValue } from "../form";
|
|
6
4
|
import { FormFieldControl } from "./controls";
|
|
7
5
|
|
|
@@ -12,6 +10,7 @@ export class SimpleInput extends FormFieldControl {
|
|
|
12
10
|
id?: string;
|
|
13
11
|
label?: string;
|
|
14
12
|
autocomplete?: boolean;
|
|
13
|
+
hide_errors?: boolean;
|
|
15
14
|
type?:
|
|
16
15
|
| "color"
|
|
17
16
|
| "date"
|
|
@@ -36,7 +35,7 @@ export class SimpleInput extends FormFieldControl {
|
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
async render<Fields extends Record<string, FormField>>(
|
|
39
|
-
ctx:
|
|
38
|
+
ctx: Context,
|
|
40
39
|
data: Record<string, FormDataValue>
|
|
41
40
|
) {
|
|
42
41
|
const id = this.options.id || this.field.name;
|
|
@@ -70,7 +69,9 @@ export class SimpleInput extends FormFieldControl {
|
|
|
70
69
|
${!this.options.autocomplete ? `autocomplete="off"` : ""}
|
|
71
70
|
${this.options.step ? `step="${this.options.step}"` : ""}
|
|
72
71
|
/>
|
|
73
|
-
${~valid
|
|
72
|
+
${~valid && !this.options.hide_errors
|
|
73
|
+
? `<div class="input__error">${message}</div>`
|
|
74
|
+
: ""}
|
|
74
75
|
</div>`;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from "koa";
|
|
3
3
|
import { FormDataValue } from "../form";
|
|
4
4
|
import {
|
|
5
5
|
FieldParseResult,
|
|
@@ -11,16 +11,16 @@ export class ChekboxedListField extends FormField<Record<string, "on">> {
|
|
|
11
11
|
constructor(
|
|
12
12
|
public required: boolean = false,
|
|
13
13
|
public generateOptions: (
|
|
14
|
-
ctx:
|
|
14
|
+
ctx: Context
|
|
15
15
|
) => Promise<Record<string, string> | { [i: string]: string }>,
|
|
16
|
-
public isVisible: (ctx:
|
|
16
|
+
public isVisible: (ctx: Context) => Promise<boolean> = () =>
|
|
17
17
|
Promise.resolve(true)
|
|
18
18
|
) {
|
|
19
19
|
super(required);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
public async isValueValid(
|
|
23
|
-
_:
|
|
23
|
+
_: Context,
|
|
24
24
|
value: unknown
|
|
25
25
|
): Promise<FormFieldValidationResponse> {
|
|
26
26
|
if (is(value, predicates.string)) {
|
|
@@ -33,7 +33,7 @@ export class ChekboxedListField extends FormField<Record<string, "on">> {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
async parse(
|
|
36
|
-
_:
|
|
36
|
+
_: Context,
|
|
37
37
|
raw_value: FormDataValue
|
|
38
38
|
): Promise<FieldParseResult<Record<string, "on">>> {
|
|
39
39
|
if (is(raw_value, predicates.object)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { Depromisify, Field, FieldOutput } from "sealious";
|
|
3
3
|
import { FormDataValue } from "../form";
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@ export class CollectionField<F extends Field> extends FormField<
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async parse(
|
|
19
|
-
ctx:
|
|
19
|
+
ctx: Context,
|
|
20
20
|
raw_value: FormDataValue
|
|
21
21
|
): Promise<FieldParseResult<FieldOutput<F>>> {
|
|
22
22
|
const encoded_value = (await this.sealiousField.encode(
|
|
@@ -37,7 +37,7 @@ export class CollectionField<F extends Field> extends FormField<
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
public async isValueValid(
|
|
40
|
-
ctx:
|
|
40
|
+
ctx: Context,
|
|
41
41
|
value: FieldOutput<F>
|
|
42
42
|
): Promise<FormFieldValidationResponse> {
|
|
43
43
|
const { valid, reason } = await this.sealiousField.checkValue(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { t } from "../../utils/translate";
|
|
3
3
|
import { FormDataValue } from "../form";
|
|
4
4
|
|
|
5
5
|
export type FormFieldValidationResponse = { valid: boolean; message: string };
|
|
6
6
|
|
|
7
7
|
export type FormFieldValidationFn<ValueType> = (
|
|
8
|
-
ctx:
|
|
8
|
+
ctx: Context,
|
|
9
9
|
value: ValueType,
|
|
10
10
|
field: FormField<ValueType>
|
|
11
11
|
) => Promise<FormFieldValidationResponse>;
|
|
@@ -29,7 +29,7 @@ export abstract class FormField<ParsedValue extends unknown = unknown> {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
public async _validate(
|
|
32
|
-
ctx:
|
|
32
|
+
ctx: Context,
|
|
33
33
|
value: ParsedValue
|
|
34
34
|
): Promise<FormFieldValidationResponse> {
|
|
35
35
|
if (
|
|
@@ -53,19 +53,19 @@ export abstract class FormField<ParsedValue extends unknown = unknown> {
|
|
|
53
53
|
public abstract getEmptyValue(): ParsedValue;
|
|
54
54
|
|
|
55
55
|
public async isValueValid(
|
|
56
|
-
ctx:
|
|
56
|
+
ctx: Context,
|
|
57
57
|
value: ParsedValue
|
|
58
58
|
): Promise<FormFieldValidationResponse> {
|
|
59
59
|
return { valid: true, message: "" };
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
abstract parse(
|
|
63
|
-
ctx:
|
|
63
|
+
ctx: Context,
|
|
64
64
|
raw_value: FormDataValue
|
|
65
65
|
): Promise<FieldParseResult<ParsedValue>>;
|
|
66
66
|
|
|
67
67
|
async getValue(
|
|
68
|
-
ctx:
|
|
68
|
+
ctx: Context,
|
|
69
69
|
all_form_values: Record<string, FormDataValue>
|
|
70
70
|
): Promise<{
|
|
71
71
|
valid: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from "koa";
|
|
3
3
|
import { FormDataValue } from "../form";
|
|
4
4
|
import { FieldParseResult, FormField } from "./field";
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ export class NumberField<
|
|
|
10
10
|
super(required);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
public async isValueValid(_:
|
|
13
|
+
public async isValueValid(_: Context, value: unknown) {
|
|
14
14
|
if (
|
|
15
15
|
(is(value, predicates.string) &&
|
|
16
16
|
!isNaN(parseFloat(value)) &&
|
|
@@ -24,7 +24,7 @@ export class NumberField<
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async parse(
|
|
27
|
-
_:
|
|
27
|
+
_: Context,
|
|
28
28
|
value: FormDataValue
|
|
29
29
|
): Promise<FieldParseResult<number>> {
|
|
30
30
|
if (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from "koa";
|
|
3
3
|
import { FormFieldValidationResponse } from "./field";
|
|
4
4
|
import { SimpleFormField } from "./simple-form-field";
|
|
5
5
|
|
|
@@ -7,10 +7,10 @@ export class PickFromListField extends SimpleFormField {
|
|
|
7
7
|
constructor(
|
|
8
8
|
public required: boolean = false,
|
|
9
9
|
public generateOptions: (
|
|
10
|
-
ctx:
|
|
10
|
+
ctx: Context
|
|
11
11
|
) => Promise<Record<string, string> | { [i: string]: string }>,
|
|
12
12
|
public customValidation: (
|
|
13
|
-
ctx:
|
|
13
|
+
ctx: Context,
|
|
14
14
|
value: unknown,
|
|
15
15
|
instance: PickFromListField
|
|
16
16
|
) => Promise<FormFieldValidationResponse> = (ctx, value, instance) =>
|
|
@@ -20,14 +20,14 @@ export class PickFromListField extends SimpleFormField {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
public isValueValid(
|
|
23
|
-
ctx:
|
|
23
|
+
ctx: Context,
|
|
24
24
|
value: string
|
|
25
25
|
): Promise<FormFieldValidationResponse> {
|
|
26
26
|
return this.customValidation(ctx, value, this);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async valueInList(
|
|
30
|
-
ctx:
|
|
30
|
+
ctx: Context,
|
|
31
31
|
value: unknown
|
|
32
32
|
): Promise<FormFieldValidationResponse> {
|
|
33
33
|
const options = await this.generateOptions(ctx);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FieldParseResult, FormField } from "./field";
|
|
2
2
|
import { FormDataValue } from "../form";
|
|
3
|
-
import {
|
|
3
|
+
import { Context } from "koa";
|
|
4
4
|
|
|
5
5
|
export class SimpleFormField extends FormField<string | null> {
|
|
6
6
|
async parse(
|
|
7
|
-
_:
|
|
7
|
+
_: Context,
|
|
8
8
|
raw_value: FormDataValue
|
|
9
9
|
): Promise<FieldParseResult<string>> {
|
|
10
10
|
return {
|
package/src/forms/form.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import Router from "@koa/router";
|
|
3
3
|
import { FlatTemplatable, Templatable, tempstream } from "tempstream";
|
|
4
4
|
import {
|
|
@@ -36,19 +36,19 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
|
|
|
36
36
|
|
|
37
37
|
async canAccess(
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
-
_:
|
|
39
|
+
_: Context
|
|
40
40
|
): Promise<{ canAccess: boolean; message: string }> {
|
|
41
41
|
return { canAccess: true, message: "" };
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async renderError(
|
|
45
|
-
_:
|
|
45
|
+
_: Context,
|
|
46
46
|
error: PageErrorMessage
|
|
47
47
|
): Promise<FlatTemplatable> {
|
|
48
48
|
return tempstream/* HTML */ `<div>${error.message}</div>`;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
async render(ctx:
|
|
51
|
+
async render(ctx: Context, data: FormData): Promise<FlatTemplatable> {
|
|
52
52
|
return tempstream/* HTML */ `${this.makeFormTag()} ${
|
|
53
53
|
!this.controls.some((control) => control.role == "messages")
|
|
54
54
|
? this.renderMessages(ctx, data)
|
|
@@ -63,7 +63,7 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
public async onValuesInvalid(
|
|
66
|
-
ctx:
|
|
66
|
+
ctx: Context,
|
|
67
67
|
form_messages: FormMessage[]
|
|
68
68
|
): Promise<void> {
|
|
69
69
|
ctx.status = 422;
|
|
@@ -77,7 +77,7 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
public async onError(
|
|
80
|
-
ctx:
|
|
80
|
+
ctx: Context,
|
|
81
81
|
data: FormData,
|
|
82
82
|
error: unknown
|
|
83
83
|
): Promise<void> {
|
|
@@ -96,11 +96,11 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
public abstract onSubmit(
|
|
99
|
-
ctx:
|
|
99
|
+
ctx: Context,
|
|
100
100
|
data: FormData
|
|
101
101
|
): void | Promise<void>;
|
|
102
102
|
|
|
103
|
-
public async onSuccess(ctx:
|
|
103
|
+
public async onSuccess(ctx: Context, data: FormData): Promise<void> {
|
|
104
104
|
ctx.body = await this.render(ctx, {
|
|
105
105
|
raw_values: data.raw_values,
|
|
106
106
|
messages: [{ type: "success", text: this.defaultSuccessMessage }],
|
|
@@ -171,7 +171,7 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
extractRawValues(ctx:
|
|
174
|
+
extractRawValues(ctx: Context): Record<string, FormDataValue> {
|
|
175
175
|
return ctx.$body;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import _locreq from "locreq";
|
|
2
|
+
import * as prettier from "prettier";
|
|
2
3
|
import { promises as fs } from "fs";
|
|
3
4
|
import { assertType, predicates } from "@sealcode/ts-predicates";
|
|
5
|
+
import { getPrettierConfig } from "./utils/prettier";
|
|
4
6
|
|
|
5
7
|
const target_locreq = _locreq(process.cwd());
|
|
6
8
|
|
|
@@ -63,7 +65,7 @@ ${file_data
|
|
|
63
65
|
};`;
|
|
64
66
|
await fs.writeFile(
|
|
65
67
|
target_locreq.resolve("src/back/collections/collections.ts"),
|
|
66
|
-
content
|
|
68
|
+
prettier.format(content, await getPrettierConfig())
|
|
67
69
|
);
|
|
68
70
|
// eslint-disable-next-line no-console
|
|
69
71
|
console.log(
|
package/src/generate-routes.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { promises as fs } from "fs";
|
|
2
|
+
import * as prettier from "prettier";
|
|
2
3
|
import { relative } from "path";
|
|
3
4
|
import _locreq from "locreq";
|
|
4
5
|
import { walkDir } from "./utils/walk";
|
|
5
6
|
import { importPath } from "./utils/import-path";
|
|
6
7
|
import { assertType, predicates } from "@sealcode/ts-predicates";
|
|
7
8
|
import { unescape_url_params } from "./utils/escape-url-params";
|
|
9
|
+
import { getPrettierConfig } from "./utils/prettier";
|
|
8
10
|
|
|
9
11
|
const target_locreq = _locreq(process.cwd());
|
|
10
12
|
|
|
@@ -46,14 +48,13 @@ export async function generateRoutes(): Promise<void> {
|
|
|
46
48
|
}))
|
|
47
49
|
);
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
target_locreq.resolve("src/back/routes/routes.ts"),
|
|
51
|
-
`// DO NOT EDIT! This file is generated automaticaly with npm run generate-routes
|
|
51
|
+
const routes_content = `// DO NOT EDIT! This file is generated automaticaly with npm run generate-routes
|
|
52
52
|
|
|
53
|
-
import Koa, {
|
|
53
|
+
import Koa, { Context } from "koa";
|
|
54
54
|
import Router from "@koa/router";
|
|
55
55
|
import { Middlewares } from "sealious";
|
|
56
56
|
import { Mountable } from "@sealcode/sealgen";
|
|
57
|
+
import * as URLs from "./urls"
|
|
57
58
|
|
|
58
59
|
${files
|
|
59
60
|
.map(
|
|
@@ -65,11 +66,7 @@ ${files
|
|
|
65
66
|
)
|
|
66
67
|
.join("\n")}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
.map(({ actionName, url }) => `export const ${actionName}URL = "${url}";`)
|
|
70
|
-
.join("\n")}
|
|
71
|
-
|
|
72
|
-
async function handleHtmlPromise(ctx: BaseContext, next: Koa.Next) {
|
|
69
|
+
async function handleHtmlPromise(ctx: Context, next: Koa.Next) {
|
|
73
70
|
await next();
|
|
74
71
|
if (ctx.body instanceof Promise) {
|
|
75
72
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -94,11 +91,32 @@ function mount(router: Router, URL: string, mountable: Mountable) {
|
|
|
94
91
|
|
|
95
92
|
export default function mountAutoRoutes(router: Router) {
|
|
96
93
|
${files
|
|
97
|
-
.map(
|
|
94
|
+
.map(
|
|
95
|
+
({ actionName }) =>
|
|
96
|
+
` mount(router, URLs.${actionName}URL, ${actionName});`
|
|
97
|
+
)
|
|
98
98
|
.join("\n")}
|
|
99
|
-
}
|
|
100
|
-
|
|
99
|
+
}`;
|
|
100
|
+
|
|
101
|
+
const urls_content = `${files
|
|
102
|
+
.map(
|
|
103
|
+
({ actionName, url }) => `export const ${actionName}URL = "${url}";`
|
|
104
|
+
)
|
|
105
|
+
.join("\n")}
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
const prettier_config = await getPrettierConfig();
|
|
109
|
+
await fs.writeFile(
|
|
110
|
+
target_locreq.resolve("src/back/routes/routes.ts"),
|
|
111
|
+
prettier.format(routes_content, prettier_config)
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
await fs.writeFile(
|
|
115
|
+
target_locreq.resolve("src/back/routes/urls.ts"),
|
|
116
|
+
prettier.format(urls_content, prettier_config)
|
|
101
117
|
);
|
|
102
118
|
// eslint-disable-next-line no-console
|
|
103
|
-
console.log(
|
|
119
|
+
console.log(
|
|
120
|
+
"Successfuly generated new src/back/routes/routes.ts and src/back/routes/urls.ts"
|
|
121
|
+
);
|
|
104
122
|
}
|
package/src/index.ts
CHANGED
|
@@ -9,8 +9,8 @@ declare module "koa" {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export * from "./forms/controls/controls";
|
|
13
|
-
export * from "./forms/fields/field";
|
|
12
|
+
export * as Controls from "./forms/controls/controls";
|
|
13
|
+
export * as Fields from "./forms/fields/field";
|
|
14
14
|
export * from "./page/mountable";
|
|
15
15
|
export * from "./page/page";
|
|
16
16
|
export * from "./forms/form";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { FlatTemplatable, tempstream } from "tempstream";
|
|
3
|
-
import { FormDataValue
|
|
3
|
+
import { FormDataValue } from ".";
|
|
4
|
+
import { FormField } from "./forms/fields/field";
|
|
4
5
|
|
|
5
6
|
export function makeHiddenInputs(
|
|
6
|
-
ctx:
|
|
7
|
+
ctx: Context,
|
|
7
8
|
fields: Record<string, FormField>,
|
|
8
9
|
values: Record<string, FormDataValue>,
|
|
9
10
|
fields_to_skip: string[]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Context } from "koa";
|
|
2
2
|
import { ActionName, Collection } from "sealious";
|
|
3
3
|
|
|
4
4
|
export function peopleWhoCan(action: ActionName, collection: Collection) {
|
|
5
|
-
return async function (ctx:
|
|
5
|
+
return async function (ctx: Context) {
|
|
6
6
|
const policy = collection.getPolicy(action);
|
|
7
7
|
const result = await policy.check(ctx.$context);
|
|
8
8
|
if (!result) {
|