@sealcode/sealgen 0.15.5 → 0.15.7

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 (35) hide show
  1. package/@types/src/builder.d.ts +0 -1
  2. package/@types/src/esbuild-plugins/load-assets.d.ts +2 -1
  3. package/@types/src/esbuild-plugins/rewrite-asset-imports.d.ts +2 -1
  4. package/@types/src/forms/controls/autocomplete.d.ts +2 -1
  5. package/@types/src/forms/controls/checkbox-group.d.ts +1 -2
  6. package/@types/src/forms/controls/collapsible-field-group.d.ts +2 -1
  7. package/@types/src/forms/controls/form-control.d.ts +1 -1
  8. package/@types/src/forms/controls/multiple-files.d.ts +3 -3
  9. package/@types/src/forms/controls/photo.d.ts +1 -1
  10. package/@types/src/forms/controls/simple-input.d.ts +1 -1
  11. package/@types/src/forms/controls/textarea.d.ts +1 -1
  12. package/@types/src/forms/controls/tickable.d.ts +2 -2
  13. package/@types/src/forms/fields/field.d.ts +2 -2
  14. package/@types/src/forms/fields/file.d.ts +1 -1
  15. package/@types/src/forms/fields/structured-array.d.ts +1 -1
  16. package/@types/src/forms/form.d.ts +1 -1
  17. package/@types/src/mount.d.ts +2 -1
  18. package/@types/src/page/sealious-list.d.ts +1 -1
  19. package/@types/src/page/stateful-page.d.ts +3 -3
  20. package/@types/src/utils/translate.d.ts +1 -1
  21. package/lib/add-route.test.js +1 -1
  22. package/lib/forms/controls/multiple-files.js +5 -3
  23. package/lib/forms/controls/photo.js +2 -1
  24. package/lib/page/stateful-page.js +4 -2
  25. package/lib/templates/jdd-component.js +0 -1
  26. package/lib/templates/page.js +1 -1
  27. package/lib/templates/route-test.js +5 -7
  28. package/package.json +3 -1
  29. package/src/add-route.test.ts +1 -1
  30. package/src/forms/controls/multiple-files.ts +5 -3
  31. package/src/forms/controls/photo.ts +1 -0
  32. package/src/page/stateful-page.ts +6 -2
  33. package/src/templates/jdd-component.ts +0 -1
  34. package/src/templates/page.ts +1 -1
  35. package/src/templates/route-test.ts +5 -7
@@ -4,7 +4,6 @@ export declare abstract class Builder {
4
4
  abstract getName(): string;
5
5
  abstract _build(): Promise<void>;
6
6
  abstract dispose(): Promise<void>;
7
- constructor();
8
7
  ongoing_build: Promise<void> | null;
9
8
  build(notifier?: (message: string) => void): Promise<void>;
10
9
  }
@@ -1,4 +1,5 @@
1
+ import { PluginBuild } from "esbuild";
1
2
  export declare const load_assets_plugin: {
2
3
  name: string;
3
- setup(build: any): void;
4
+ setup(build: PluginBuild): void;
4
5
  };
@@ -1,4 +1,5 @@
1
+ import { PluginBuild } from "esbuild";
1
2
  export declare const rewrite_asset_imports_plugin: {
2
3
  name: string;
3
- setup(build: any): void;
4
+ setup(build: PluginBuild): void;
4
5
  };
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" resolution-mode="require"/>
1
2
  import { Context } from "koa";
2
3
  import { PickFromListField } from "../fields/pick-from-list.js";
3
4
  import { FormControlContext } from "./form-control.js";
@@ -18,5 +19,5 @@ export declare class Autocomplete extends SimpleInput<string | null> {
18
19
  getInputAttributes(fctx: FormControlContext): Promise<{
19
20
  list: string;
20
21
  }>;
21
- postInput(ctx: Context): Promise<string>;
22
+ postInput(ctx: Context): Promise<import("stream").Readable>;
22
23
  }
@@ -1,6 +1,5 @@
1
1
  import { FlatTemplatable } from "tempstream";
2
2
  import { EnumMultipleField } from "../fields/enum-multiple.js";
3
- import { FormField } from "../fields/field.js";
4
3
  import { CheckboxWithValue } from "./checkbox.js";
5
4
  import { FormControlContext } from "./form-control.js";
6
5
  import { FormFieldControl } from "./form-field-control.js";
@@ -18,5 +17,5 @@ export declare class CheckboxGroup<Options extends DefaultCheckboxOptions = Defa
18
17
  options: Options;
19
18
  constructor(field: EnumMultipleField<readonly string[], boolean>, options?: Options);
20
19
  wrapGroup(fctx: FormControlContext, checkboxes: CheckboxWithValue[]): Promise<FlatTemplatable>;
21
- render<Fields extends Record<string, FormField>>(fctx: FormControlContext): Promise<FlatTemplatable>;
20
+ render(fctx: FormControlContext): Promise<FlatTemplatable>;
22
21
  }
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" resolution-mode="require"/>
1
2
  import { FlatTemplatable } from "tempstream";
2
3
  import { FieldGroup } from "./field-group.js";
3
4
  import { FormControl } from "./form-control.js";
@@ -14,7 +15,7 @@ export declare class CollapsibleFieldGroup extends FieldGroup {
14
15
  options: CollapsibleFieldGroupOptions;
15
16
  collapseID: string;
16
17
  constructor(controls: FormControl[], options?: CollapsibleFieldGroupOptions);
17
- getGroupLabelProps(): string;
18
+ getGroupLabelProps(): import("stream").Readable;
18
19
  preLabelContainer(): FlatTemplatable;
19
20
  postLabel(): FlatTemplatable;
20
21
  }
@@ -15,5 +15,5 @@ export declare class FormControlContext {
15
15
  export declare abstract class FormControl {
16
16
  abstract render(fctx: FormControlContext): FlatTemplatable | Promise<FlatTemplatable>;
17
17
  abstract role: "input" | "decoration" | "messages" | "submit";
18
- mount(router: Router): void;
18
+ mount(_router: Router): void;
19
19
  }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="koa__router" />
2
2
  /// <reference types="node" resolution-mode="require"/>
3
3
  import Router from "@koa/router";
4
- import { CollectionItem, Field as SealiousField } from "sealious";
4
+ import { Collection, CollectionItem, Field as SealiousField } from "sealious";
5
5
  import { Context } from "koa";
6
6
  import { FlatTemplatable } from "tempstream";
7
7
  import { MultipleFiles as MultipleFilesField } from "../fields/multiple-files.js";
@@ -25,9 +25,9 @@ export declare class MultipleFiles extends FormFieldControl {
25
25
  getFrameID(): string;
26
26
  renderFrame(_ctx: Context, content?: FlatTemplatable): import("stream").Readable;
27
27
  render(fctx: FormControlContext): FlatTemplatable | Promise<FlatTemplatable>;
28
- getReferencingCollection(): import("sealious").Collection;
28
+ getReferencingCollection(): Collection;
29
29
  getFileField(): SealiousField | null;
30
- extractFileFromItem(item: CollectionItem): Promise<FilePointer | null>;
30
+ extractFileFromItem(item: CollectionItem<Collection>): Promise<FilePointer | null>;
31
31
  renderFileItemPreview(_fileItem: CollectionItem, file: FilePointer): Promise<FlatTemplatable>;
32
32
  renderFileItem(fileItem: CollectionItem, file: FilePointer): Promise<FlatTemplatable>;
33
33
  renderFileRemoveButton(fileItem: CollectionItem): FlatTemplatable;
@@ -12,7 +12,7 @@ export declare class Photo extends File {
12
12
  imageRouter: KoaResponsiveImageRouter;
13
13
  constructor(field: FormField<boolean, FileContainer>, imageRouter: KoaResponsiveImageRouter, options?: SimpleInputOptions);
14
14
  getImgStyle(): Promise<string>;
15
- renderFilePreview(ctx: Context, file: FilePointer | null): Promise<FlatTemplatable>;
15
+ renderFilePreview(_ctx: Context, file: FilePointer | null): Promise<FlatTemplatable>;
16
16
  getWrapperModifiers(): string[];
17
17
  getInputAttributes(fctx: FormControlContext): Promise<{
18
18
  accept: string;
@@ -29,5 +29,5 @@ export declare class SimpleInput<ParsedValue, Options extends SimpleInputOptions
29
29
  postInput(_: Context): Promise<FlatTemplatable>;
30
30
  renderInput(_ctx: Context, attributes_str: string, _data: Record<string, FormDataValue>): Promise<FlatTemplatable>;
31
31
  getWrapperModifiers(): string[];
32
- render<Fields extends Record<string, FormField>>(fctx: FormControlContext): Promise<FlatTemplatable>;
32
+ render(fctx: FormControlContext): Promise<FlatTemplatable>;
33
33
  }
@@ -3,7 +3,7 @@ import { FormField } from "../fields/field.js";
3
3
  import { FormDataValue } from "../form-types.js";
4
4
  import { FormControlContext } from "./form-control.js";
5
5
  import { SimpleInput, SimpleInputOptions } from "./simple-input.js";
6
- export declare class Textarea<Required extends boolean> extends SimpleInput<string | null> {
6
+ export declare class Textarea extends SimpleInput<string | null> {
7
7
  field: FormField<boolean, string | null>;
8
8
  options: SimpleInputOptions & {
9
9
  label?: string;
@@ -11,7 +11,7 @@ export type TickableOptions = {
11
11
  hide_errors?: boolean;
12
12
  readonly?: boolean;
13
13
  };
14
- export declare abstract class Tickable<T extends unknown> extends FormFieldControl {
14
+ export declare abstract class Tickable<T> extends FormFieldControl {
15
15
  field: FormField<boolean, T>;
16
16
  options: TickableOptions;
17
17
  constructor(field: FormField<boolean, T>, options?: TickableOptions);
@@ -20,5 +20,5 @@ export declare abstract class Tickable<T extends unknown> extends FormFieldContr
20
20
  abstract isChecked(ctx: Context, data: Record<string, FormDataValue>, value: T): boolean;
21
21
  makeInputID(ctx: Context, data: Record<string, FormDataValue>, value: T): string;
22
22
  getWrapperClasses(ctx: Context, data: Record<string, FormDataValue>, value: T): string[];
23
- render<Fields extends Record<string, FormField>>(fctx: FormControlContext): Promise<FlatTemplatable>;
23
+ render(fctx: FormControlContext): Promise<FlatTemplatable>;
24
24
  }
@@ -21,7 +21,7 @@ export type FieldParseResult<T> = {
21
21
  error: string;
22
22
  parsed_value: null;
23
23
  };
24
- export declare abstract class FormField<Required extends boolean = boolean, ParsedValue extends unknown = unknown> {
24
+ export declare abstract class FormField<Required extends boolean = boolean, ParsedValue = unknown> {
25
25
  readonly required: Required;
26
26
  name: string;
27
27
  constructor(required: Required);
@@ -30,7 +30,7 @@ export declare abstract class FormField<Required extends boolean = boolean, Pars
30
30
  init(fieldname: string): Promise<void>;
31
31
  _validate(ctx: Context, value: ParsedValue): Promise<FormFieldValidationResponse>;
32
32
  abstract getEmptyValue(): ParsedValue;
33
- isValueValid(ctx: Context, value: ParsedValue): Promise<FormFieldValidationResponse>;
33
+ isValueValid(_ctx: Context, _value: ParsedValue): Promise<FormFieldValidationResponse>;
34
34
  abstract parse(ctx: Context, raw_value: FormDataValue): Promise<FieldParseResult<ParsedValue>>;
35
35
  getValue(ctx: Context, all_form_values: Record<string, FormDataValue>): Promise<{
36
36
  valid: boolean;
@@ -10,7 +10,7 @@ export declare class File<Required extends boolean> extends FormField<Required,
10
10
  readonly required: Required;
11
11
  file_manager: FileManager;
12
12
  constructor(required: Required, file_manager: FileManager);
13
- parse(ctx: Context, raw_value: FormDataValue): Promise<FieldParseResult<FileContainer>>;
13
+ parse(_ctx: Context, raw_value: FormDataValue): Promise<FieldParseResult<FileContainer>>;
14
14
  getDatabaseValue(ctx: Context, data: Record<string, FormDataValue>): Promise<FilePointer | undefined>;
15
15
  getEmptyValue(): {
16
16
  old: null;
@@ -5,7 +5,7 @@ import { FormField } from "./field.js";
5
5
  export declare class StructuredArrayField<Fields extends Record<string, Field>> extends FormField<true, FieldTypes.ArrayStorageInput<FieldsetOutput<Fields>>> {
6
6
  sealious_field: FieldTypes.StructuredArray<Fields>;
7
7
  constructor(sealious_field: FieldTypes.StructuredArray<Fields>);
8
- parse(context: Context, value: FormDataValue): Promise<{
8
+ parse(_context: Context, value: FormDataValue): Promise<{
9
9
  parsable: true;
10
10
  error: null;
11
11
  parsed_value: FieldsetOutput<Fields>;
@@ -4,7 +4,7 @@ import Router from "@koa/router";
4
4
  import { FlatTemplatable } from "tempstream";
5
5
  import { FormData, FormDataValue, FormMessage, FormReaction } from "./form-types.js";
6
6
  import { Fields, MountableWithFields, PageErrorMessage } from "../page/mountable-with-fields.js";
7
- export declare abstract class Form<F extends Fields, SubmitResult extends any> extends MountableWithFields<F> {
7
+ export declare abstract class Form<F extends Fields, SubmitResult> extends MountableWithFields<F> {
8
8
  defaultSuccessMessage: string;
9
9
  submitButtonText: string;
10
10
  action: string;
@@ -1,6 +1,7 @@
1
1
  /// <reference types="koa__router" />
2
2
  import Router from "@koa/router";
3
+ import { FileManager } from "@sealcode/file-manager";
3
4
  import { Mountable } from "./page/mountable.js";
4
5
  export declare function mount(router: Router, url: string | {
5
6
  rawURL: string;
6
- }, mountable: Mountable, use_dummy_app?: boolean): void;
7
+ }, mountable: Mountable, use_dummy_app?: boolean, file_manager?: FileManager | undefined): void;
@@ -11,7 +11,7 @@ export declare abstract class SealiousItemListPage<C extends Collection, F exten
11
11
  makeQuery(ctx: Context): Promise<ItemList<C>>;
12
12
  getItems(ctx: Context, page: number, itemsPerPage: number): Promise<CollectionItem<C>[]>;
13
13
  getFilterValues(ctx: Context): Promise<Record<string, string | undefined>>;
14
- renderItem(_: Context, item: CollectionItem<C>, index: number): Promise<FlatTemplatable>;
14
+ renderItem(_: Context, item: CollectionItem<C>, _index: number): Promise<FlatTemplatable>;
15
15
  canAccess: (ctx: Context) => Promise<{
16
16
  canAccess: boolean;
17
17
  message: string;
@@ -21,9 +21,9 @@ export type StateAndMetadata<State, Actions> = {
21
21
  action_args: null;
22
22
  $: Record<string, unknown>;
23
23
  };
24
- export declare abstract class StatefulPage<State extends Record<string, unknown>, Actions extends Record<string, (state: State, inputs: Record<string, string>, ...args: unknown[]) => State | Promise<State>>> extends Mountable {
24
+ export declare abstract class StatefulPage<State extends Record<string, unknown>, Actions extends Record<string, (ctx: BaseContext, state: State, inputs: Record<string, string>, ...args: unknown[]) => State | Promise<State>>> extends Mountable {
25
25
  abstract actions: Actions;
26
- abstract getInitialState(): State | Promise<State>;
26
+ abstract getInitialState(ctx: BaseContext): State | Promise<State>;
27
27
  abstract render(ctx: BaseContext, state: State, inputs: Record<string, string>): Templatable | Promise<Templatable>;
28
28
  canAccess(): Promise<{
29
29
  readonly canAccess: true;
@@ -45,7 +45,7 @@ export declare abstract class StatefulPage<State extends Record<string, unknown>
45
45
  } | ActionName, ...args: ExtractTail<ExtractTail<Parameters<Actions[ActionName]>>>): string;
46
46
  rerender(): string;
47
47
  preprocessState(values: State): Promise<State>;
48
- preprocessOverrides(state: State, values: Record<string, unknown>): Promise<Record<string, unknown>>;
48
+ preprocessOverrides(_context: BaseContext, _state: State, values: Record<string, unknown>): Promise<Record<string, unknown>>;
49
49
  serializeState(_context: BaseContext, state: State): Promise<string>;
50
50
  deserializeState(_context: BaseContext, s: string): Promise<State>;
51
51
  extractState(ctx: BaseContext): Promise<StateAndMetadata<State, Actions>>;
@@ -1,3 +1,3 @@
1
1
  import { Context } from "koa";
2
2
  import { Translation } from "sealious";
3
- export declare function t(ctx: Context, key: string, props: any[], default_translation: Translation): string;
3
+ export declare function t(ctx: Context, key: string, props: unknown[], default_translation: Translation): string;
@@ -93,6 +93,6 @@ describe("add route test", () => {
93
93
  if (res.status != 200) {
94
94
  throw new Error("url generated by add-route exists but doesnt return 200");
95
95
  }
96
- });
96
+ }).timeout(100 * 1e3);
97
97
  });
98
98
  //# sourceMappingURL=add-route.test.js.map
@@ -102,9 +102,11 @@ class MultipleFiles extends FormFieldControl {
102
102
  if (!sealious_field) {
103
103
  return null;
104
104
  }
105
- return await item.collection.app.FileManager.fromToken(
106
- item.get(sealious_field.name).token
107
- );
105
+ const token = item.get(sealious_field.name).token;
106
+ if (!token) {
107
+ return null;
108
+ }
109
+ return await item.collection.app.FileManager.fromToken(token);
108
110
  }
109
111
  async renderFileItemPreview(_fileItem, file) {
110
112
  return file.getOriginalFilename();
@@ -19,7 +19,8 @@ class Photo extends File {
19
19
  ${this.imageRouter.image(await file.getPath(), {
20
20
  resolutions: [100],
21
21
  sizesAttr: "100px",
22
- imgStyle: await this.getImgStyle()
22
+ imgStyle: await this.getImgStyle(),
23
+ alt: "Image preview"
23
24
  })}
24
25
  </div>`;
25
26
  }
@@ -84,7 +84,7 @@ class StatefulPage extends Mountable {
84
84
  async preprocessState(values) {
85
85
  return values;
86
86
  }
87
- async preprocessOverrides(_state, values) {
87
+ async preprocessOverrides(_context, _state, values) {
88
88
  return values;
89
89
  }
90
90
  async serializeState(_context, state) {
@@ -123,6 +123,7 @@ class StatefulPage extends Mountable {
123
123
  const $body = ctx.$body;
124
124
  let state_overrides = $body.$ || {};
125
125
  state_overrides = await this.preprocessOverrides(
126
+ ctx,
126
127
  original_state,
127
128
  state_overrides
128
129
  );
@@ -169,12 +170,13 @@ class StatefulPage extends Mountable {
169
170
  }
170
171
  mount(router, path) {
171
172
  router.get(path, async (ctx) => {
172
- ctx.body = this.render(ctx, await this.getInitialState(), {});
173
+ ctx.body = this.render(ctx, await this.getInitialState(ctx), {});
173
174
  });
174
175
  router.post(path, async (ctx) => {
175
176
  const { action, state, inputs, action_args } = await this.extractState(ctx);
176
177
  if (action) {
177
178
  const new_state = await this.actions[action](
179
+ ctx,
178
180
  state,
179
181
  inputs,
180
182
  ...JSON.parse(
@@ -35,7 +35,6 @@ export class ${toPascalCase(
35
35
  );
36
36
  }
37
37
  }
38
-
39
38
  `;
40
39
  }
41
40
  export {
@@ -1,7 +1,7 @@
1
1
  import { curryImportPath } from "../utils/import-path.js";
2
2
  async function pageTemplate(action_name, newfilefullpath) {
3
3
  const rel = curryImportPath(newfilefullpath);
4
- return `import { Context } from "koa";
4
+ return `import type { Context } from "koa";
5
5
  import { TempstreamJSX } from "tempstream";
6
6
  import { Page } from "@sealcode/sealgen";
7
7
  import html from "${rel("src/back/html.js")}";
@@ -9,7 +9,7 @@ import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "${rel(
9
9
  )}";
10
10
  import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
11
11
  import { getBrowser } from "${rel("src/back/test_utils/browser-creator.js")}";
12
- import { Browser, BrowserContext, Page } from "@playwright/test";
12
+ import type { Browser, BrowserContext, Page } from "@playwright/test";
13
13
 
14
14
  describe("${action_name} webhint", () => {
15
15
  it(
@@ -23,9 +23,8 @@ describe("${action_name} webhint", () => {
23
23
  // const response = await rest_api.get(${action_name}URL);
24
24
  // await webhintHTML(response);
25
25
  });
26
- },
27
- VERY_LONG_TEST_TIMEOUT
28
- );
26
+ }
27
+ ).timeout(VERY_LONG_TEST_TIMEOUT);
29
28
  });
30
29
 
31
30
  describe("${action_name}", () => {
@@ -49,9 +48,8 @@ describe("${action_name}", () => {
49
48
  return withProdApp(async ({ base_url }) => {
50
49
  await page.goto(base_url + ${action_name}URL);
51
50
  });
52
- },
53
- VERY_LONG_TEST_TIMEOUT
54
- );
51
+ }
52
+ ).timeout(VERY_LONG_TEST_TIMEOUT);
55
53
  });
56
54
  `;
57
55
  }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.15.5",
3
+ "version": "0.15.7",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "prebuild": "npm run lint && rm -rf lib",
9
9
  "build": "node ./build.js",
10
+ "postbuild": "npm run build-types",
10
11
  "pretest": "npm run build",
11
12
  "test": "node test.cjs",
12
13
  "typecheck": "tsc --noemit",
14
+ "build-types": "tsc --emitDeclarationOnly",
13
15
  "prepare": "npm run build",
14
16
  "lint": "eslint src",
15
17
  "preinstrument": "npm run build && rm -fr .xunit coverage lib-instrumented",
@@ -102,5 +102,5 @@ describe("add route test", () => {
102
102
  if (res.status != 200) {
103
103
  throw new Error("url generated by add-route exists but doesnt return 200");
104
104
  }
105
- });
105
+ }).timeout(100 * 1000);
106
106
  });
@@ -146,9 +146,11 @@ export class MultipleFiles extends FormFieldControl {
146
146
  if (!sealious_field) {
147
147
  return null;
148
148
  }
149
- return await item.collection.app.FileManager.fromToken(
150
- (item.get(sealious_field.name) as FilePointer).token
151
- );
149
+ const token = (item.get(sealious_field.name) as FilePointer).token;
150
+ if (!token) {
151
+ return null;
152
+ }
153
+ return await item.collection.app.FileManager.fromToken(token);
152
154
  }
153
155
 
154
156
  async renderFileItemPreview(
@@ -35,6 +35,7 @@ export class Photo extends File {
35
35
  resolutions: [100],
36
36
  sizesAttr: "100px",
37
37
  imgStyle: await this.getImgStyle(),
38
+ alt: "Image preview",
38
39
  })}
39
40
  </div>`;
40
41
  }
@@ -37,6 +37,7 @@ export abstract class StatefulPage<
37
37
  Actions extends Record<
38
38
  string,
39
39
  (
40
+ ctx: BaseContext,
40
41
  state: State,
41
42
  inputs: Record<string, string>,
42
43
  ...args: unknown[]
@@ -44,7 +45,7 @@ export abstract class StatefulPage<
44
45
  >
45
46
  > extends Mountable {
46
47
  abstract actions: Actions;
47
- abstract getInitialState(): State | Promise<State>;
48
+ abstract getInitialState(ctx: BaseContext): State | Promise<State>;
48
49
  abstract render(
49
50
  ctx: BaseContext,
50
51
  state: State,
@@ -169,6 +170,7 @@ export abstract class StatefulPage<
169
170
  }
170
171
 
171
172
  async preprocessOverrides(
173
+ _context: BaseContext,
172
174
  _state: State,
173
175
  values: Record<string, unknown>
174
176
  ): Promise<Record<string, unknown>> {
@@ -223,6 +225,7 @@ export abstract class StatefulPage<
223
225
  const $body = ctx.$body;
224
226
  let state_overrides = $body.$ || {};
225
227
  state_overrides = await this.preprocessOverrides(
228
+ ctx,
226
229
  original_state,
227
230
  state_overrides
228
231
  );
@@ -283,7 +286,7 @@ export abstract class StatefulPage<
283
286
 
284
287
  mount(router: Router, path: string) {
285
288
  router.get(path, async (ctx) => {
286
- ctx.body = this.render(ctx, await this.getInitialState(), {});
289
+ ctx.body = this.render(ctx, await this.getInitialState(ctx), {});
287
290
  });
288
291
 
289
292
  router.post(path, async (ctx) => {
@@ -291,6 +294,7 @@ export abstract class StatefulPage<
291
294
  await this.extractState(ctx);
292
295
  if (action) {
293
296
  const new_state = await this.actions[action](
297
+ ctx,
294
298
  state,
295
299
  inputs,
296
300
  ...(JSON.parse(
@@ -36,6 +36,5 @@ export class ${toPascalCase(
36
36
  );
37
37
  }
38
38
  }
39
-
40
39
  `;
41
40
  }
@@ -4,7 +4,7 @@ export async function pageTemplate(
4
4
  newfilefullpath: string
5
5
  ): Promise<string> {
6
6
  const rel = curryImportPath(newfilefullpath);
7
- return `import { Context } from "koa";
7
+ return `import type { Context } from "koa";
8
8
  import { TempstreamJSX } from "tempstream";
9
9
  import { Page } from "@sealcode/sealgen";
10
10
  import html from "${rel("src/back/html.js")}";
@@ -10,7 +10,7 @@ import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "${rel(
10
10
  )}";
11
11
  import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
12
12
  import { getBrowser } from "${rel("src/back/test_utils/browser-creator.js")}";
13
- import { Browser, BrowserContext, Page } from "@playwright/test";
13
+ import type { Browser, BrowserContext, Page } from "@playwright/test";
14
14
 
15
15
  describe("${action_name} webhint", () => {
16
16
  it(
@@ -24,9 +24,8 @@ describe("${action_name} webhint", () => {
24
24
  // const response = await rest_api.get(${action_name}URL);
25
25
  // await webhintHTML(response);
26
26
  });
27
- },
28
- VERY_LONG_TEST_TIMEOUT
29
- );
27
+ }
28
+ ).timeout(VERY_LONG_TEST_TIMEOUT);
30
29
  });
31
30
 
32
31
  describe("${action_name}", () => {
@@ -50,9 +49,8 @@ describe("${action_name}", () => {
50
49
  return withProdApp(async ({ base_url }) => {
51
50
  await page.goto(base_url + ${action_name}URL);
52
51
  });
53
- },
54
- VERY_LONG_TEST_TIMEOUT
55
- );
52
+ }
53
+ ).timeout(VERY_LONG_TEST_TIMEOUT);
56
54
  });
57
55
  `;
58
56
  }