@sealcode/sealgen 0.1.7 → 0.2.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/.eslintrc.js +1 -0
- package/.log/ti-101379.log +524 -0
- package/.log/ti-131883.log +505 -0
- package/.log/ti-138140.log +505 -0
- package/.log/ti-138288.log +526 -0
- package/.log/ti-292609.log +508 -0
- package/.log/ti-304933.log +524 -0
- package/.log/ti-312312.log +508 -0
- package/.log/ti-314240.log +1617 -0
- package/.log/ti-62627.log +508 -0
- package/.log/ti-64785.log +508 -0
- package/.log/ti-65911.log +533 -0
- package/.log/ti-69885.log +548 -0
- package/.log/ti-72106.log +551 -0
- package/.log/ti-74858.log +508 -0
- package/.log/tsserver.log +1610 -902
- package/@types/build.d.ts +1 -0
- package/@types/cli.d.ts +2 -0
- package/@types/forms/controls/checkboxed-list-input.d.ts +16 -0
- package/@types/forms/controls/controls.d.ts +9 -0
- package/@types/forms/controls/dropdown.d.ts +20 -0
- package/@types/forms/controls/editable-collection-subset.d.ts +21 -0
- package/@types/forms/controls/form-control.d.ts +8 -0
- package/@types/forms/controls/form-field-control.d.ts +13 -0
- package/@types/forms/controls/form-header.d.ts +9 -0
- package/@types/forms/controls/form-paragraph.d.ts +7 -0
- package/@types/forms/controls/frame.d.ts +17 -0
- package/@types/forms/controls/simple-input.d.ts +28 -0
- package/@types/forms/controls.d.ts +0 -0
- package/@types/forms/field.d.ts +42 -0
- package/@types/forms/form-fields-list.d.ts +4 -0
- package/@types/forms/form.d.ts +42 -0
- package/@types/forms/validator.d.ts +3 -0
- package/@types/index.d.ts +14 -2
- package/@types/page/access-control.d.ts +6 -0
- package/@types/page/list.d.ts +59 -0
- package/@types/page/page.d.ts +26 -0
- package/@types/page/props-parser.d.ts +20 -0
- package/@types/run.d.ts +0 -0
- package/@types/templates/form.d.ts +1 -1
- package/@types/templates/list.d.ts +1 -0
- package/@types/templates/page.d.ts +1 -1
- package/@types/utils/list-collections.d.ts +1 -0
- package/@types/utils/natural-numbers.d.ts +1 -0
- package/@types/utils/sleep.d.ts +1 -0
- package/@types/utils/url-with-new-params.d.ts +2 -0
- package/@types/utils/utils.d.ts +9 -0
- package/@types/utils/walk.d.ts +1 -1
- package/lib/add-collection.js +13 -24
- package/lib/add-collection.js.map +1 -1
- package/lib/add-route.js +25 -32
- package/lib/add-route.js.map +1 -1
- package/lib/build.js +108 -0
- package/lib/build.js.map +1 -0
- package/lib/cli.js +30 -0
- package/lib/cli.js.map +1 -0
- package/lib/find-scss-includes.js +10 -20
- package/lib/find-scss-includes.js.map +1 -1
- package/lib/forms/controls/checkboxed-list-input.js +43 -0
- package/lib/forms/controls/checkboxed-list-input.js.map +1 -0
- package/lib/forms/controls/controls.js +22 -0
- package/lib/forms/controls/controls.js.map +1 -0
- package/lib/forms/controls/dropdown.js +40 -0
- package/lib/forms/controls/dropdown.js.map +1 -0
- package/lib/forms/controls/editable-collection-subset.js +73 -0
- package/lib/forms/controls/editable-collection-subset.js.map +1 -0
- package/lib/forms/controls/form-control.js +7 -0
- package/lib/forms/controls/form-control.js.map +1 -0
- package/lib/forms/controls/form-field-control.js +22 -0
- package/lib/forms/controls/form-field-control.js.map +1 -0
- package/lib/forms/controls/form-header.js +18 -0
- package/lib/forms/controls/form-header.js.map +1 -0
- package/lib/forms/controls/form-paragraph.js +16 -0
- package/lib/forms/controls/form-paragraph.js.map +1 -0
- package/lib/forms/controls/frame.js +29 -0
- package/lib/forms/controls/frame.js.map +1 -0
- package/lib/forms/controls/simple-input.js +50 -0
- package/lib/forms/controls/simple-input.js.map +1 -0
- package/lib/forms/controls.js +1 -0
- package/lib/forms/controls.js.map +1 -0
- package/lib/forms/field.js +80 -0
- package/lib/forms/field.js.map +1 -0
- package/lib/forms/form-fields-list.js +10 -0
- package/lib/forms/form-fields-list.js.map +1 -0
- package/lib/forms/form.js +162 -0
- package/lib/forms/form.js.map +1 -0
- package/lib/forms/validator.js +11 -0
- package/lib/forms/validator.js.map +1 -0
- package/lib/generate-collections.js +30 -43
- package/lib/generate-collections.js.map +1 -1
- package/lib/generate-routes.js +29 -42
- package/lib/generate-routes.js.map +1 -1
- package/lib/index.js +16 -37
- package/lib/index.js.map +1 -1
- package/lib/page/access-control.js +20 -0
- package/lib/page/access-control.js.map +1 -0
- package/lib/page/list.js +148 -0
- package/lib/page/list.js.map +1 -0
- package/lib/page/page.js +20 -0
- package/lib/page/page.js.map +1 -0
- package/lib/page/props-parser.js +74 -0
- package/lib/page/props-parser.js.map +1 -0
- package/lib/run.js +1 -0
- package/lib/run.js.map +1 -0
- package/lib/templates/form.js +2 -2
- package/lib/templates/form.js.map +1 -1
- package/lib/templates/list.js +61 -0
- package/lib/templates/list.js.map +1 -0
- package/lib/templates/page.js +3 -1
- package/lib/templates/page.js.map +1 -1
- package/lib/utils/exec.js +16 -27
- package/lib/utils/exec.js.map +1 -1
- package/lib/utils/list-collections.js +20 -0
- package/lib/utils/list-collections.js.map +1 -0
- package/lib/utils/natural-numbers.js +10 -0
- package/lib/utils/natural-numbers.js.map +1 -0
- package/lib/utils/question.js +15 -26
- package/lib/utils/question.js.map +1 -1
- package/lib/utils/sleep.js +8 -0
- package/lib/utils/sleep.js.map +1 -0
- package/lib/utils/url-with-new-params.js +12 -0
- package/lib/utils/url-with-new-params.js.map +1 -0
- package/lib/utils/utils.js +19 -0
- package/lib/utils/utils.js.map +1 -0
- package/lib/utils/walk.js +16 -27
- package/lib/utils/walk.js.map +1 -1
- package/package.json +19 -4
- package/src/add-route.ts +14 -9
- package/src/build.ts +82 -0
- package/src/cli.ts +34 -0
- package/src/find-scss-includes.ts +3 -2
- package/src/forms/controls/checkboxed-list-input.ts +50 -0
- package/src/forms/controls/controls.ts +9 -0
- package/src/forms/controls/dropdown.ts +57 -0
- package/src/forms/controls/editable-collection-subset.ts +91 -0
- package/src/forms/controls/form-control.ts +13 -0
- package/src/forms/controls/form-field-control.ts +39 -0
- package/src/forms/controls/form-header.ts +16 -0
- package/src/forms/controls/form-paragraph.ts +11 -0
- package/src/forms/controls/frame.ts +26 -0
- package/src/forms/controls/simple-input.ts +73 -0
- package/src/forms/controls.ts +0 -0
- package/src/forms/field.ts +119 -0
- package/src/forms/form-fields-list.ts +7 -0
- package/src/forms/form.ts +242 -0
- package/src/forms/forms.scss +18 -0
- package/src/forms/validator.ts +10 -0
- package/src/generate-routes.ts +8 -3
- package/src/index.ts +14 -28
- package/src/page/access-control.ts +18 -0
- package/src/page/list.ts +214 -0
- package/src/page/page.ts +31 -0
- package/src/page/props-parser.ts +99 -0
- package/src/run.ts +0 -0
- package/src/templates/form.ts +5 -2
- package/src/templates/list.ts +65 -0
- package/src/templates/page.ts +4 -2
- package/src/utils/list-collections.ts +16 -0
- package/src/utils/natural-numbers.ts +5 -0
- package/src/utils/sleep.ts +3 -0
- package/src/utils/url-with-new-params.ts +9 -0
- package/src/utils/utils.ts +10 -0
- package/src/utils/walk.ts +2 -2
- package/tsconfig.json +23 -25
- package/src/tsconfig.json +0 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildProject(...args: string[]): Promise<void>;
|
package/@types/cli.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { Form, FormData } from "../form";
|
|
5
|
+
import { FormFieldControl } from "./controls";
|
|
6
|
+
export declare class CheckboxedListInput extends FormFieldControl {
|
|
7
|
+
fieldname: string;
|
|
8
|
+
options: {
|
|
9
|
+
label: string;
|
|
10
|
+
};
|
|
11
|
+
constructor(fieldname: string, options?: {
|
|
12
|
+
label: string;
|
|
13
|
+
});
|
|
14
|
+
isValidFieldName(form: Form): boolean;
|
|
15
|
+
_render(ctx: BaseContext, fields: FormField[], data: FormData): Promise<import("stream").Readable>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { FormControl } from "./form-control";
|
|
2
|
+
export { FormFieldControl } from "./form-field-control";
|
|
3
|
+
export { EditableCollectionSubset } from "./editable-collection-subset";
|
|
4
|
+
export { Frame } from "./frame";
|
|
5
|
+
export { CheckboxedListInput } from "./checkboxed-list-input";
|
|
6
|
+
export { Dropdown } from "./dropdown";
|
|
7
|
+
export { SimpleInput } from "./simple-input";
|
|
8
|
+
export { FormHeader } from "./form-header";
|
|
9
|
+
export { FormParagraph } from "./form-paragraph";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormFieldControl } from "./controls";
|
|
6
|
+
export declare class Dropdown extends FormFieldControl {
|
|
7
|
+
fieldname: string;
|
|
8
|
+
options: {
|
|
9
|
+
label: string;
|
|
10
|
+
autosubmit?: boolean;
|
|
11
|
+
autocomplete?: boolean;
|
|
12
|
+
};
|
|
13
|
+
constructor(fieldname: string, options?: {
|
|
14
|
+
label: string;
|
|
15
|
+
autosubmit?: boolean;
|
|
16
|
+
autocomplete?: boolean;
|
|
17
|
+
});
|
|
18
|
+
areFieldNamesValid(fields: FormField[]): boolean;
|
|
19
|
+
_render(ctx: BaseContext, fields: FormField[], data: FormData): import("stream").Readable;
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable } from "tempstream";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormFieldControl } from "./controls";
|
|
6
|
+
/**
|
|
7
|
+
* This control has own forms in it so if you want to use it you
|
|
8
|
+
* probably shouldn't use `await super.render(ctx, data, path)` in
|
|
9
|
+
* render method of you from implementation and you should write
|
|
10
|
+
* your own implementation of this method. See forms that uses
|
|
11
|
+
* this control for reference.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EditableCollectionSubset extends FormFieldControl {
|
|
14
|
+
fieldname: string;
|
|
15
|
+
actionname: string;
|
|
16
|
+
listLabel?: string | undefined;
|
|
17
|
+
selectLabel?: string | undefined;
|
|
18
|
+
constructor(fieldname: string, actionname: string, listLabel?: string | undefined, selectLabel?: string | undefined);
|
|
19
|
+
_render(ctx: BaseContext, fields: FormField[], data: FormData<string>): Templatable | Promise<Templatable>;
|
|
20
|
+
role: "input";
|
|
21
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable } from "tempstream";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
export declare abstract class FormControl {
|
|
6
|
+
abstract render(ctx: BaseContext, formFields: FormField[], data: FormData): Templatable | Promise<Templatable>;
|
|
7
|
+
abstract role: "input" | "decoration" | "messages" | "submit";
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable } from "tempstream";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormControl } from "./form-control";
|
|
6
|
+
export declare abstract class FormFieldControl extends FormControl {
|
|
7
|
+
fieldnames: string[];
|
|
8
|
+
role: "input";
|
|
9
|
+
constructor(fieldnames: string[]);
|
|
10
|
+
areFieldNamesValid(fields: FormField[]): boolean;
|
|
11
|
+
abstract _render(ctx: BaseContext, fields: FormField[], data: FormData): Templatable | Promise<Templatable>;
|
|
12
|
+
render(ctx: BaseContext, fields: FormField[], data: FormData): Templatable | Promise<Templatable>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { FormControl } from "./controls";
|
|
3
|
+
export declare class FormHeader extends FormControl {
|
|
4
|
+
text: string;
|
|
5
|
+
isVisible: (ctx: BaseContext) => Promise<boolean>;
|
|
6
|
+
role: "decoration";
|
|
7
|
+
constructor(text: string, isVisible?: (ctx: BaseContext) => Promise<boolean>);
|
|
8
|
+
render(ctx: BaseContext): Promise<string>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Templatable } from "tempstream";
|
|
2
|
+
import { FormControl } from "./controls";
|
|
3
|
+
/**
|
|
4
|
+
* This class will render `turbo-frame` tag so that u can
|
|
5
|
+
* embed other route inside your form. This will require
|
|
6
|
+
* to add value to `data: FormData` (inside your master form
|
|
7
|
+
* render function) with key `Frame.FRAME_PATH_KEY`. Value
|
|
8
|
+
* needs to be url to route that you want to embed. If you
|
|
9
|
+
* this value wont be provided frame will redner empty string.
|
|
10
|
+
* See `src/back/routes/profile/[id].form.ts` for an example.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Frame extends FormControl {
|
|
13
|
+
src: string;
|
|
14
|
+
constructor(src: string);
|
|
15
|
+
render(): Templatable | Promise<Templatable>;
|
|
16
|
+
role: "decoration";
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { FormField } from "../field";
|
|
3
|
+
import { FormData } from "../form";
|
|
4
|
+
import { FormFieldControl } from "./controls";
|
|
5
|
+
export declare class SimpleInput extends FormFieldControl {
|
|
6
|
+
fieldname: string;
|
|
7
|
+
options: {
|
|
8
|
+
id?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
autocomplete?: boolean;
|
|
11
|
+
type?: "color" | "date" | "email" | "file" | "month" | "number" | "password" | "search" | "tel" | "text" | "time" | "url" | "week";
|
|
12
|
+
value?: string;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
readonly?: boolean;
|
|
15
|
+
step?: number;
|
|
16
|
+
};
|
|
17
|
+
constructor(fieldname: string, options?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
autocomplete?: boolean;
|
|
21
|
+
type?: "color" | "date" | "email" | "file" | "month" | "number" | "password" | "search" | "tel" | "text" | "time" | "url" | "week";
|
|
22
|
+
value?: string;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
readonly?: boolean;
|
|
25
|
+
step?: number;
|
|
26
|
+
});
|
|
27
|
+
_render(_: BaseContext, fields: FormField[], data: FormData): string;
|
|
28
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
export declare type FormFieldValidationResponse = {
|
|
3
|
+
valid: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export declare type FormFieldValidationFn = (ctx: BaseContext, value: unknown, field: FormField) => Promise<FormFieldValidationResponse>;
|
|
7
|
+
export declare class FormField<Fieldnames extends string = string> {
|
|
8
|
+
name: Fieldnames;
|
|
9
|
+
required: boolean;
|
|
10
|
+
validator: FormFieldValidationFn;
|
|
11
|
+
constructor(name: Fieldnames, required?: boolean, validator?: FormFieldValidationFn);
|
|
12
|
+
_validate(ctx: BaseContext, value: unknown): Promise<FormFieldValidationResponse>;
|
|
13
|
+
getEmptyValue(): string;
|
|
14
|
+
}
|
|
15
|
+
export declare class PickFromListField<Fieldnames extends string = string> extends FormField<Fieldnames> {
|
|
16
|
+
name: Fieldnames;
|
|
17
|
+
required: boolean;
|
|
18
|
+
generateOptions: (ctx: BaseContext) => Promise<Record<string, string> | {
|
|
19
|
+
[i: string]: string;
|
|
20
|
+
}>;
|
|
21
|
+
customValidation: (ctx: BaseContext, value: unknown, instance: PickFromListField) => Promise<FormFieldValidationResponse>;
|
|
22
|
+
constructor(name: Fieldnames, required: boolean, generateOptions: (ctx: BaseContext) => Promise<Record<string, string> | {
|
|
23
|
+
[i: string]: string;
|
|
24
|
+
}>, customValidation?: (ctx: BaseContext, value: unknown, instance: PickFromListField) => Promise<FormFieldValidationResponse>);
|
|
25
|
+
valueInList(ctx: BaseContext, value: unknown): Promise<FormFieldValidationResponse>;
|
|
26
|
+
}
|
|
27
|
+
export declare class ChekboxedListField<Fieldnames extends string = string> extends FormField<Fieldnames> {
|
|
28
|
+
name: Fieldnames;
|
|
29
|
+
required: boolean;
|
|
30
|
+
generateOptions: (ctx: BaseContext) => Promise<Record<string, string> | {
|
|
31
|
+
[i: string]: string;
|
|
32
|
+
}>;
|
|
33
|
+
isVisible: (ctx: BaseContext) => Promise<boolean>;
|
|
34
|
+
constructor(name: Fieldnames, required: boolean, generateOptions: (ctx: BaseContext) => Promise<Record<string, string> | {
|
|
35
|
+
[i: string]: string;
|
|
36
|
+
}>, isVisible?: (ctx: BaseContext) => Promise<boolean>);
|
|
37
|
+
private isValueValid;
|
|
38
|
+
}
|
|
39
|
+
export declare class NumberField<Fieldnames extends string = string> extends FormField<Fieldnames> {
|
|
40
|
+
constructor(field_name: Fieldnames, required: boolean);
|
|
41
|
+
private isValueValid;
|
|
42
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/// <reference types="koa__router" />
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import Router from "@koa/router";
|
|
4
|
+
import { Templatable } from "tempstream";
|
|
5
|
+
import { FormControl } from "./controls/controls";
|
|
6
|
+
import { Mountable, PageErrorMessage } from "../page/page";
|
|
7
|
+
import { FormField } from "./field";
|
|
8
|
+
export declare type FormData<Fieldnames extends string = string> = {
|
|
9
|
+
values: Record<Fieldnames, string | string[] | number>;
|
|
10
|
+
raw_values: Record<Fieldnames, string | string[] | number>;
|
|
11
|
+
errors: Partial<Record<Fieldnames, string>>;
|
|
12
|
+
messages: {
|
|
13
|
+
type: "info" | "success" | "error";
|
|
14
|
+
text: string;
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
export declare abstract class Form<Fieldnames extends string = string> implements Mountable {
|
|
18
|
+
abstract fields: FormField<Fieldnames>[];
|
|
19
|
+
abstract controls: FormControl[];
|
|
20
|
+
defaultSuccessMessage: string;
|
|
21
|
+
submitButtonText: string;
|
|
22
|
+
canAccess(_: BaseContext): Promise<{
|
|
23
|
+
canAccess: boolean;
|
|
24
|
+
message: string;
|
|
25
|
+
}>;
|
|
26
|
+
renderError(_: BaseContext, error: PageErrorMessage): Promise<Templatable>;
|
|
27
|
+
validate(_: BaseContext, __: Record<string, unknown>): Promise<{
|
|
28
|
+
valid: boolean;
|
|
29
|
+
error: string;
|
|
30
|
+
}>;
|
|
31
|
+
private _validate;
|
|
32
|
+
render(ctx: BaseContext, data: FormData, _: string): Promise<Templatable>;
|
|
33
|
+
renderMessages(_: BaseContext, data: FormData): Templatable;
|
|
34
|
+
renderControls(ctx: BaseContext, data: FormData): Templatable;
|
|
35
|
+
makeFormTag(path: string): string;
|
|
36
|
+
private generateData;
|
|
37
|
+
onValuesInvalid(ctx: BaseContext, errors: Record<Fieldnames, string>, form_path: string): Promise<void>;
|
|
38
|
+
onError(ctx: BaseContext, error: unknown, form_path: string): Promise<void>;
|
|
39
|
+
abstract onSubmit(ctx: BaseContext, values: Record<Fieldnames, string | string[] | number>): void | Promise<void>;
|
|
40
|
+
onSuccess(ctx: BaseContext, form_path: string): Promise<void>;
|
|
41
|
+
mount(router: Router, path: string): void;
|
|
42
|
+
}
|
package/@types/index.d.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import Sealious from "sealious";
|
|
2
|
+
declare module "koa" {
|
|
3
|
+
interface BaseContext {
|
|
4
|
+
$context: Sealious.Context;
|
|
5
|
+
$body: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export * from "./forms/form";
|
|
9
|
+
export * from "./forms/controls/controls";
|
|
10
|
+
export * from "./forms/field";
|
|
11
|
+
export * from "./page/page";
|
|
12
|
+
export * from "./page/props-parser";
|
|
13
|
+
export * from "./utils/utils";
|
|
14
|
+
export * from "./forms/validator";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import { Collection, CollectionItem } from "sealious";
|
|
4
|
+
import { Templatable } from "tempstream";
|
|
5
|
+
import { Page } from "./page";
|
|
6
|
+
import { ShapeToType } from "@sealcode/ts-predicates";
|
|
7
|
+
import { PagePropsParser } from "./props-parser";
|
|
8
|
+
import { FormFieldControl } from "../forms/controls/controls";
|
|
9
|
+
import { FormField } from "../forms/field";
|
|
10
|
+
export declare const BasePagePropsShape: {};
|
|
11
|
+
export declare type BasePageProps = ShapeToType<typeof BasePagePropsShape>;
|
|
12
|
+
export declare const BaseListPagePropsShape: {
|
|
13
|
+
readonly page: import("@sealcode/ts-predicates").Predicate<number>;
|
|
14
|
+
readonly itemsPerPage: import("@sealcode/ts-predicates").Predicate<number>;
|
|
15
|
+
};
|
|
16
|
+
export declare type BaseListPageProps = ShapeToType<typeof BaseListPagePropsShape>;
|
|
17
|
+
export declare const BaseListPageDefaultProps: {
|
|
18
|
+
page: number;
|
|
19
|
+
itemsPerPage: number;
|
|
20
|
+
};
|
|
21
|
+
export declare type PropsErrors<PropsType> = Partial<Record<keyof PropsType, string>>;
|
|
22
|
+
export declare abstract class ListPage<ItemType, PropsType extends BaseListPageProps = BaseListPageProps> extends Page {
|
|
23
|
+
abstract getItems(ctx: BaseContext, props: PropsType): Promise<{
|
|
24
|
+
items: ItemType[];
|
|
25
|
+
}>;
|
|
26
|
+
abstract getTotalPages(ctx: BaseContext, props: PropsType): Promise<number>;
|
|
27
|
+
abstract renderItem(ctx: BaseContext, item: ItemType): Promise<Templatable>;
|
|
28
|
+
abstract propsParser: PagePropsParser<PropsType>;
|
|
29
|
+
filterFields: FormField<keyof PropsType>[];
|
|
30
|
+
filterControls: FormFieldControl[];
|
|
31
|
+
renderListContainer(_: BaseContext, content: Templatable): Templatable;
|
|
32
|
+
validateProps(ctx: BaseContext, props: PropsType): Promise<{
|
|
33
|
+
valid: boolean;
|
|
34
|
+
errors: PropsErrors<PropsType>;
|
|
35
|
+
}>;
|
|
36
|
+
getProps(ctx: BaseContext): Promise<{
|
|
37
|
+
parsed_props: PropsType;
|
|
38
|
+
errors: PropsErrors<PropsType>;
|
|
39
|
+
raw_props: PropsType;
|
|
40
|
+
}>;
|
|
41
|
+
render(ctx: BaseContext): Promise<import("stream").Readable>;
|
|
42
|
+
renderPagination(ctx: BaseContext, props: PropsType): Promise<import("stream").Readable>;
|
|
43
|
+
private renderPageButton;
|
|
44
|
+
renderFilters(ctx: BaseContext, parsed_props: PropsType, // parsed props don't include wrong values
|
|
45
|
+
raw_props: PropsType, errors: PropsErrors<PropsType>): import("stream").Readable;
|
|
46
|
+
}
|
|
47
|
+
export declare abstract class SealiousItemListPage<C extends Collection, PageProps extends BaseListPageProps = BaseListPageProps> extends ListPage<CollectionItem<C>, PageProps> {
|
|
48
|
+
collection: C;
|
|
49
|
+
constructor(collection: C);
|
|
50
|
+
getTotalPages(ctx: BaseContext, props: PageProps): Promise<number>;
|
|
51
|
+
getItems(ctx: BaseContext, props: PageProps): Promise<{
|
|
52
|
+
items: CollectionItem<C>[];
|
|
53
|
+
}>;
|
|
54
|
+
renderItem(_: BaseContext, item: CollectionItem<C>): Promise<Templatable>;
|
|
55
|
+
canAccess: (ctx: BaseContext) => Promise<{
|
|
56
|
+
canAccess: boolean;
|
|
57
|
+
message: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="koa__router" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import Router from "@koa/router";
|
|
4
|
+
import { BaseContext } from "koa";
|
|
5
|
+
import { Templatable } from "tempstream";
|
|
6
|
+
export declare type PageErrorMessage = {
|
|
7
|
+
type: "access" | "internal";
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
export interface Mountable {
|
|
11
|
+
mount: (router: Router, path: string) => void;
|
|
12
|
+
canAccess: (ctx: BaseContext) => Promise<{
|
|
13
|
+
canAccess: boolean;
|
|
14
|
+
message: string;
|
|
15
|
+
}>;
|
|
16
|
+
renderError(ctx: BaseContext, error: PageErrorMessage): Promise<Templatable>;
|
|
17
|
+
}
|
|
18
|
+
export declare abstract class Page implements Mountable {
|
|
19
|
+
mount(router: Router, path: string): void;
|
|
20
|
+
canAccess(_: BaseContext): Promise<{
|
|
21
|
+
canAccess: boolean;
|
|
22
|
+
message: string;
|
|
23
|
+
}>;
|
|
24
|
+
renderError(_: BaseContext, error: PageErrorMessage): Promise<import("stream").Readable>;
|
|
25
|
+
abstract render(ctx: BaseContext): Promise<Templatable>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Shape } from "@sealcode/ts-predicates";
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import { BasePageProps } from "./list";
|
|
4
|
+
export declare type EncodedProps = Record<string, unknown>;
|
|
5
|
+
export declare abstract class PagePropsParser<PropsType extends BasePageProps> {
|
|
6
|
+
propsShape: Shape;
|
|
7
|
+
defaultValues: Partial<PropsType>;
|
|
8
|
+
abstract decode(ctx: BaseContext): PropsType;
|
|
9
|
+
abstract encode(props: PropsType): EncodedProps;
|
|
10
|
+
abstract getHTMLInputName(prop_name: string): string;
|
|
11
|
+
constructor(propsShape: Shape, defaultValues: Partial<PropsType>);
|
|
12
|
+
overwriteProp(ctx: BaseContext, new_props: Partial<PropsType>): EncodedProps;
|
|
13
|
+
makeHiddenInputs(values: PropsType, fields_to_skip: string[]): string;
|
|
14
|
+
getDefaultValue<Key extends keyof PropsType>(key: Key): PropsType[Key] | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare class AllQueryParams<PropsType extends BasePageProps> extends PagePropsParser<PropsType> {
|
|
17
|
+
decode(ctx: BaseContext): PropsType;
|
|
18
|
+
encode(props: PropsType): Record<string, unknown>;
|
|
19
|
+
getHTMLInputName(prop_name: string): string;
|
|
20
|
+
}
|
package/@types/run.d.ts
ADDED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare function formTemplate(action_name: string, newfilefullpath: string): Promise<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const listTemplate: (action_name: string, newfilefullpath: string) => Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare function pageTemplate(action_name: string, fullpath: string): Promise<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function listCollections(): Promise<string[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function naturalNumbers(min: number, max: number): Generator<number, void, unknown>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(time: number): Promise<unknown>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare type Awaited<T> = T extends Promise<infer U> ? U : T;
|
|
2
|
+
export declare type UnwrapArray<T> = T extends Array<infer U> ? U : T;
|
|
3
|
+
export { sleep } from "./sleep";
|
|
4
|
+
export { naturalNumbers } from "./natural-numbers";
|
|
5
|
+
export { UrlWithNewParams } from "./url-with-new-params";
|
|
6
|
+
export { exec } from "./exec";
|
|
7
|
+
export { importPath, curryImportPath } from "./import-path";
|
|
8
|
+
export { listCollections } from "./list-collections";
|
|
9
|
+
export { walkDir } from "./walk";
|
package/@types/utils/walk.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function walkDir(dir: string): Promise<string[]>;
|
package/lib/add-collection.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -20,22 +11,20 @@ const question_1 = require("./utils/question");
|
|
|
20
11
|
const collection_1 = require("./templates/collection");
|
|
21
12
|
const generate_collections_1 = require("./generate-collections");
|
|
22
13
|
const target_locreq = locreq_1.default(process.cwd());
|
|
23
|
-
function addCollection() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (fs_1.existsSync(file_path)) {
|
|
29
|
-
// eslint-disable-next-line no-console
|
|
30
|
-
console.error(`ERROR: File ${file_path} already exists.`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
yield fs_1.promises.mkdir(path_1.resolve(file_path, "../"), { recursive: true });
|
|
34
|
-
yield fs_1.promises.writeFile(file_path, collection_1.collectionTemplate(collection_name));
|
|
14
|
+
async function addCollection() {
|
|
15
|
+
const collection_name = await question_1.question('What\'s the name of the collection class (e.g. "SecretDocuments", must start with a capital letter): ', (s) => s.length > 3 && s[0].toUpperCase() == s[0]);
|
|
16
|
+
const url = await question_1.question("Enter the url-friendly name for the collection (e.g. secret-documents): ", (s) => !s.includes("/") && !s.includes(" "));
|
|
17
|
+
const file_path = target_locreq.resolve(`src/back/collections/${url}.ts`);
|
|
18
|
+
if (fs_1.existsSync(file_path)) {
|
|
35
19
|
// eslint-disable-next-line no-console
|
|
36
|
-
console.
|
|
37
|
-
|
|
38
|
-
}
|
|
20
|
+
console.error(`ERROR: File ${file_path} already exists.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
await fs_1.promises.mkdir(path_1.resolve(file_path, "../"), { recursive: true });
|
|
24
|
+
await fs_1.promises.writeFile(file_path, collection_1.collectionTemplate(collection_name));
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.log(`${file_path} created`);
|
|
27
|
+
await generate_collections_1.generateCollections();
|
|
39
28
|
}
|
|
40
29
|
exports.addCollection = addCollection;
|
|
41
30
|
//# sourceMappingURL=add-collection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-collection.js","sourceRoot":"","sources":["../src/add-collection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add-collection.js","sourceRoot":"","sources":["../src/add-collection.ts"],"names":[],"mappings":";;;;;;AAAA,+BAA+B;AAC/B,oDAA6B;AAC7B,2BAAgD;AAChD,+CAA4C;AAC5C,uDAA4D;AAC5D,iEAA6D;AAC7D,MAAM,aAAa,GAAG,gBAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAEtC,KAAK,UAAU,aAAa;IAClC,MAAM,eAAe,GAAG,MAAM,mBAAQ,CACrC,uGAAuG,EACvG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CACzD,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,mBAAQ,CACzB,0EAA0E,EAC1E,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CACnD,CAAC;IACF,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAwB,GAAG,KAAK,CAAC,CAAC;IAE1E,IAAI,eAAU,CAAC,SAAS,CAAC,EAAE;QAC1B,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,eAAe,SAAS,kBAAkB,CAAC,CAAC;QAC1D,OAAO;KACP;IACD,MAAM,aAAE,CAAC,KAAK,CAAC,cAAO,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,aAAE,CAAC,SAAS,CAAC,SAAS,EAAE,+BAAkB,CAAC,eAAe,CAAC,CAAC,CAAC;IACnE,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC;IACpC,MAAM,0CAAmB,EAAE,CAAC;AAC7B,CAAC;AArBD,sCAqBC"}
|
package/lib/add-route.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -22,31 +13,33 @@ const route_test_1 = require("./templates/route-test");
|
|
|
22
13
|
const escape_url_params_1 = require("./utils/escape-url-params");
|
|
23
14
|
const locreq_1 = __importDefault(require("locreq"));
|
|
24
15
|
const generate_routes_1 = require("./generate-routes");
|
|
16
|
+
const list_1 = require("./templates/list");
|
|
25
17
|
const target_locreq = locreq_1.default(process.cwd());
|
|
26
|
-
function addRoute() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
yield fs_1.promises.mkdir(path_1.resolve(file_path, "../"), { recursive: true });
|
|
42
|
-
yield fs_1.promises.writeFile(file_path, template(action, file_path));
|
|
43
|
-
yield fs_1.promises.writeFile(test_file_path, route_test_1.testTemplate(action, file_path));
|
|
44
|
-
// eslint-disable-next-line no-console
|
|
45
|
-
console.log(`${file_path} created`);
|
|
18
|
+
async function addRoute() {
|
|
19
|
+
const action = await question_1.question('What\'s the name of the action (e.g. "AddUser"): ', (s) => s.length > 3);
|
|
20
|
+
const url = await question_1.question("Enter a full absolute path for the new route (e.g. /admin/users/add): ", (s) => s.trim()[0] == "/");
|
|
21
|
+
const mode_answer = (await question_1.question("Is this a page (p), a form (f), or a list (l)? ", (a) => ["p", "f", "l"].includes(a.toLowerCase())));
|
|
22
|
+
const mode = { p: "page", f: "form", l: "list" }[mode_answer];
|
|
23
|
+
const file_path = target_locreq.resolve(`src/back/routes/${escape_url_params_1.escape_url_params(url)}.${mode}.ts`);
|
|
24
|
+
const test_file_path = target_locreq.resolve(`src/back/routes/${escape_url_params_1.escape_url_params(url)}.test.ts`);
|
|
25
|
+
const template = {
|
|
26
|
+
page: page_1.pageTemplate,
|
|
27
|
+
form: form_1.formTemplate,
|
|
28
|
+
list: list_1.listTemplate,
|
|
29
|
+
}[mode];
|
|
30
|
+
if (fs_1.existsSync(file_path)) {
|
|
46
31
|
// eslint-disable-next-line no-console
|
|
47
|
-
console.
|
|
48
|
-
|
|
49
|
-
}
|
|
32
|
+
console.error(`ERROR: File ${file_path} already exists.`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
await fs_1.promises.mkdir(path_1.resolve(file_path, "../"), { recursive: true });
|
|
36
|
+
await fs_1.promises.writeFile(file_path, await template(action, file_path));
|
|
37
|
+
await fs_1.promises.writeFile(test_file_path, route_test_1.testTemplate(action, file_path));
|
|
38
|
+
// eslint-disable-next-line no-console
|
|
39
|
+
console.log(`${file_path} created`);
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.log(`${test_file_path} created`);
|
|
42
|
+
await generate_routes_1.generateRoutes();
|
|
50
43
|
}
|
|
51
44
|
exports.addRoute = addRoute;
|
|
52
45
|
//# sourceMappingURL=add-route.js.map
|
package/lib/add-route.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-route.js","sourceRoot":"","sources":["../src/add-route.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add-route.js","sourceRoot":"","sources":["../src/add-route.ts"],"names":[],"mappings":";;;;;;AAAA,+BAA+B;AAC/B,2BAAgD;AAChD,+CAA4C;AAC5C,2CAAgD;AAChD,2CAAgD;AAChD,uDAAsD;AACtD,iEAA8D;AAE9D,oDAA6B;AAC7B,uDAAmD;AACnD,2CAAgD;AAChD,MAAM,aAAa,GAAG,gBAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAEtC,KAAK,UAAU,QAAQ;IAC7B,MAAM,MAAM,GAAG,MAAM,mBAAQ,CAC5B,mDAAmD,EACnD,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAC3B,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,mBAAQ,CACzB,wEAAwE,EACxE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CACjC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,MAAM,mBAAQ,CAClC,iDAAiD,EACjD,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CACxD,CAAoB,CAAC;IACtB,MAAM,IAAI,GAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAG,CAAC,WAAW,CAAC,CAAC;IAEvE,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CACtC,mBAAmB,qCAAiB,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,CACtD,CAAC;IACF,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAC3C,mBAAmB,qCAAiB,CAAC,GAAG,CAAC,UAAU,CACnD,CAAC;IACF,MAAM,QAAQ,GAAG;QAChB,IAAI,EAAE,mBAAY;QAClB,IAAI,EAAE,mBAAY;QAClB,IAAI,EAAE,mBAAY;KAClB,CAAC,IAAI,CAAC,CAAC;IAER,IAAI,eAAU,CAAC,SAAS,CAAC,EAAE;QAC1B,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,eAAe,SAAS,kBAAkB,CAAC,CAAC;QAC1D,OAAO;KACP;IACD,MAAM,aAAE,CAAC,KAAK,CAAC,cAAO,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,aAAE,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACjE,MAAM,aAAE,CAAC,SAAS,CAAC,cAAc,EAAE,yBAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACpE,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC;IACpC,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,GAAG,cAAc,UAAU,CAAC,CAAC;IACzC,MAAM,gCAAc,EAAE,CAAC;AACxB,CAAC;AAxCD,4BAwCC"}
|