@sealcode/sealgen 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/@types/forms/controls/checkboxed-list-input.d.ts +2 -2
  2. package/@types/forms/controls/dropdown.d.ts +2 -2
  3. package/@types/forms/controls/editable-collection-subset.d.ts +2 -2
  4. package/@types/forms/controls/form-control.d.ts +2 -2
  5. package/@types/forms/controls/form-field-control.d.ts +2 -2
  6. package/@types/forms/controls/form-header.d.ts +4 -4
  7. package/@types/forms/controls/simple-input.d.ts +4 -2
  8. package/@types/forms/fields/checkboxed-list.d.ts +7 -7
  9. package/@types/forms/fields/collection-field.d.ts +3 -3
  10. package/@types/forms/fields/field.d.ts +6 -6
  11. package/@types/forms/fields/number.d.ts +3 -3
  12. package/@types/forms/fields/pick-from-list.d.ts +7 -7
  13. package/@types/forms/fields/simple-form-field.d.ts +2 -2
  14. package/@types/forms/form.d.ts +10 -10
  15. package/@types/index.d.ts +5 -3
  16. package/@types/make-hidden-inputs.d.ts +5 -4
  17. package/@types/page/access-control.d.ts +2 -2
  18. package/@types/page/list.d.ts +14 -14
  19. package/@types/page/mountable.d.ts +9 -9
  20. package/@types/page/page.d.ts +6 -6
  21. package/@types/page/props-parser.d.ts +4 -4
  22. package/@types/utils/translate.d.ts +3 -0
  23. package/@types/utils/url-with-new-params.d.ts +2 -2
  24. package/lib/build.js +2 -1
  25. package/lib/build.js.map +1 -1
  26. package/lib/forms/controls/checkboxed-list-input.js.map +1 -1
  27. package/lib/forms/controls/dropdown.js.map +1 -1
  28. package/lib/forms/controls/editable-collection-subset.js.map +1 -1
  29. package/lib/forms/controls/form-header.js.map +1 -1
  30. package/lib/forms/controls/simple-input.js +4 -2
  31. package/lib/forms/controls/simple-input.js.map +1 -1
  32. package/lib/forms/fields/checkboxed-list.js.map +1 -1
  33. package/lib/forms/fields/collection-field.js.map +1 -1
  34. package/lib/forms/fields/field.js +5 -1
  35. package/lib/forms/fields/field.js.map +1 -1
  36. package/lib/forms/fields/number.js.map +1 -1
  37. package/lib/forms/fields/pick-from-list.js.map +1 -1
  38. package/lib/forms/fields/simple-form-field.js.map +1 -1
  39. package/lib/forms/form.js +6 -3
  40. package/lib/forms/form.js.map +1 -1
  41. package/lib/generate-routes.js +18 -2
  42. package/lib/generate-routes.js.map +1 -1
  43. package/lib/index.js +16 -2
  44. package/lib/index.js.map +1 -1
  45. package/lib/make-hidden-inputs.js.map +1 -1
  46. package/lib/page/access-control.js.map +1 -1
  47. package/lib/page/list.js +2 -1
  48. package/lib/page/list.js.map +1 -1
  49. package/lib/page/mountable.js.map +1 -1
  50. package/lib/page/page.js.map +1 -1
  51. package/lib/page/props-parser.js.map +1 -1
  52. package/lib/templates/form.js +9 -16
  53. package/lib/templates/form.js.map +1 -1
  54. package/lib/templates/list.js +4 -4
  55. package/lib/templates/list.js.map +1 -1
  56. package/lib/templates/page.js +3 -3
  57. package/lib/utils/translate.js +10 -0
  58. package/lib/utils/translate.js.map +1 -0
  59. package/lib/utils/url-with-new-params.js.map +1 -1
  60. package/package.json +3 -2
  61. package/src/build.ts +2 -1
  62. package/src/forms/controls/checkboxed-list-input.ts +2 -2
  63. package/src/forms/controls/dropdown.ts +2 -2
  64. package/src/forms/controls/editable-collection-subset.ts +2 -2
  65. package/src/forms/controls/form-control.ts +2 -2
  66. package/src/forms/controls/form-field-control.ts +2 -2
  67. package/src/forms/controls/form-header.ts +3 -3
  68. package/src/forms/controls/simple-input.ts +7 -6
  69. package/src/forms/fields/checkboxed-list.ts +5 -5
  70. package/src/forms/fields/collection-field.ts +3 -3
  71. package/src/forms/fields/field.ts +17 -7
  72. package/src/forms/fields/number.ts +3 -3
  73. package/src/forms/fields/pick-from-list.ts +5 -5
  74. package/src/forms/fields/simple-form-field.ts +2 -2
  75. package/src/forms/form.ts +15 -12
  76. package/src/generate-routes.ts +18 -2
  77. package/src/index.ts +5 -3
  78. package/src/make-hidden-inputs.ts +6 -5
  79. package/src/page/access-control.ts +2 -2
  80. package/src/page/list.ts +17 -24
  81. package/src/page/mountable.ts +11 -11
  82. package/src/page/page.ts +5 -5
  83. package/src/page/props-parser.ts +4 -7
  84. package/src/templates/form.ts +9 -16
  85. package/src/templates/list.ts +4 -4
  86. package/src/templates/page.ts +3 -3
  87. package/src/utils/translate.ts +13 -0
  88. package/src/utils/url-with-new-params.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
- import { BaseContext } from "koa";
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: BaseContext
14
+ ctx: Context
15
15
  ) => Promise<Record<string, string> | { [i: string]: string }>,
16
- public isVisible: (ctx: BaseContext) => Promise<boolean> = () =>
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
- _: BaseContext,
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
- _: BaseContext,
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 { BaseContext } from "koa";
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: BaseContext,
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: BaseContext,
40
+ ctx: Context,
41
41
  value: FieldOutput<F>
42
42
  ): Promise<FormFieldValidationResponse> {
43
43
  const { valid, reason } = await this.sealiousField.checkValue(
@@ -1,10 +1,11 @@
1
- import { BaseContext } from "koa";
1
+ import { Context } from "koa";
2
+ import { t } from "../../utils/translate";
2
3
  import { FormDataValue } from "../form";
3
4
 
4
5
  export type FormFieldValidationResponse = { valid: boolean; message: string };
5
6
 
6
7
  export type FormFieldValidationFn<ValueType> = (
7
- ctx: BaseContext,
8
+ ctx: Context,
8
9
  value: ValueType,
9
10
  field: FormField<ValueType>
10
11
  ) => Promise<FormFieldValidationResponse>;
@@ -28,14 +29,23 @@ export abstract class FormField<ParsedValue extends unknown = unknown> {
28
29
  }
29
30
 
30
31
  public async _validate(
31
- ctx: BaseContext,
32
+ ctx: Context,
32
33
  value: ParsedValue
33
34
  ): Promise<FormFieldValidationResponse> {
34
35
  if (
35
36
  this.required &&
36
37
  (value === "" || value === null || value === undefined)
37
38
  ) {
38
- return { valid: false, message: "This field is required" };
39
+ return {
40
+ valid: false,
41
+
42
+ message: t(
43
+ ctx,
44
+ "field_is_required",
45
+ [],
46
+ "This field is required"
47
+ ),
48
+ };
39
49
  }
40
50
  return this.isValueValid(ctx, value);
41
51
  }
@@ -43,19 +53,19 @@ export abstract class FormField<ParsedValue extends unknown = unknown> {
43
53
  public abstract getEmptyValue(): ParsedValue;
44
54
 
45
55
  public async isValueValid(
46
- ctx: BaseContext,
56
+ ctx: Context,
47
57
  value: ParsedValue
48
58
  ): Promise<FormFieldValidationResponse> {
49
59
  return { valid: true, message: "" };
50
60
  }
51
61
 
52
62
  abstract parse(
53
- ctx: BaseContext,
63
+ ctx: Context,
54
64
  raw_value: FormDataValue
55
65
  ): Promise<FieldParseResult<ParsedValue>>;
56
66
 
57
67
  async getValue(
58
- ctx: BaseContext,
68
+ ctx: Context,
59
69
  all_form_values: Record<string, FormDataValue>
60
70
  ): Promise<{
61
71
  valid: boolean;
@@ -1,5 +1,5 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
- import { BaseContext } from "koa";
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(_: BaseContext, value: unknown) {
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
- _: BaseContext,
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 { BaseContext } from "koa";
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: BaseContext
10
+ ctx: Context
11
11
  ) => Promise<Record<string, string> | { [i: string]: string }>,
12
12
  public customValidation: (
13
- ctx: BaseContext,
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: BaseContext,
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: BaseContext,
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 { BaseContext } from "koa";
3
+ import { Context } from "koa";
4
4
 
5
5
  export class SimpleFormField extends FormField<string | null> {
6
6
  async parse(
7
- _: BaseContext,
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 { BaseContext } from "koa";
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
- _: BaseContext
39
+ _: Context
40
40
  ): Promise<{ canAccess: boolean; message: string }> {
41
41
  return { canAccess: true, message: "" };
42
42
  }
43
43
 
44
44
  async renderError(
45
- _: BaseContext,
45
+ _: Context,
46
46
  error: PageErrorMessage
47
- ): Promise<Templatable> {
47
+ ): Promise<FlatTemplatable> {
48
48
  return tempstream/* HTML */ `<div>${error.message}</div>`;
49
49
  }
50
50
 
51
- async render(ctx: BaseContext, data: FormData): Promise<Templatable> {
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: BaseContext,
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: BaseContext,
80
+ ctx: Context,
81
81
  data: FormData,
82
82
  error: unknown
83
83
  ): Promise<void> {
@@ -96,13 +96,13 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
96
96
  }
97
97
 
98
98
  public abstract onSubmit(
99
- ctx: BaseContext,
99
+ ctx: Context,
100
100
  data: FormData
101
101
  ): void | Promise<void>;
102
102
 
103
- public async onSuccess(ctx: BaseContext): Promise<void> {
103
+ public async onSuccess(ctx: Context, data: FormData): Promise<void> {
104
104
  ctx.body = await this.render(ctx, {
105
- raw_values: ctx.$body,
105
+ raw_values: data.raw_values,
106
106
  messages: [{ type: "success", text: this.defaultSuccessMessage }],
107
107
  });
108
108
  ctx.status = 422;
@@ -139,7 +139,10 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
139
139
  raw_values: ctx.$body,
140
140
  messages: [],
141
141
  });
142
- await this.onSuccess(ctx);
142
+ await this.onSuccess(ctx, {
143
+ raw_values: ctx.$body,
144
+ messages: [],
145
+ });
143
146
  } catch (e: unknown) {
144
147
  // eslint-disable-next-line no-console
145
148
  console.dir(e, { depth: 5 });
@@ -168,7 +171,7 @@ export abstract class Form<F extends Fields> extends Mountable<F> {
168
171
  });
169
172
  }
170
173
 
171
- extractRawValues(ctx: BaseContext): Record<string, FormDataValue> {
174
+ extractRawValues(ctx: Context): Record<string, FormDataValue> {
172
175
  return ctx.$body;
173
176
  }
174
177
  }
@@ -50,6 +50,7 @@ export async function generateRoutes(): Promise<void> {
50
50
  target_locreq.resolve("src/back/routes/routes.ts"),
51
51
  `// DO NOT EDIT! This file is generated automaticaly with npm run generate-routes
52
52
 
53
+ import Koa, { Context } from "koa";
53
54
  import Router from "@koa/router";
54
55
  import { Middlewares } from "sealious";
55
56
  import { Mountable } from "@sealcode/sealgen";
@@ -68,12 +69,27 @@ ${files
68
69
  .map(({ actionName, url }) => `export const ${actionName}URL = "${url}";`)
69
70
  .join("\n")}
70
71
 
71
- function mount(router: Router, URL: string, mountable: Mountable){
72
- router.use(URL, Middlewares.extractContext(), Middlewares.parseBody());
72
+ async function handleHtmlPromise(ctx: Context, next: Koa.Next) {
73
+ await next();
74
+ if (ctx.body instanceof Promise) {
75
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
76
+ ctx.body = await ctx.body;
77
+ }
78
+ ctx.set("content-type", "text/html;charset=utf-8");
79
+ }
80
+
81
+ function mount(router: Router, URL: string, mountable: Mountable) {
82
+ router.use(
83
+ URL,
84
+ Middlewares.extractContext(),
85
+ Middlewares.parseBody(),
86
+ handleHtmlPromise
87
+ );
73
88
  mountable.init();
74
89
  mountable.mount(router, URL);
75
90
  // to automatically add trailing slashes:
76
91
  router.get(URL.slice(0, -1), (ctx) => ctx.redirect(URL));
92
+ router.use(URL, (ctx) => ctx.set("content-type", "text/html;charset=utf-8"));
77
93
  }
78
94
 
79
95
  export default function mountAutoRoutes(router: Router) {
package/src/index.ts CHANGED
@@ -1,18 +1,20 @@
1
- import Sealious from "sealious";
1
+ import Sealious, { App } from "sealious";
2
2
  import { FormDataValue } from "./forms/form";
3
3
 
4
4
  declare module "koa" {
5
5
  interface BaseContext {
6
6
  $context: Sealious.Context;
7
+ $app: App;
7
8
  $body: Record<string, FormDataValue>;
8
9
  }
9
10
  }
10
11
 
11
- export * from "./forms/controls/controls";
12
- export * from "./forms/fields/field";
12
+ export * as Controls from "./forms/controls/controls";
13
+ export * as Fields from "./forms/fields/field";
13
14
  export * from "./page/mountable";
14
15
  export * from "./page/page";
15
16
  export * from "./forms/form";
16
17
  export * from "./page/props-parser";
17
18
  export * from "./utils/utils";
18
19
  export * from "./page/list";
20
+ export * from "./utils/translate";
@@ -1,13 +1,14 @@
1
- import { BaseContext } from "koa";
2
- import { Templatable, tempstream } from "tempstream";
3
- import { FormDataValue, FormField } from ".";
1
+ import { Context } from "koa";
2
+ import { FlatTemplatable, tempstream } from "tempstream";
3
+ import { FormDataValue } from ".";
4
+ import { FormField } from "./forms/fields/field";
4
5
 
5
6
  export function makeHiddenInputs(
6
- ctx: BaseContext,
7
+ ctx: Context,
7
8
  fields: Record<string, FormField>,
8
9
  values: Record<string, FormDataValue>,
9
10
  fields_to_skip: string[]
10
- ): Templatable {
11
+ ): FlatTemplatable {
11
12
  return tempstream`${Object.entries(fields)
12
13
  .filter(([key]) => !fields_to_skip.includes(key))
13
14
  .map(
@@ -1,8 +1,8 @@
1
- import { BaseContext } from "koa";
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: BaseContext) {
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) {
package/src/page/list.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { BaseContext } from "koa";
1
+ import { Context } from "koa";
2
2
  import { Collection, CollectionItem, ItemFields, ItemList } from "sealious";
3
+
3
4
  import { Templatable, tempstream, FlatTemplatable } from "tempstream";
4
5
  import { peopleWhoCan } from "./access-control";
5
6
  import { Page } from "./page";
@@ -23,22 +24,19 @@ export abstract class ListPage<
23
24
  F extends typeof BaseListPageFields
24
25
  > extends Page<F> {
25
26
  abstract getItems(
26
- ctx: BaseContext,
27
+ ctx: Context,
27
28
  page: number,
28
29
  itemsPerPage: number,
29
30
  values: Record<string, FormDataValue>
30
31
  ): Promise<ItemType[]>;
31
32
 
32
33
  abstract getTotalPages(
33
- ctx: BaseContext,
34
+ ctx: Context,
34
35
  itemsPerPage: number,
35
36
  values: Record<string, FormDataValue>
36
37
  ): Promise<number>;
37
38
 
38
- abstract renderItem(
39
- ctx: BaseContext,
40
- item: ItemType
41
- ): Promise<FlatTemplatable>;
39
+ abstract renderItem(ctx: Context, item: ItemType): Promise<FlatTemplatable>;
42
40
 
43
41
  filterFields: Record<string, FormField> = {};
44
42
  filterControls: FormFieldControl[] = [];
@@ -50,19 +48,20 @@ export abstract class ListPage<
50
48
  }
51
49
  }
52
50
 
53
- renderListContainer(_: BaseContext, content: Templatable): FlatTemplatable {
51
+ renderListContainer(_: Context, content: Templatable): FlatTemplatable {
54
52
  return tempstream`<div>${content}</div>`;
55
53
  }
56
54
 
57
- async render(ctx: BaseContext): Promise<FlatTemplatable> {
55
+ async render(ctx: Context): Promise<FlatTemplatable> {
58
56
  const values = this.extractRawValues(ctx);
59
57
  const { parsed: page } = await this.fields.page.getValue(ctx, values);
60
58
  const { parsed: itemsPerPage } =
61
59
  await this.fields.itemsPerPage.getValue(ctx, values);
62
60
 
61
+ const items_promise = this.getItems(ctx, page, itemsPerPage, values);
63
62
  return tempstream`${this.renderPagination(ctx, values)}
64
63
  ${this.renderFilters(ctx)}
65
- ${this.getItems(ctx, page, itemsPerPage, values).then((items) =>
64
+ ${items_promise.then((items) =>
66
65
  this.renderListContainer(
67
66
  ctx,
68
67
  items.map((item) => this.renderItem(ctx, item))
@@ -71,7 +70,7 @@ export abstract class ListPage<
71
70
  }
72
71
 
73
72
  async renderPagination(
74
- ctx: BaseContext,
73
+ ctx: Context,
75
74
  values: Record<string, FormDataValue>
76
75
  ): Promise<FlatTemplatable> {
77
76
  const { parsed: page } = await this.fields.page.getValue(ctx, values);
@@ -110,7 +109,7 @@ export abstract class ListPage<
110
109
  </center>`;
111
110
  }
112
111
 
113
- private renderPageButton(ctx: BaseContext, page: number, text: string) {
112
+ private renderPageButton(ctx: Context, page: number, text: string) {
114
113
  return /* HTML */ `<a
115
114
  href="${UrlWithNewParams(
116
115
  ctx,
@@ -123,7 +122,7 @@ export abstract class ListPage<
123
122
  >`;
124
123
  }
125
124
 
126
- async getFilterValues(ctx: BaseContext): Promise<Record<string, unknown>> {
125
+ async getFilterValues(ctx: Context): Promise<Record<string, unknown>> {
127
126
  const filter = {} as Record<string, unknown>;
128
127
  const raw_values = this.extractRawValues(ctx);
129
128
  for (const [fieldname, field] of Object.entries(this.filterFields)) {
@@ -134,7 +133,7 @@ export abstract class ListPage<
134
133
  return filter;
135
134
  }
136
135
 
137
- renderFilters(ctx: BaseContext): FlatTemplatable {
136
+ renderFilters(ctx: Context): FlatTemplatable {
138
137
  const values = this.extractRawValues(ctx);
139
138
  return tempstream/* HTML */ `<form method="GET">
140
139
  ${makeHiddenInputs(ctx, this.fields, values, [
@@ -157,20 +156,14 @@ export abstract class SealiousItemListPage<
157
156
  super();
158
157
  }
159
158
 
160
- async getTotalPages(
161
- ctx: BaseContext,
162
- itemsPerPage: number
163
- ): Promise<number> {
159
+ async getTotalPages(ctx: Context, itemsPerPage: number): Promise<number> {
164
160
  const query = this.collection.list(ctx.$context);
165
161
  await this.addFilter(ctx, query);
166
162
  const { items } = await query.fetch();
167
163
  return Math.ceil(items.length / itemsPerPage);
168
164
  }
169
165
 
170
- protected async addFilter(
171
- ctx: BaseContext,
172
- list: ItemList<C>
173
- ): Promise<void> {
166
+ protected async addFilter(ctx: Context, list: ItemList<C>): Promise<void> {
174
167
  const filters = await this.getFilterValues(ctx);
175
168
  if (Object.keys(filters).length) {
176
169
  list.filter(filters as Partial<ItemFields<C>>);
@@ -178,7 +171,7 @@ export abstract class SealiousItemListPage<
178
171
  }
179
172
 
180
173
  async getItems(
181
- ctx: BaseContext,
174
+ ctx: Context,
182
175
  page: number,
183
176
  itemsPerPage: number
184
177
  ): Promise<CollectionItem<C>[]> {
@@ -191,7 +184,7 @@ export abstract class SealiousItemListPage<
191
184
  }
192
185
 
193
186
  async renderItem(
194
- _: BaseContext,
187
+ _: Context,
195
188
  item: CollectionItem<C>
196
189
  ): Promise<FlatTemplatable> {
197
190
  return `<div>${item.id}</div>`;
@@ -1,7 +1,7 @@
1
1
  import Router from "@koa/router";
2
2
  import { FormControl } from "../forms/controls/form-control";
3
- import { BaseContext } from "koa";
4
- import { FlatTemplatable, Templatable, tempstream } from "tempstream";
3
+ import { Context } from "koa";
4
+ import { FlatTemplatable, tempstream } from "tempstream";
5
5
  import { FormField } from "../forms/fields/field";
6
6
  import { FormData, FormDataValue, FormMessage } from "../forms/form";
7
7
 
@@ -20,19 +20,19 @@ export abstract class Mountable<F extends Fields = Fields> {
20
20
  abstract mount(router: Router, path: string): void;
21
21
 
22
22
  abstract canAccess(
23
- ctx: BaseContext
23
+ ctx: Context
24
24
  ): Promise<{ canAccess: boolean; message: string }>;
25
25
 
26
26
  abstract renderError(
27
- ctx: BaseContext,
27
+ ctx: Context,
28
28
  error: PageErrorMessage
29
- ): Promise<Templatable>;
29
+ ): Promise<FlatTemplatable>;
30
30
 
31
- abstract extractRawValues(ctx: BaseContext): Record<string, FormDataValue>;
31
+ abstract extractRawValues(ctx: Context): Record<string, FormDataValue>;
32
32
 
33
33
  // this one is meant to be overwritten
34
34
  async validateValues(
35
- ctx: BaseContext,
35
+ ctx: Context,
36
36
  data: Record<string, FormDataValue>
37
37
  ): Promise<{ valid: boolean; error: string }> {
38
38
  return {
@@ -42,7 +42,7 @@ export abstract class Mountable<F extends Fields = Fields> {
42
42
  }
43
43
 
44
44
  protected async validate(
45
- ctx: BaseContext,
45
+ ctx: Context,
46
46
  values: Record<string, FormDataValue>
47
47
  ): Promise<{
48
48
  valid: boolean;
@@ -83,7 +83,7 @@ export abstract class Mountable<F extends Fields = Fields> {
83
83
  }
84
84
 
85
85
  public renderControls(
86
- ctx: BaseContext,
86
+ ctx: Context,
87
87
  data: FormData<keyof Fields>
88
88
  ): FlatTemplatable {
89
89
  return tempstream/* HTML */ `${this.controls.map((control) =>
@@ -92,9 +92,9 @@ export abstract class Mountable<F extends Fields = Fields> {
92
92
  }
93
93
 
94
94
  public renderMessages(
95
- _: BaseContext,
95
+ _: Context,
96
96
  data: FormData<keyof Fields>
97
- ): Templatable {
97
+ ): FlatTemplatable {
98
98
  return tempstream/* HTML */ `<div class="form-messages">
99
99
  ${data.messages.map(
100
100
  (message) =>
package/src/page/page.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Router from "@koa/router";
2
- import { BaseContext } from "koa";
2
+ import { Context } from "koa";
3
3
 
4
4
  import { FlatTemplatable, Templatable, tempstream } from "tempstream";
5
5
  import { AllQueryParams } from "..";
@@ -21,20 +21,20 @@ export abstract class Page<
21
21
  }
22
22
 
23
23
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
- async canAccess(_: BaseContext) {
24
+ async canAccess(_: Context) {
25
25
  return { canAccess: true, message: "" };
26
26
  }
27
27
 
28
28
  async renderError(
29
- _: BaseContext,
29
+ _: Context,
30
30
  error: PageErrorMessage
31
31
  ): Promise<FlatTemplatable> {
32
32
  return tempstream/* HTML */ `<div>${error.message}</div>`;
33
33
  }
34
34
 
35
- public abstract render(ctx: BaseContext): Promise<Templatable>;
35
+ public abstract render(ctx: Context): Promise<FlatTemplatable>;
36
36
 
37
- extractRawValues(ctx: BaseContext): Record<string, FormDataValue> {
37
+ extractRawValues(ctx: Context): Record<string, FormDataValue> {
38
38
  return this.propsParser.decode(ctx);
39
39
  }
40
40
  }
@@ -1,4 +1,4 @@
1
- import { BaseContext } from "koa";
1
+ import { Context } from "koa";
2
2
  import merge from "merge";
3
3
  import { FormData, FormDataValue } from "..";
4
4
  import { BasePageProps } from "./list";
@@ -10,14 +10,11 @@ export type EncodedProps = Record<string, unknown>;
10
10
  // or any other exotic types is done by fields logic.
11
11
 
12
12
  export abstract class PagePropsParser<PropsType> {
13
- abstract decode(ctx: BaseContext): Record<string, FormDataValue>;
13
+ abstract decode(ctx: Context): Record<string, FormDataValue>;
14
14
  abstract encode(props: Record<string, FormData>): EncodedProps;
15
15
  abstract getHTMLInputName(prop_name: string): string;
16
16
 
17
- overwriteProp(
18
- ctx: BaseContext,
19
- new_props: Partial<PropsType>
20
- ): EncodedProps {
17
+ overwriteProp(ctx: Context, new_props: Partial<PropsType>): EncodedProps {
21
18
  const result = {};
22
19
  merge.recursive(result, this.decode(ctx), new_props);
23
20
  return result;
@@ -27,7 +24,7 @@ export abstract class PagePropsParser<PropsType> {
27
24
  export class AllQueryParams<
28
25
  PropsType extends BasePageProps
29
26
  > extends PagePropsParser<PropsType> {
30
- decode(ctx: BaseContext): Record<string, FormDataValue> {
27
+ decode(ctx: Context): Record<string, FormDataValue> {
31
28
  return ctx.query;
32
29
  }
33
30