@sealcode/sealgen 0.15.8 → 0.15.11

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/.xunit CHANGED
@@ -1,53 +1,55 @@
1
- <testsuite name="Mocha Tests" tests="51" failures="0" errors="0" skipped="0" timestamp="Mon, 29 Apr 2024 11:24:39 GMT" time="19.296">
2
- <testcase classname="add route test" name="creates minimal sealious app" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/add-route.test.js" time="7.334"/>
1
+ <testsuite name="Mocha Tests" tests="53" failures="0" errors="0" skipped="0" timestamp="Thu, 02 May 2024 10:22:17 GMT" time="21.049">
2
+ <testcase classname="add route test" name="creates minimal sealious app" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/add-route.test.js" time="8.525"/>
3
3
  <testcase classname="empty test" name="empty test" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/example.test.js" time="0"/>
4
- <testcase classname="checkboxed-list basic tests" name="sends the values" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/checkboxed-list-input.test.js" time="1.12"/>
5
- <testcase classname="photo-control basic tests" name="sends the old photo if it wasn&#x27;t changed and it has an initial value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/photo.test.js" time="0.248"/>
4
+ <testcase classname="checkboxed-list basic tests" name="sends the values" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/checkboxed-list-input.test.js" time="1.68"/>
5
+ <testcase classname="photo-control basic tests" name="sends the old photo if it wasn&#x27;t changed and it has an initial value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/photo.test.js" time="0.319"/>
6
6
  <testcase classname="boolean field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/boolean.test.js" time="0.001"/>
7
7
  <testcase classname="boolean field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/boolean.test.js" time="0"/>
8
8
  <testcase classname="email field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/email.test.js" time="0.001"/>
9
9
  <testcase classname="email field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/email.test.js" time="0"/>
10
- <testcase classname="enum-multiple field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum-multiple.test.js" time="0.001"/>
10
+ <testcase classname="enum-multiple field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum-multiple.test.js" time="0"/>
11
11
  <testcase classname="enum-multiple field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum-multiple.test.js" time="0"/>
12
12
  <testcase classname="enum field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum.test.js" time="0"/>
13
- <testcase classname="enum field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum.test.js" time="0"/>
13
+ <testcase classname="enum field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum.test.js" time="0.001"/>
14
+ <testcase classname="file field" name="should handle as imple upload scenario" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/file.test.js" time="0.355"/>
14
15
  <testcase classname="number field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/number.test.js" time="0.001"/>
15
16
  <testcase classname="number field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/number.test.js" time="0"/>
16
17
  <testcase classname="pick-from-list field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/pick-from-list.test.js" time="0"/>
17
18
  <testcase classname="regexp field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/regexp.test.js" time="0"/>
18
- <testcase classname="regexp field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/regexp.test.js" time="0"/>
19
- <testcase classname="form test basic tests" name="does not allow to submit an empty form when there&#x27;s a required field" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.573"/>
20
- <testcase classname="form test basic tests" name="allows to submit a form when all required fields have a value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.194"/>
21
- <testcase classname="form test basic tests" name="does not allow submitting an empty form by circumventing HTML-based validation" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.014"/>
19
+ <testcase classname="regexp field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/regexp.test.js" time="0.001"/>
20
+ <testcase classname="form test basic tests" name="does not allow to submit an empty form when there&#x27;s a required field" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.589"/>
21
+ <testcase classname="form test basic tests" name="allows to submit a form when all required fields have a value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.19"/>
22
+ <testcase classname="form test basic tests" name="does not allow submitting an empty form by circumventing HTML-based validation" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.012"/>
22
23
  <testcase classname="form test canAccess tests" name="allows visit when configured when canAccess returns true" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.011"/>
23
- <testcase classname="form test canAccess tests" name="passes the context to canAccess (false case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.013"/>
24
- <testcase classname="form test canAccess tests" name="passes the context to canAccess (true case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.011"/>
25
- <testcase classname="form test canAccess tests declines access when canAccess returns false" name="prevents the form from rendering" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.007"/>
26
- <testcase classname="form test canAccess tests declines access when canAccess returns false" name="does not allow submitting of the form through axios" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.002"/>
27
- <testcase classname="form test validation e2e validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.221"/>
28
- <testcase classname="form test validation e2e validation message" name="doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.627"/>
29
- <testcase classname="form test validation e2e field specific validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.197"/>
30
- <testcase classname="form test validation e2e field specific validation message" name="doesn&#x27;t show up when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.151"/>
31
- <testcase classname="form test getInitialValues tests" name="fills the form with values from getInitialValues" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.035"/>
32
- <testcase classname="multiform test basic tests turbolinks + js enabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.561"/>
24
+ <testcase classname="form test canAccess tests" name="passes the context to canAccess (false case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.012"/>
25
+ <testcase classname="form test canAccess tests" name="passes the context to canAccess (true case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.016"/>
26
+ <testcase classname="form test canAccess tests declines access when canAccess returns false" name="prevents the form from rendering" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.008"/>
27
+ <testcase classname="form test canAccess tests declines access when canAccess returns false" name="does not allow submitting of the form through axios" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.003"/>
28
+ <testcase classname="form test validation e2e validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.22"/>
29
+ <testcase classname="form test validation e2e validation message" name="doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.621"/>
30
+ <testcase classname="form test validation e2e field specific validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.217"/>
31
+ <testcase classname="form test validation e2e field specific validation message" name="doesn&#x27;t show up when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.137"/>
32
+ <testcase classname="form test getInitialValues tests" name="fills the form with values from getInitialValues" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.033"/>
33
+ <testcase classname="multiform test basic tests turbolinks + js enabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.557"/>
33
34
  <testcase classname="multiform test basic tests turbolinks + js enabled" name="checking whether the input in the not submitted form prevails" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
34
- <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.572"/>
35
- <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether the input in the not submitted form prevails" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
36
- <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether it renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.436"/>
37
- <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether you can submit through http (axios)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.005"/>
38
- <testcase classname="multiform test canAccess deny access to both forms" name="check wether forms didnt render" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.642"/>
39
- <testcase classname="multiform test canAccess deny access to both forms" name="check wether it&#x27;s possible to submit through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.004"/>
40
- <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether form1 renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.359"/>
35
+ <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.564"/>
36
+ <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether the input in the not submitted form prevails" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.009"/>
37
+ <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether it renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.381"/>
38
+ <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether you can submit through http (axios)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.008"/>
39
+ <testcase classname="multiform test canAccess deny access to both forms" name="check wether forms didnt render" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.58"/>
40
+ <testcase classname="multiform test canAccess deny access to both forms" name="check wether it&#x27;s possible to submit through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.005"/>
41
+ <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether form1 renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.495"/>
41
42
  <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether it&#x27;s possible to submit to form1 through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
42
43
  <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether form2 does not render" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.323"/>
43
44
  <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether it&#x27;s possible to submit to form2 through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
44
- <testcase classname="multiform test validation e2e basic tests" name="js enabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="1.12"/>
45
- <testcase classname="multiform test validation e2e basic tests" name="js disabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.859"/>
46
- <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.213"/>
47
- <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.137"/>
48
- <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.239"/>
49
- <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.212"/>
50
- <testcase classname="generate routes" name="handles a url with params" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.127"/>
45
+ <testcase classname="multiform test validation e2e basic tests" name="js enabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="1.118"/>
46
+ <testcase classname="multiform test validation e2e basic tests" name="js disabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.862"/>
47
+ <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.205"/>
48
+ <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.106"/>
49
+ <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.194"/>
50
+ <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.138"/>
51
+ <testcase classname="generate routes" name="handles a url with params" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.132"/>
51
52
  <testcase classname="generate routes" name="handles polish characters in the url" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0"/>
52
- <testcase classname="generate routes" name="handles a url with params and diacritics" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.007"/>
53
+ <testcase classname="generate routes" name="handles a url with params and diacritics" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.006"/>
54
+ <testcase classname="stateful page" name="handles a basic case with action buttons" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/page/stateful-page.test.js" time="0"/>
53
55
  </testsuite>
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- export declare function testTemplate(action_name: string, new_file_fullpath: string): string;
1
+ export declare function testTemplate(action_name: string, new_file_fullpath: string): Promise<string>;
@@ -1,2 +1,3 @@
1
1
  import { Options } from "prettier";
2
- export declare function getPrettierConfig(): Promise<Options>;
2
+ export declare function getPrettierConfig(parser?: string): Promise<Options>;
3
+ export declare function formatWithPrettier(content: string, lang?: string): Promise<string>;
package/lib/add-route.js CHANGED
@@ -64,7 +64,10 @@ async function addRoute(params, app_directory = process.cwd()) {
64
64
  await fs.mkdir(resolve(file_path, "../"), { recursive: true });
65
65
  await fs.writeFile(file_path, await template(action, file_path));
66
66
  if (mode !== "lpr") {
67
- await fs.writeFile(test_file_path, testTemplate(action, file_path));
67
+ await fs.writeFile(
68
+ test_file_path,
69
+ await testTemplate(action, file_path)
70
+ );
68
71
  }
69
72
  console.log(`${file_path} created`);
70
73
  console.log(`${test_file_path} created`);
@@ -25,7 +25,7 @@ const execAsync = (cmd) => {
25
25
  });
26
26
  });
27
27
  };
28
- const callSealgenBin = () => `node ${locreq.resolve("dist/cli.js")}`;
28
+ const callSealgenBin = () => `node ${locreq.resolve("lib/cli.js")}`;
29
29
  describe("add route test", () => {
30
30
  let node_pid = 0;
31
31
  const timestamp = Date.now();
@@ -46,11 +46,11 @@ describe("add route test", () => {
46
46
  it("creates minimal sealious app", async function() {
47
47
  console.log(" cloning sealious-minimal...");
48
48
  await execAsync(
49
- `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout 5b33aac`
49
+ `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout df8cccf`
50
50
  );
51
51
  console.log(" installing dependencies and sealgen...");
52
52
  await execAsync(
53
- `cd ${app_path} && npm ci && rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen`
53
+ `cd ${app_path} && npm ci rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen && ${callSealgenBin()} make-env`
54
54
  );
55
55
  console.log(" running add-route and building app...");
56
56
  await execAsync(
@@ -1,5 +1,7 @@
1
1
  import { hasFieldOfType, is, predicates } from "@sealcode/ts-predicates";
2
- import { FilePointer } from "@sealcode/file-manager";
2
+ import {
3
+ PathFilePointer
4
+ } from "@sealcode/file-manager";
3
5
  import { FormField } from "./field.js";
4
6
  class File extends FormField {
5
7
  constructor(required, file_manager) {
@@ -26,15 +28,18 @@ class File extends FormField {
26
28
  const old_file = hasFieldOfType(
27
29
  raw_value,
28
30
  "old",
29
- predicates.or(predicates.string, predicates.object)
31
+ predicates.instanceOf(PathFilePointer)
30
32
  ) ? await this.file_manager.toPointer(
31
33
  raw_value.old
32
34
  ) : null;
33
35
  const new_file = hasFieldOfType(
34
36
  raw_value,
35
37
  "new",
36
- predicates.array(predicates.object)
37
- ) && raw_value.new[0] instanceof FilePointer ? raw_value.new[0] : null;
38
+ predicates.or(
39
+ predicates.array(predicates.instanceOf(PathFilePointer)),
40
+ predicates.instanceOf(PathFilePointer)
41
+ )
42
+ ) ? Array.isArray(raw_value.new) ? raw_value.new[0] : raw_value.new : null;
38
43
  result = {
39
44
  parsable: true,
40
45
  error: null,
@@ -0,0 +1,77 @@
1
+ import Router from "@koa/router";
2
+ import { FileManager, FilePointer } from "@sealcode/file-manager";
3
+ import getPort from "get-port";
4
+ import Koa from "koa";
5
+ import fs from "node:fs/promises";
6
+ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
7
+ import { mount } from "../../mount.js";
8
+ import { Photo } from "../controls/photo.js";
9
+ import { Form } from "../form.js";
10
+ import { File as FileField } from "./file.js";
11
+ import { getBrowser } from "../../utils/browser-creator.js";
12
+ import assert from "node:assert";
13
+ import { module_dirname } from "../../utils/module-dirname.js";
14
+ import _locreq from "locreq";
15
+ const locreq = _locreq(module_dirname(import.meta.url));
16
+ describe("file field", () => {
17
+ let server;
18
+ let browser;
19
+ let page;
20
+ afterEach(() => {
21
+ server.close();
22
+ });
23
+ it("should handle as imple upload scenario", async () => {
24
+ const port = await getPort();
25
+ console.log(`Using port http://localhost:${port} form file field test`);
26
+ const app = new Koa();
27
+ const router = new Router();
28
+ const fields = {
29
+ file: new FileField(true, new FileManager("/tmp", "/uploaded_files"))
30
+ };
31
+ let received_values;
32
+ mount(
33
+ router,
34
+ "/",
35
+ new class extends Form {
36
+ constructor() {
37
+ super(...arguments);
38
+ this.fields = fields;
39
+ this.controls = [
40
+ new Photo(
41
+ fields.file,
42
+ new KoaResponsiveImageRouter({
43
+ staticPath: "/tmp",
44
+ thumbnailSize: 10,
45
+ cacheManagerResolutionThreshold: 10,
46
+ imageStoragePath: "/tmp",
47
+ smartCropStoragePath: "/tmp"
48
+ })
49
+ )
50
+ ];
51
+ }
52
+ async onSubmit(ctx) {
53
+ received_values = await this.getParsedValues(ctx);
54
+ }
55
+ async canAccess(_) {
56
+ return { canAccess: true, message: "" };
57
+ }
58
+ }(),
59
+ true
60
+ );
61
+ app.use(router.routes()).use(router.allowedMethods());
62
+ server = app.listen(port);
63
+ browser = await getBrowser();
64
+ const context = await browser.newContext();
65
+ page = await context.newPage();
66
+ await page.goto(`http://localhost:${port}`);
67
+ await page.getByPlaceholder("file").setInputFiles({
68
+ name: "important.png",
69
+ mimeType: "image/png",
70
+ buffer: await fs.readFile(locreq.resolve("assets/important.png"))
71
+ });
72
+ await page.getByRole("button", { name: "Wy\u015Blij" }).click();
73
+ assert.ok(received_values.file.old == null);
74
+ assert.ok(received_values.file.new instanceof FilePointer);
75
+ }).timeout(999999);
76
+ });
77
+ //# sourceMappingURL=file.test.js.map
@@ -1,7 +1,9 @@
1
+ import Prettier from "prettier";
1
2
  import { curryImportPath } from "../utils/import-path.js";
3
+ import { getPrettierConfig } from "../utils/prettier.js";
2
4
  async function formTemplate(action_name, newfilefullpath) {
3
5
  const rel = curryImportPath(newfilefullpath);
4
- return `import type { Context } from "koa";
6
+ const content = `import type { Context } from "koa";
5
7
  import type { FormData, FormDataValue } from "@sealcode/sealgen";
6
8
  import { Form, Fields, Controls, fieldsToShape } from "@sealcode/sealgen";
7
9
  import html from "${rel("src/back/html.js")}";
@@ -35,6 +37,7 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
35
37
  // just a silly example, please remove this with better logic
36
38
  const { parsed: email } = await this.fields.email.getValue(ctx, data);
37
39
  const { parsed: password } = await this.fields.password.getValue(ctx, data);
40
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
38
41
  if ((password || "").length > ((email as string) || "").length) {
39
42
  return { valid: false, error: "Password cannot be longer than email" };
40
43
  } else {
@@ -57,6 +60,7 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
57
60
  }
58
61
  })();
59
62
  `;
63
+ return Prettier.format(content, await getPrettierConfig());
60
64
  }
61
65
  export {
62
66
  formTemplate
@@ -1,10 +1,10 @@
1
1
  import _locreq from "locreq";
2
- import { curryImportPath } from "../utils/import-path.js";
3
2
  import prompts from "prompts";
4
3
  import { listCollections } from "../utils/list-collections.js";
5
4
  import { extractCollectionClassname } from "../generate-collections.js";
6
5
  import extract_fields_from_collection from "../utils/extract-fields-from-collection.js";
7
6
  import { DefaultListFilters } from "../page/default-list-filters.js";
7
+ import { formatWithPrettier } from "../utils/prettier.js";
8
8
  const target_locreq = _locreq(process.cwd());
9
9
  const listTemplate = async (action_name, newfilefullpath) => {
10
10
  const response = await prompts({
@@ -25,25 +25,23 @@ const listTemplate = async (action_name, newfilefullpath) => {
25
25
  ),
26
26
  extract_fields_from_collection(collection_name)
27
27
  ]);
28
- const rel = curryImportPath(newfilefullpath);
29
- return `import { Context } from "koa";
30
- import { CollectionItem } from "sealious";
31
- import { FlatTemplatable, TempstreamJSX } from "tempstream";
32
- import { ${uppercase_collection} } from "${rel(
33
- "src/back/collections/collections.js"
34
- )}";
35
- import html from "${rel("src/back/html.js")}";
28
+ const result = `import type { Context } from "koa";
29
+ import type { CollectionItem } from "sealious";
30
+ import type { FlatTemplatable } from "tempstream";
31
+ import { TempstreamJSX } from "tempstream";
32
+ import { Photos } from "../collections/collections.js";
33
+ import html from "../html.js";
34
+ import type { ListFilterRender } from "@sealcode/sealgen";
36
35
  import {
37
36
  SealiousItemListPage,
38
37
  BaseListPageFields,
39
38
  DefaultListFilters,
40
- ListFilterRender,
41
- } from "@sealcode/sealgen";;
39
+ } from "@sealcode/sealgen";
42
40
  import qs from "qs";
43
- import { is, predicates } from "@sealcode/ts-predicates";
44
41
 
45
42
  export const actionName = "${action_name}";
46
43
 
44
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
47
45
  const filterFields = [
48
46
  ${collection_fields.map(
49
47
  (field) => ` { field: "${field.name}", render: ${DefaultListFilters[field.type] ? `DefaultListFilters["${field.type}"]` : `DefaultListFilters.fallback`} }`
@@ -119,6 +117,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
119
117
  async renderItem(_: Context, item: CollectionItem<typeof ${uppercase_collection}>) {
120
118
  return <tr>
121
119
  {displayFields.map(({ field, format }) => {
120
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
122
121
  const value = item.get(field as any);
123
122
  return <td>{format ? format(value) : value}</td>;
124
123
  })}
@@ -141,6 +140,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
141
140
 
142
141
  })(${uppercase_collection});
143
142
  `;
143
+ return formatWithPrettier(result);
144
144
  };
145
145
  export {
146
146
  listTemplate
@@ -1,7 +1,8 @@
1
1
  import { curryImportPath } from "../utils/import-path.js";
2
- function testTemplate(action_name, new_file_fullpath) {
2
+ import { formatWithPrettier } from "../utils/prettier.js";
3
+ async function testTemplate(action_name, new_file_fullpath) {
3
4
  const rel = curryImportPath(new_file_fullpath);
4
- return `import { withProdApp } from "${rel(
5
+ const content = `import { withProdApp } from "${rel(
5
6
  "src/back/test_utils/with-prod-app.js"
6
7
  )}";
7
8
  import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "${rel(
@@ -52,6 +53,7 @@ describe("${action_name}", () => {
52
53
  ).timeout(VERY_LONG_TEST_TIMEOUT);
53
54
  });
54
55
  `;
56
+ return formatWithPrettier(content);
55
57
  }
56
58
  export {
57
59
  testTemplate
@@ -1,15 +1,19 @@
1
1
  import Prettier from "prettier";
2
2
  import _locreq from "locreq";
3
3
  const target_locreq = _locreq(process.cwd());
4
- async function getPrettierConfig() {
4
+ async function getPrettierConfig(parser = "typescript") {
5
5
  return {
6
6
  ...await Prettier.resolveConfig(
7
7
  target_locreq.resolve("src/back/routes")
8
8
  ),
9
- parser: "typescript"
9
+ parser
10
10
  };
11
11
  }
12
+ async function formatWithPrettier(content, lang = "typescript") {
13
+ return Prettier.format(content, await getPrettierConfig(lang));
14
+ }
12
15
  export {
16
+ formatWithPrettier,
13
17
  getPrettierConfig
14
18
  };
15
19
  //# sourceMappingURL=prettier.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.15.8",
3
+ "version": "0.15.11",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -32,7 +32,7 @@ const execAsync = (cmd: string) => {
32
32
  });
33
33
  };
34
34
 
35
- const callSealgenBin = () => `node ${locreq.resolve("dist/cli.js")}`;
35
+ const callSealgenBin = () => `node ${locreq.resolve("lib/cli.js")}`;
36
36
 
37
37
  describe("add route test", () => {
38
38
  let node_pid = 0;
@@ -54,11 +54,11 @@ describe("add route test", () => {
54
54
  it("creates minimal sealious app", async function () {
55
55
  console.log("\tcloning sealious-minimal...");
56
56
  await execAsync(
57
- `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout 5b33aac`
57
+ `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout df8cccf`
58
58
  );
59
59
  console.log("\tinstalling dependencies and sealgen...");
60
60
  await execAsync(
61
- `cd ${app_path} && npm ci && rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen`
61
+ `cd ${app_path} && npm ci rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen && ${callSealgenBin()} make-env`
62
62
  );
63
63
  console.log("\trunning add-route and building app...");
64
64
  await execAsync(
package/src/add-route.ts CHANGED
@@ -78,7 +78,10 @@ export async function addRoute(
78
78
  await fs.mkdir(resolve(file_path, "../"), { recursive: true });
79
79
  await fs.writeFile(file_path, await template(action, file_path));
80
80
  if (mode !== "lpr") {
81
- await fs.writeFile(test_file_path, testTemplate(action, file_path));
81
+ await fs.writeFile(
82
+ test_file_path,
83
+ await testTemplate(action, file_path)
84
+ );
82
85
  }
83
86
  // eslint-disable-next-line no-console
84
87
  console.log(`${file_path} created`);
@@ -0,0 +1,87 @@
1
+ import Router from "@koa/router";
2
+ import { Context } from "koa";
3
+ import { FileManager, FilePointer } from "@sealcode/file-manager";
4
+ import getPort from "get-port";
5
+ import Koa from "koa";
6
+ import fs from "node:fs/promises";
7
+ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
8
+ import { mount } from "../../mount.js";
9
+ import { Photo } from "../controls/photo.js";
10
+ import { Form } from "../form.js";
11
+ import { File as FileField } from "./file.js";
12
+ import { getBrowser } from "../../utils/browser-creator.js";
13
+ import assert from "node:assert";
14
+ import { Browser, Page } from "playwright";
15
+ import { module_dirname } from "../../utils/module-dirname.js";
16
+ import _locreq from "locreq";
17
+
18
+ const locreq = _locreq(module_dirname(import.meta.url));
19
+
20
+ describe("file field", () => {
21
+ let server: ReturnType<Koa["listen"]>;
22
+ let browser: Browser;
23
+ let page: Page;
24
+
25
+ afterEach(() => {
26
+ server.close();
27
+ });
28
+
29
+ it("should handle as imple upload scenario", async () => {
30
+ const port = await getPort();
31
+ console.log(`Using port http://localhost:${port} form file field test`);
32
+ const app = new Koa();
33
+ const router = new Router();
34
+
35
+ const fields = {
36
+ file: new FileField(true, new FileManager("/tmp", "/uploaded_files")),
37
+ };
38
+
39
+ let received_values: any;
40
+
41
+ mount(
42
+ router,
43
+ "/",
44
+ new (class extends Form<typeof fields, unknown> {
45
+ fields = fields;
46
+ controls = [
47
+ new Photo(
48
+ fields.file,
49
+ new KoaResponsiveImageRouter({
50
+ staticPath: "/tmp",
51
+ thumbnailSize: 10,
52
+ cacheManagerResolutionThreshold: 10,
53
+ imageStoragePath: "/tmp",
54
+ smartCropStoragePath: "/tmp",
55
+ })
56
+ ),
57
+ ];
58
+
59
+ async onSubmit(ctx: Context) {
60
+ received_values = await this.getParsedValues(ctx);
61
+ }
62
+
63
+ async canAccess(_: Context) {
64
+ return { canAccess: true, message: "" };
65
+ }
66
+ })(),
67
+ true
68
+ );
69
+ app.use(router.routes()).use(router.allowedMethods());
70
+ server = app.listen(port);
71
+
72
+ browser = await getBrowser();
73
+ const context = await browser.newContext();
74
+ page = await context.newPage();
75
+ // await sleep(999999999);
76
+ await page.goto(`http://localhost:${port}`);
77
+ // await page.getByPlaceholder("file").click();
78
+ await page.getByPlaceholder("file").setInputFiles({
79
+ name: "important.png",
80
+ mimeType: "image/png",
81
+ buffer: await fs.readFile(locreq.resolve("assets/important.png")),
82
+ });
83
+ await page.getByRole("button", { name: "Wyślij" }).click();
84
+ assert.ok(received_values.file.old == null);
85
+ assert.ok(received_values.file.new instanceof FilePointer);
86
+ }).timeout(999999);
87
+ });
@@ -1,6 +1,10 @@
1
1
  import { hasFieldOfType, is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
- import { FileManager, FilePointer } from "@sealcode/file-manager";
3
+ import {
4
+ FileManager,
5
+ FilePointer,
6
+ PathFilePointer,
7
+ } from "@sealcode/file-manager";
4
8
  import { FormDataValue } from "../form-types.js";
5
9
  import { FieldParseResult, FormField } from "./field.js";
6
10
 
@@ -42,20 +46,24 @@ export class File<Required extends boolean> extends FormField<
42
46
  const old_file = hasFieldOfType(
43
47
  raw_value,
44
48
  "old",
45
- predicates.or(predicates.string, predicates.object)
49
+ predicates.instanceOf(PathFilePointer)
46
50
  )
47
51
  ? await this.file_manager.toPointer(
48
52
  raw_value.old as string | FilePointer
49
53
  )
50
54
  : null;
51
- const new_file =
52
- hasFieldOfType(
53
- raw_value,
54
- "new",
55
- predicates.array(predicates.object)
56
- ) && raw_value.new[0] instanceof FilePointer
55
+ const new_file = hasFieldOfType(
56
+ raw_value,
57
+ "new",
58
+ predicates.or(
59
+ predicates.array(predicates.instanceOf(PathFilePointer)),
60
+ predicates.instanceOf(PathFilePointer)
61
+ )
62
+ )
63
+ ? Array.isArray(raw_value.new)
57
64
  ? raw_value.new[0]
58
- : null;
65
+ : raw_value.new
66
+ : null;
59
67
  result = {
60
68
  parsable: true as const,
61
69
  error: null,
@@ -1,11 +1,13 @@
1
+ import Prettier from "prettier";
1
2
  import { curryImportPath } from "../utils/import-path.js";
3
+ import { getPrettierConfig } from "../utils/prettier.js";
2
4
 
3
5
  export async function formTemplate(
4
6
  action_name: string,
5
7
  newfilefullpath: string
6
8
  ): Promise<string> {
7
9
  const rel = curryImportPath(newfilefullpath);
8
- return `import type { Context } from "koa";
10
+ const content = `import type { Context } from "koa";
9
11
  import type { FormData, FormDataValue } from "@sealcode/sealgen";
10
12
  import { Form, Fields, Controls, fieldsToShape } from "@sealcode/sealgen";
11
13
  import html from "${rel("src/back/html.js")}";
@@ -39,6 +41,7 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
39
41
  // just a silly example, please remove this with better logic
40
42
  const { parsed: email } = await this.fields.email.getValue(ctx, data);
41
43
  const { parsed: password } = await this.fields.password.getValue(ctx, data);
44
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
42
45
  if ((password || "").length > ((email as string) || "").length) {
43
46
  return { valid: false, error: "Password cannot be longer than email" };
44
47
  } else {
@@ -61,4 +64,5 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
61
64
  }
62
65
  })();
63
66
  `;
67
+ return Prettier.format(content, await getPrettierConfig());
64
68
  }
@@ -5,6 +5,7 @@ import { listCollections } from "../utils/list-collections.js";
5
5
  import { extractCollectionClassname } from "../generate-collections.js";
6
6
  import extract_fields_from_collection from "../utils/extract-fields-from-collection.js";
7
7
  import { DefaultListFilters } from "../page/default-list-filters.js";
8
+ import { formatWithPrettier } from "../utils/prettier.js";
8
9
  const target_locreq = _locreq(process.cwd());
9
10
 
10
11
  export const listTemplate = async (
@@ -31,25 +32,23 @@ export const listTemplate = async (
31
32
  ),
32
33
  extract_fields_from_collection(collection_name),
33
34
  ]);
34
- const rel = curryImportPath(newfilefullpath);
35
- return `import { Context } from "koa";
36
- import { CollectionItem } from "sealious";
37
- import { FlatTemplatable, TempstreamJSX } from "tempstream";
38
- import { ${uppercase_collection} } from "${rel(
39
- "src/back/collections/collections.js"
40
- )}";
41
- import html from "${rel("src/back/html.js")}";
35
+ const result = `import type { Context } from "koa";
36
+ import type { CollectionItem } from "sealious";
37
+ import type { FlatTemplatable } from "tempstream";
38
+ import { TempstreamJSX } from "tempstream";
39
+ import { Photos } from "../collections/collections.js";
40
+ import html from "../html.js";
41
+ import type { ListFilterRender } from "@sealcode/sealgen";
42
42
  import {
43
43
  SealiousItemListPage,
44
44
  BaseListPageFields,
45
45
  DefaultListFilters,
46
- ListFilterRender,
47
- } from "@sealcode/sealgen";;
46
+ } from "@sealcode/sealgen";
48
47
  import qs from "qs";
49
- import { is, predicates } from "@sealcode/ts-predicates";
50
48
 
51
49
  export const actionName = "${action_name}";
52
50
 
51
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
53
52
  const filterFields = [
54
53
  ${collection_fields
55
54
  .map(
@@ -134,6 +133,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
134
133
  async renderItem(_: Context, item: CollectionItem<typeof ${uppercase_collection}>) {
135
134
  return <tr>
136
135
  {displayFields.map(({ field, format }) => {
136
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
137
137
  const value = item.get(field as any);
138
138
  return <td>{format ? format(value) : value}</td>;
139
139
  })}
@@ -156,4 +156,5 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
156
156
 
157
157
  })(${uppercase_collection});
158
158
  `;
159
+ return formatWithPrettier(result);
159
160
  };
@@ -1,8 +1,12 @@
1
1
  import { curryImportPath } from "../utils/import-path.js";
2
+ import { formatWithPrettier } from "../utils/prettier.js";
2
3
 
3
- export function testTemplate(action_name: string, new_file_fullpath: string) {
4
+ export async function testTemplate(
5
+ action_name: string,
6
+ new_file_fullpath: string
7
+ ) {
4
8
  const rel = curryImportPath(new_file_fullpath);
5
- return `import { withProdApp } from "${rel(
9
+ const content = `import { withProdApp } from "${rel(
6
10
  "src/back/test_utils/with-prod-app.js"
7
11
  )}";
8
12
  import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "${rel(
@@ -53,4 +57,6 @@ describe("${action_name}", () => {
53
57
  ).timeout(VERY_LONG_TEST_TIMEOUT);
54
58
  });
55
59
  `;
60
+
61
+ return formatWithPrettier(content);
56
62
  }
@@ -3,11 +3,20 @@ import { Options } from "prettier";
3
3
  import _locreq from "locreq";
4
4
  const target_locreq = _locreq(process.cwd());
5
5
 
6
- export async function getPrettierConfig(): Promise<Options> {
6
+ export async function getPrettierConfig(
7
+ parser = "typescript"
8
+ ): Promise<Options> {
7
9
  return {
8
10
  ...(await Prettier.resolveConfig(
9
11
  target_locreq.resolve("src/back/routes")
10
12
  )),
11
- parser: "typescript",
13
+ parser,
12
14
  };
13
15
  }
16
+
17
+ export async function formatWithPrettier(
18
+ content: string,
19
+ lang = "typescript"
20
+ ): Promise<string> {
21
+ return Prettier.format(content, await getPrettierConfig(lang));
22
+ }