@sealcode/sealgen 0.15.15 → 0.15.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/src/forms/controls/file.test.d.ts +1 -0
- package/lib/forms/controls/file.js +1 -1
- package/lib/forms/controls/file.test.js +78 -0
- package/lib/forms/controls/photo.test.js +57 -1
- package/lib/page/stateful-page.js +1 -1
- package/lib/templates/post.js +2 -2
- package/lib/utils/render-attributes.js +2 -1
- package/package.json +1 -1
- package/src/forms/controls/file.test.ts +87 -0
- package/src/forms/controls/file.ts +1 -1
- package/src/forms/controls/photo.test.ts +63 -2
- package/src/page/stateful-page.ts +1 -1
- package/src/templates/post.ts +2 -2
- package/src/utils/render-attributes.ts +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import Router from "@koa/router";
|
|
2
|
+
import getPort from "get-port";
|
|
3
|
+
import Koa from "koa";
|
|
4
|
+
import { mount } from "../../mount.js";
|
|
5
|
+
import { Form } from "../form.js";
|
|
6
|
+
import { getBrowser } from "../../utils/browser-creator.js";
|
|
7
|
+
import { Controls, Fields, sleep } from "../../index.js";
|
|
8
|
+
import _locreq from "locreq";
|
|
9
|
+
import { module_dirname } from "../../utils/module-dirname.js";
|
|
10
|
+
import { FileManager, PathFilePointer } from "@sealcode/file-manager";
|
|
11
|
+
import assert from "node:assert";
|
|
12
|
+
const locreq = _locreq(module_dirname(import.meta.url));
|
|
13
|
+
describe("file-control", () => {
|
|
14
|
+
describe("basic tests", async () => {
|
|
15
|
+
let server;
|
|
16
|
+
let browser;
|
|
17
|
+
let page;
|
|
18
|
+
after(() => {
|
|
19
|
+
server.close();
|
|
20
|
+
});
|
|
21
|
+
it("doesn't require image input if it already has old-value", async () => {
|
|
22
|
+
const port = await getPort();
|
|
23
|
+
console.log(`Using port ${port} for photo.test.ts`);
|
|
24
|
+
const app = new Koa();
|
|
25
|
+
const router = new Router();
|
|
26
|
+
const fields = {
|
|
27
|
+
file: new Fields.File(true, new FileManager("/tmp", "/uploaded_files"))
|
|
28
|
+
};
|
|
29
|
+
let submit_called = false;
|
|
30
|
+
mount(
|
|
31
|
+
router,
|
|
32
|
+
"/",
|
|
33
|
+
new class extends Form {
|
|
34
|
+
constructor() {
|
|
35
|
+
super(...arguments);
|
|
36
|
+
this.fields = fields;
|
|
37
|
+
this.controls = [new Controls.File(fields.file)];
|
|
38
|
+
}
|
|
39
|
+
async onSubmit(_ctx) {
|
|
40
|
+
submit_called = true;
|
|
41
|
+
}
|
|
42
|
+
async getInitialValues(_ctx) {
|
|
43
|
+
const file = new PathFilePointer(
|
|
44
|
+
new FileManager("/tmp", "/uploaded_files"),
|
|
45
|
+
locreq.resolve("assets/important.png")
|
|
46
|
+
);
|
|
47
|
+
return {
|
|
48
|
+
file: await file.save(false)
|
|
49
|
+
// to get the token
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async canAccess(_) {
|
|
53
|
+
return { canAccess: true, message: "" };
|
|
54
|
+
}
|
|
55
|
+
}(),
|
|
56
|
+
true
|
|
57
|
+
);
|
|
58
|
+
app.use(router.routes()).use(router.allowedMethods());
|
|
59
|
+
server = app.listen(port);
|
|
60
|
+
browser = await getBrowser();
|
|
61
|
+
const context = await browser.newContext();
|
|
62
|
+
page = await context.newPage();
|
|
63
|
+
let screenshot = true;
|
|
64
|
+
(async function() {
|
|
65
|
+
while (screenshot) {
|
|
66
|
+
await page.screenshot({ path: "/home/kuba/Downloads/" + Date.now() + ".png" });
|
|
67
|
+
await sleep(100);
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
await page.goto(`http://localhost:${port}`);
|
|
71
|
+
await page.getByRole("button", { name: "Wy\u015Blij" }).click();
|
|
72
|
+
await sleep(100);
|
|
73
|
+
assert(submit_called, "Submit not called - something prevented submit on click?");
|
|
74
|
+
screenshot = false;
|
|
75
|
+
});
|
|
76
|
+
}).timeout(1e4);
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=file.test.js.map
|
|
@@ -74,6 +74,62 @@ describe("photo-control", () => {
|
|
|
74
74
|
await page.getByRole("button", { name: "Wy\u015Blij" }).click();
|
|
75
75
|
assert(received_photo !== void 0 && received_photo.old !== null);
|
|
76
76
|
});
|
|
77
|
-
|
|
77
|
+
it("doesn't require image input if it already has old-value", async () => {
|
|
78
|
+
const port = await getPort();
|
|
79
|
+
console.log(`Using port ${port} for photo.test.ts`);
|
|
80
|
+
const app = new Koa();
|
|
81
|
+
const router = new Router();
|
|
82
|
+
const fields = {
|
|
83
|
+
photo: new Fields.File(true, new FileManager("/tmp", "/uploaded_files"))
|
|
84
|
+
};
|
|
85
|
+
let received_photo;
|
|
86
|
+
const imageRouter = new KoaResponsiveImageRouter({
|
|
87
|
+
staticPath: "/images",
|
|
88
|
+
thumbnailSize: 20,
|
|
89
|
+
cacheManagerResolutionThreshold: 50,
|
|
90
|
+
imageStoragePath: `/tmp/image-cache-${port}`,
|
|
91
|
+
smartCropStoragePath: `/tmp/smartcrop-storage-${port}`
|
|
92
|
+
});
|
|
93
|
+
let submit_called = false;
|
|
94
|
+
mount(
|
|
95
|
+
router,
|
|
96
|
+
"/",
|
|
97
|
+
new class extends Form {
|
|
98
|
+
constructor() {
|
|
99
|
+
super(...arguments);
|
|
100
|
+
this.fields = fields;
|
|
101
|
+
this.controls = [new Photo(fields.photo, imageRouter)];
|
|
102
|
+
}
|
|
103
|
+
async onSubmit(ctx) {
|
|
104
|
+
submit_called = true;
|
|
105
|
+
const data = await this.getParsedValues(ctx);
|
|
106
|
+
received_photo = data.photo;
|
|
107
|
+
}
|
|
108
|
+
async getInitialValues(_ctx) {
|
|
109
|
+
const file = new PathFilePointer(
|
|
110
|
+
new FileManager("/tmp", "/uploaded_files"),
|
|
111
|
+
locreq.resolve("assets/important.png")
|
|
112
|
+
);
|
|
113
|
+
return {
|
|
114
|
+
photo: await file.save(false)
|
|
115
|
+
// to get the token
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async canAccess(_) {
|
|
119
|
+
return { canAccess: true, message: "" };
|
|
120
|
+
}
|
|
121
|
+
}(),
|
|
122
|
+
true
|
|
123
|
+
);
|
|
124
|
+
app.use(router.routes()).use(router.allowedMethods());
|
|
125
|
+
server = app.listen(port);
|
|
126
|
+
browser = await getBrowser();
|
|
127
|
+
const context = await browser.newContext();
|
|
128
|
+
page = await context.newPage();
|
|
129
|
+
await page.goto(`http://localhost:${port}`);
|
|
130
|
+
await page.getByRole("button", { name: "Wy\u015Blij" }).click();
|
|
131
|
+
assert(submit_called, "Submit not called - something prevented submit on click?");
|
|
132
|
+
});
|
|
133
|
+
}).timeout(1e4);
|
|
78
134
|
});
|
|
79
135
|
//# sourceMappingURL=photo.test.js.map
|
|
@@ -128,7 +128,7 @@ class StatefulPage extends Mountable {
|
|
|
128
128
|
state_overrides
|
|
129
129
|
);
|
|
130
130
|
let modified_state = deepmerge(original_state, state_overrides, {
|
|
131
|
-
isMergeableObject: isPlainObject,
|
|
131
|
+
isMergeableObject: (v) => isPlainObject(v) || Array.isArray(v),
|
|
132
132
|
arrayMerge: (target, source, options) => {
|
|
133
133
|
const destination = target.slice();
|
|
134
134
|
source.forEach((item, index) => {
|
package/lib/templates/post.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
async function postTemplate(action_name) {
|
|
2
|
-
return `import { Context } from "koa";
|
|
2
|
+
return `import type { Context } from "koa";
|
|
3
3
|
import { Mountable } from "@sealcode/sealgen";
|
|
4
|
-
import Router from "@koa/router";
|
|
4
|
+
import type Router from "@koa/router";
|
|
5
5
|
|
|
6
6
|
export const actionName = "${action_name}";
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { attribute } from "../sanitize.js";
|
|
2
2
|
function renderAttributes(attrs) {
|
|
3
|
-
|
|
3
|
+
const ret = Object.entries(attrs).map(([key, value]) => {
|
|
4
4
|
if (typeof value === "boolean") {
|
|
5
5
|
if (value) {
|
|
6
6
|
return key;
|
|
@@ -13,6 +13,7 @@ function renderAttributes(attrs) {
|
|
|
13
13
|
return "";
|
|
14
14
|
}
|
|
15
15
|
}).join(" ");
|
|
16
|
+
return ret;
|
|
16
17
|
}
|
|
17
18
|
export {
|
|
18
19
|
renderAttributes
|
package/package.json
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import Router from "@koa/router";
|
|
2
|
+
import getPort from "get-port";
|
|
3
|
+
import { Browser, Page } from "playwright";
|
|
4
|
+
import type { Context } from "koa";
|
|
5
|
+
import Koa from "koa";
|
|
6
|
+
import { mount } from "../../mount.js";
|
|
7
|
+
import { Form } from "../form.js";
|
|
8
|
+
import { getBrowser } from "../../utils/browser-creator.js";
|
|
9
|
+
import { Controls, Fields, sleep } from "../../index.js";
|
|
10
|
+
|
|
11
|
+
import _locreq from "locreq";
|
|
12
|
+
import { module_dirname } from "../../utils/module-dirname.js";
|
|
13
|
+
import { FileManager, PathFilePointer } from "@sealcode/file-manager";
|
|
14
|
+
import assert from "node:assert";
|
|
15
|
+
const locreq = _locreq(module_dirname(import.meta.url));
|
|
16
|
+
|
|
17
|
+
describe("file-control", () => {
|
|
18
|
+
describe("basic tests", async () => {
|
|
19
|
+
let server: ReturnType<Koa["listen"]>;
|
|
20
|
+
let browser: Browser;
|
|
21
|
+
let page: Page;
|
|
22
|
+
|
|
23
|
+
after(() => {
|
|
24
|
+
server.close();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("doesn't require image input if it already has old-value", async () => {
|
|
28
|
+
const port = await getPort();
|
|
29
|
+
console.log(`Using port ${port} for photo.test.ts`);
|
|
30
|
+
const app = new Koa();
|
|
31
|
+
const router = new Router();
|
|
32
|
+
|
|
33
|
+
const fields = {
|
|
34
|
+
file: new Fields.File(true, new FileManager("/tmp", "/uploaded_files")),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
let submit_called = false;
|
|
38
|
+
|
|
39
|
+
mount(
|
|
40
|
+
router,
|
|
41
|
+
"/",
|
|
42
|
+
new (class extends Form<typeof fields, unknown> {
|
|
43
|
+
fields = fields;
|
|
44
|
+
controls = [new Controls.File(fields.file)];
|
|
45
|
+
|
|
46
|
+
async onSubmit(_ctx: Context) {
|
|
47
|
+
submit_called = true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async getInitialValues(_ctx: Context) {
|
|
51
|
+
const file = new PathFilePointer(
|
|
52
|
+
new FileManager("/tmp", "/uploaded_files"),
|
|
53
|
+
locreq.resolve("assets/important.png")
|
|
54
|
+
);
|
|
55
|
+
return {
|
|
56
|
+
file: await file.save(false), // to get the token
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async canAccess(_: Context) {
|
|
61
|
+
return { canAccess: true, message: "" };
|
|
62
|
+
}
|
|
63
|
+
})(),
|
|
64
|
+
true
|
|
65
|
+
);
|
|
66
|
+
app.use(router.routes()).use(router.allowedMethods());
|
|
67
|
+
server = app.listen(port);
|
|
68
|
+
|
|
69
|
+
browser = await getBrowser();
|
|
70
|
+
const context = await browser.newContext();
|
|
71
|
+
page = await context.newPage();
|
|
72
|
+
let screenshot = true;
|
|
73
|
+
(async function () {
|
|
74
|
+
while (screenshot) {
|
|
75
|
+
await page.screenshot({ path: "/home/kuba/Downloads/" + Date.now() + ".png" });
|
|
76
|
+
await sleep(100);
|
|
77
|
+
}
|
|
78
|
+
})();
|
|
79
|
+
await page.goto(`http://localhost:${port}`);
|
|
80
|
+
|
|
81
|
+
await page.getByRole("button", { name: "Wyślij" }).click();
|
|
82
|
+
await sleep(100);
|
|
83
|
+
assert(submit_called, "Submit not called - something prevented submit on click?");
|
|
84
|
+
screenshot = false;
|
|
85
|
+
});
|
|
86
|
+
}).timeout(10000);
|
|
87
|
+
});
|
|
@@ -76,7 +76,6 @@ describe("photo-control", () => {
|
|
|
76
76
|
);
|
|
77
77
|
app.use(router.routes()).use(router.allowedMethods());
|
|
78
78
|
server = app.listen(port);
|
|
79
|
-
// await sleep(99999999);
|
|
80
79
|
|
|
81
80
|
browser = await getBrowser();
|
|
82
81
|
const context = await browser.newContext();
|
|
@@ -85,5 +84,67 @@ describe("photo-control", () => {
|
|
|
85
84
|
await page.getByRole("button", { name: "Wyślij" }).click();
|
|
86
85
|
assert(received_photo !== undefined && (received_photo as any).old !== null);
|
|
87
86
|
});
|
|
88
|
-
|
|
87
|
+
|
|
88
|
+
it("doesn't require image input if it already has old-value", async () => {
|
|
89
|
+
const port = await getPort();
|
|
90
|
+
console.log(`Using port ${port} for photo.test.ts`);
|
|
91
|
+
const app = new Koa();
|
|
92
|
+
const router = new Router();
|
|
93
|
+
|
|
94
|
+
const fields = {
|
|
95
|
+
photo: new Fields.File(true, new FileManager("/tmp", "/uploaded_files")),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
let received_photo: unknown;
|
|
99
|
+
|
|
100
|
+
const imageRouter = new KoaResponsiveImageRouter({
|
|
101
|
+
staticPath: "/images",
|
|
102
|
+
thumbnailSize: 20,
|
|
103
|
+
cacheManagerResolutionThreshold: 50,
|
|
104
|
+
imageStoragePath: `/tmp/image-cache-${port}`,
|
|
105
|
+
smartCropStoragePath: `/tmp/smartcrop-storage-${port}`,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
let submit_called = false;
|
|
109
|
+
|
|
110
|
+
mount(
|
|
111
|
+
router,
|
|
112
|
+
"/",
|
|
113
|
+
new (class extends Form<typeof fields, unknown> {
|
|
114
|
+
fields = fields;
|
|
115
|
+
controls = [new Photo(fields.photo, imageRouter)];
|
|
116
|
+
|
|
117
|
+
async onSubmit(ctx: Context) {
|
|
118
|
+
submit_called = true;
|
|
119
|
+
const data = await this.getParsedValues(ctx);
|
|
120
|
+
received_photo = data.photo;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async getInitialValues(_ctx: Context) {
|
|
124
|
+
const file = new PathFilePointer(
|
|
125
|
+
new FileManager("/tmp", "/uploaded_files"),
|
|
126
|
+
locreq.resolve("assets/important.png")
|
|
127
|
+
);
|
|
128
|
+
return {
|
|
129
|
+
photo: await file.save(false), // to get the token
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async canAccess(_: Context) {
|
|
134
|
+
return { canAccess: true, message: "" };
|
|
135
|
+
}
|
|
136
|
+
})(),
|
|
137
|
+
true
|
|
138
|
+
);
|
|
139
|
+
app.use(router.routes()).use(router.allowedMethods());
|
|
140
|
+
server = app.listen(port);
|
|
141
|
+
|
|
142
|
+
browser = await getBrowser();
|
|
143
|
+
const context = await browser.newContext();
|
|
144
|
+
page = await context.newPage();
|
|
145
|
+
await page.goto(`http://localhost:${port}`);
|
|
146
|
+
await page.getByRole("button", { name: "Wyślij" }).click();
|
|
147
|
+
assert(submit_called, "Submit not called - something prevented submit on click?");
|
|
148
|
+
});
|
|
149
|
+
}).timeout(10000);
|
|
89
150
|
});
|
|
@@ -236,7 +236,7 @@ export abstract class StatefulPage<
|
|
|
236
236
|
state_overrides
|
|
237
237
|
);
|
|
238
238
|
let modified_state = deepmerge(original_state, state_overrides, {
|
|
239
|
-
isMergeableObject: isPlainObject,
|
|
239
|
+
isMergeableObject: (v) => isPlainObject(v) || Array.isArray(v),
|
|
240
240
|
arrayMerge: (
|
|
241
241
|
target: any[],
|
|
242
242
|
source: any[],
|
package/src/templates/post.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export async function postTemplate(action_name: string): Promise<string> {
|
|
2
|
-
return `import { Context } from "koa";
|
|
2
|
+
return `import type { Context } from "koa";
|
|
3
3
|
import { Mountable } from "@sealcode/sealgen";
|
|
4
|
-
import Router from "@koa/router";
|
|
4
|
+
import type Router from "@koa/router";
|
|
5
5
|
|
|
6
6
|
export const actionName = "${action_name}";
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { attribute } from "../sanitize.js";
|
|
2
2
|
|
|
3
3
|
export function renderAttributes(attrs: Record<string, string | boolean>) {
|
|
4
|
-
|
|
4
|
+
const ret = Object.entries(attrs)
|
|
5
5
|
.map(([key, value]) => {
|
|
6
6
|
if (typeof value === "boolean") {
|
|
7
7
|
if (value) {
|
|
@@ -16,4 +16,6 @@ export function renderAttributes(attrs: Record<string, string | boolean>) {
|
|
|
16
16
|
}
|
|
17
17
|
})
|
|
18
18
|
.join(" ");
|
|
19
|
+
|
|
20
|
+
return ret;
|
|
19
21
|
}
|