@sealcode/sealgen 0.8.53 → 0.9.1
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/lib/add-route.js +1 -1
- package/lib/build.js +30 -1
- package/lib/generate-collections.js +1 -1
- package/lib/generate-routes.js +1 -1
- package/lib/page/list.js +22 -15
- package/lib/templates/form.js +2 -2
- package/lib/templates/list.js +3 -3
- package/lib/templates/multiform.js +1 -1
- package/lib/templates/page.js +1 -1
- package/lib/templates/route-test.js +43 -13
- package/lib/templates/stateful-page.js +1 -1
- package/lib/utils/import-path.js +1 -1
- package/package.json +2 -2
- package/src/add-route.ts +1 -1
- package/src/build.ts +56 -1
- package/src/generate-collections.ts +1 -1
- package/src/generate-routes.ts +1 -1
- package/src/page/list.ts +36 -29
- package/src/templates/form.ts +2 -2
- package/src/templates/list.ts +3 -3
- package/src/templates/multiform.ts +1 -1
- package/src/templates/page.ts +1 -1
- package/src/templates/route-test.ts +43 -13
- package/src/templates/stateful-page.ts +1 -1
- package/src/utils/import-path.ts +1 -1
package/lib/add-route.js
CHANGED
|
@@ -31,7 +31,7 @@ async function addRoute(params, app_directory = process.cwd()) {
|
|
|
31
31
|
{
|
|
32
32
|
type: "text",
|
|
33
33
|
name: "url",
|
|
34
|
-
message: "Enter a full absolute path for the new route (
|
|
34
|
+
message: "Enter a full absolute path for the new route (for example: /admin/users/:id/edit): ",
|
|
35
35
|
validate: (s) => s.trim()[0] == "/" ? true : "Should start with a '/'",
|
|
36
36
|
},
|
|
37
37
|
{
|
package/lib/build.js
CHANGED
|
@@ -28,6 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.buildProject = void 0;
|
|
30
30
|
const esbuild_1 = require("esbuild");
|
|
31
|
+
const fs_1 = require("fs");
|
|
31
32
|
const esbuild_sass_plugin_1 = require("esbuild-sass-plugin");
|
|
32
33
|
const chokidar = __importStar(require("chokidar"));
|
|
33
34
|
const tiny_glob_1 = __importDefault(require("tiny-glob"));
|
|
@@ -35,6 +36,14 @@ const find_scss_includes_1 = require("./find-scss-includes");
|
|
|
35
36
|
const sleep_1 = require("./utils/sleep");
|
|
36
37
|
const generate_collections_1 = require("./generate-collections");
|
|
37
38
|
const generate_routes_1 = require("./generate-routes");
|
|
39
|
+
const generate_names = (function* generate_names() {
|
|
40
|
+
let base_name = "______unique_import_";
|
|
41
|
+
let count = 0;
|
|
42
|
+
while (true) {
|
|
43
|
+
yield base_name + count;
|
|
44
|
+
count++;
|
|
45
|
+
}
|
|
46
|
+
})();
|
|
38
47
|
async function build_ts() {
|
|
39
48
|
await Promise.all([(0, generate_collections_1.generateCollections)(), (0, generate_routes_1.generateRoutes)()]);
|
|
40
49
|
const entryPoints = (await (0, tiny_glob_1.default)("./src/back/**/*.ts")).filter((path) => !path.includes(".#"));
|
|
@@ -46,7 +55,27 @@ async function build_ts() {
|
|
|
46
55
|
logLevel: "info",
|
|
47
56
|
platform: "node",
|
|
48
57
|
target: "es2022",
|
|
49
|
-
format: "
|
|
58
|
+
format: "esm",
|
|
59
|
+
plugins: [
|
|
60
|
+
{
|
|
61
|
+
name: "remove-named-imports",
|
|
62
|
+
setup(build) {
|
|
63
|
+
build.onLoad({ filter: /.*/ }, async ({ path }) => {
|
|
64
|
+
const named_and_default_regex = /^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
|
|
65
|
+
const old_content = await fs_1.promises.readFile(path, "utf-8");
|
|
66
|
+
const contents = old_content.replace(named_and_default_regex, (entire_string, default_import_name, _, all_named, module_path) => {
|
|
67
|
+
const new_name = generate_names.next().value;
|
|
68
|
+
return `import * as ${new_name} from ${module_path}; ${default_import_name
|
|
69
|
+
? `const ${default_import_name.replace(",", "")} = ${new_name}`
|
|
70
|
+
: ""}; const ${all_named.replaceAll(/\s+as\s+/g, ": ")} = ${/\s+default\s+as/.test(all_named)
|
|
71
|
+
? `${new_name};`
|
|
72
|
+
: `${new_name}.default || ${new_name};`}`;
|
|
73
|
+
});
|
|
74
|
+
return { contents, loader: "ts" };
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
50
79
|
});
|
|
51
80
|
}
|
|
52
81
|
catch (e) {
|
|
@@ -61,7 +61,7 @@ async function generateCollections() {
|
|
|
61
61
|
import { App } from "sealious";
|
|
62
62
|
|
|
63
63
|
${file_data
|
|
64
|
-
.map(({ class_name, urlname }) => `import _${class_name} from "./${urlname}";`)
|
|
64
|
+
.map(({ class_name, urlname }) => `import _${class_name} from "./${urlname}.js";`)
|
|
65
65
|
.join("\n")}
|
|
66
66
|
|
|
67
67
|
${file_data
|
package/lib/generate-routes.js
CHANGED
|
@@ -84,7 +84,7 @@ async function generateRoutes() {
|
|
|
84
84
|
|
|
85
85
|
import Router from "@koa/router";
|
|
86
86
|
import { mount } from "@sealcode/sealgen";
|
|
87
|
-
import * as URLs from "./urls"
|
|
87
|
+
import * as URLs from "./urls.js"
|
|
88
88
|
|
|
89
89
|
${files
|
|
90
90
|
.map(({ actionName, fullpath }) => `import { default as ${actionName} } from "${(0, import_path_1.importPath)(target_locreq.resolve("src/back/routes/routes.ts"), fullpath)}";`)
|
package/lib/page/list.js
CHANGED
|
@@ -77,31 +77,38 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
|
77
77
|
async renderPagination(ctx, values) {
|
|
78
78
|
const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
|
|
79
79
|
const totalIems = await this.getTotalPages(ctx, itemsPerPage, values);
|
|
80
|
-
return (0, tempstream_1.tempstream /* HTML */) `<
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
return (0, tempstream_1.tempstream /* HTML */) `<div class="list-pagination">
|
|
81
|
+
<div class="list-pagination__left">
|
|
82
|
+
${page > 1
|
|
83
|
+
? this.renderPageButton(ctx, 1, "Pierwsza strona")
|
|
84
|
+
: ""}
|
|
85
|
+
${page > 1
|
|
83
86
|
? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
|
|
84
87
|
: ""}
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
</div>
|
|
89
|
+
<div class="list-pagination__center">
|
|
90
|
+
<select onchange="if (this.value) Turbo.visit(this.value)">
|
|
91
|
+
${Array.from((0, utils_1.naturalNumbers)(1, totalIems)).map((n) => /* HTML */ `<option
|
|
92
|
+
value="${(0, utils_1.UrlWithNewParams)(ctx,
|
|
89
93
|
//eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
90
94
|
this.propsParser.overwriteProp(ctx, {
|
|
91
95
|
page: n,
|
|
92
96
|
}))}"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
${page === n ? "selected" : ""}
|
|
98
|
+
>
|
|
99
|
+
${n}
|
|
100
|
+
</option>`)}
|
|
101
|
+
</select>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="list-pagination__right">
|
|
104
|
+
${page < totalIems
|
|
99
105
|
? this.renderPageButton(ctx, page + 1, "Następna strona")
|
|
100
106
|
: ""}
|
|
101
|
-
|
|
107
|
+
${page < totalIems
|
|
102
108
|
? this.renderPageButton(ctx, totalIems, "Ostatnia strona")
|
|
103
109
|
: ""}
|
|
104
|
-
|
|
110
|
+
</div>
|
|
111
|
+
</div>`;
|
|
105
112
|
}
|
|
106
113
|
renderPageButton(ctx, page, text) {
|
|
107
114
|
return /* HTML */ `<a
|
package/lib/templates/form.js
CHANGED
|
@@ -6,8 +6,8 @@ async function formTemplate(action_name, newfilefullpath) {
|
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
8
|
import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen";
|
|
9
|
-
import html from "${rel("src/back/html")}";
|
|
10
|
-
import { Users } from "${rel("src/back/collections/collections")}";
|
|
9
|
+
import html from "${rel("src/back/html.js")}";
|
|
10
|
+
import { Users } from "${rel("src/back/collections/collections.js")}";
|
|
11
11
|
|
|
12
12
|
export const actionName = "${action_name}";
|
|
13
13
|
|
package/lib/templates/list.js
CHANGED
|
@@ -20,8 +20,8 @@ const listTemplate = async (action_name, newfilefullpath) => {
|
|
|
20
20
|
return `import { Context } from "koa";
|
|
21
21
|
import { CollectionItem } from "sealious";
|
|
22
22
|
import { tempstream } from "tempstream";
|
|
23
|
-
import { ${uppercase_collection} } from "${rel("src/back/collections/collections")}";
|
|
24
|
-
import html from "${rel("src/back/html.
|
|
23
|
+
import { ${uppercase_collection} } from "${rel("src/back/collections/collections.js")}";
|
|
24
|
+
import html from "${rel("src/back/html.js")}";
|
|
25
25
|
import { SealiousItemListPage, BaseListPageFields } from "@sealcode/sealgen";
|
|
26
26
|
|
|
27
27
|
export const actionName = "${action_name}";
|
|
@@ -43,7 +43,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
|
|
|
43
43
|
"${uppercase_collection}",
|
|
44
44
|
tempstream/* HTML */ \`<div>
|
|
45
45
|
<h2>${uppercase_collection} List</h2>
|
|
46
|
-
<table>
|
|
46
|
+
<table class="sealious-list">
|
|
47
47
|
\${this.renderTableHead(ctx, [
|
|
48
48
|
{ field: "id" },
|
|
49
49
|
...Object.keys(Patrons.fields).map((field) => ({
|
|
@@ -5,7 +5,7 @@ const utils_1 = require("../utils/utils");
|
|
|
5
5
|
async function multiformTemplate(action_name, newfilefullpath) {
|
|
6
6
|
const rel = (0, utils_1.curryImportPath)(newfilefullpath);
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
|
-
import html from "${rel("src/back/html")}";
|
|
8
|
+
import html from "${rel("src/back/html.js")}";
|
|
9
9
|
import { Controls, Fields, Form, FormMessage, Multiform } from "@sealcode/sealgen";
|
|
10
10
|
import { FlatTemplatable } from "tempstream";
|
|
11
11
|
|
package/lib/templates/page.js
CHANGED
|
@@ -7,7 +7,7 @@ async function pageTemplate(action_name, newfilefullpath) {
|
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
8
|
import { tempstream } from "tempstream";
|
|
9
9
|
import { Page } from "@sealcode/sealgen";
|
|
10
|
-
import html from "${rel("src/back/html")}";
|
|
10
|
+
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
|
|
12
12
|
export const actionName = "${action_name}";
|
|
13
13
|
|
|
@@ -4,22 +4,52 @@ exports.testTemplate = void 0;
|
|
|
4
4
|
const import_path_1 = require("../utils/import-path");
|
|
5
5
|
function testTemplate(action_name, new_file_fullpath) {
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(new_file_fullpath);
|
|
7
|
-
return `import { withProdApp } from "${rel("src/back/test_utils/with-prod-app")}";
|
|
8
|
-
import { LONG_TEST_TIMEOUT, webhintURL } from "${rel("src/back/test_utils/webhint")}";
|
|
9
|
-
import { ${action_name}URL } from "${rel("src/back/routes/urls")}";
|
|
7
|
+
return `import { withProdApp } from "${rel("src/back/test_utils/with-prod-app.js")}";
|
|
8
|
+
import { LONG_TEST_TIMEOUT, webhintURL } from "${rel("src/back/test_utils/webhint.js")}";
|
|
9
|
+
import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
|
|
10
|
+
import { getBrowser } from "${rel("src/test_utils/browser-creator.js")}";
|
|
11
|
+
|
|
12
|
+
describe("${action_name} webhint", () => {
|
|
13
|
+
it(
|
|
14
|
+
"doesn't crash",
|
|
15
|
+
async function () {
|
|
16
|
+
return withProdApp(async ({ base_url, rest_api }) => {
|
|
17
|
+
await rest_api.get(${action_name}URL);
|
|
18
|
+
await webhintURL(base_url + ${action_name}URL);
|
|
19
|
+
// alternatively you can use webhintHTML for faster but less precise scans
|
|
20
|
+
// or for scanning responses of requests that use some form of authorization:
|
|
21
|
+
// const response = await rest_api.get(${action_name}URL);
|
|
22
|
+
// await webhintHTML(response);
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
VERY_LONG_TEST_TIMEOUT
|
|
26
|
+
);
|
|
27
|
+
});
|
|
10
28
|
|
|
11
29
|
describe("${action_name}", () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// await webhintHTML(response);
|
|
21
|
-
});
|
|
30
|
+
let page: Page;
|
|
31
|
+
let browser: Browser;
|
|
32
|
+
let context: BrowserContext;
|
|
33
|
+
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
browser = await getBrowser();
|
|
36
|
+
context = await browser.newContext();
|
|
37
|
+
page = await context.newPage();
|
|
22
38
|
});
|
|
39
|
+
|
|
40
|
+
afterEach(async () => {
|
|
41
|
+
await context.close();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it(
|
|
45
|
+
"works as expected",
|
|
46
|
+
async function () {
|
|
47
|
+
return withProdApp(async ({ base_url }) => {
|
|
48
|
+
await page.goto(base_url + ${action_name}URL);
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
VERY_LONG_TEST_TIMEOUT
|
|
52
|
+
);
|
|
23
53
|
});
|
|
24
54
|
`;
|
|
25
55
|
}
|
|
@@ -7,7 +7,7 @@ async function statefulPageTemplate(action_name, newfilefullpath) {
|
|
|
7
7
|
return `import { BaseContext } from "koa";
|
|
8
8
|
import { tempstream, Templatable } from "tempstream";
|
|
9
9
|
import { StatefulPage } from "@sealcode/sealgen";
|
|
10
|
-
import html from "${rel("src/back/html")}";
|
|
10
|
+
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
|
|
12
12
|
export const actionName = "${action_name}";
|
|
13
13
|
|
package/lib/utils/import-path.js
CHANGED
|
@@ -8,7 +8,7 @@ const path_1 = require("path");
|
|
|
8
8
|
const locreq_1 = __importDefault(require("locreq"));
|
|
9
9
|
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
10
10
|
function importPath(project_module_path, project_target_path) {
|
|
11
|
-
let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.ts$/, ""));
|
|
11
|
+
let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.ts$/, ".js"));
|
|
12
12
|
if (result[0] != ".") {
|
|
13
13
|
result = "./" + result;
|
|
14
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"playwright": "^1.29.2",
|
|
41
41
|
"source-map-support": "^0.5.21",
|
|
42
42
|
"ts-node": "^10.9.1",
|
|
43
|
-
"typescript": "^4.
|
|
43
|
+
"typescript": "^4.7",
|
|
44
44
|
"wait-port": "^1.0.4"
|
|
45
45
|
},
|
|
46
46
|
"types": "./@types/index.d.ts",
|
package/src/add-route.ts
CHANGED
|
@@ -31,7 +31,7 @@ export async function addRoute(
|
|
|
31
31
|
type: "text",
|
|
32
32
|
name: "url",
|
|
33
33
|
message:
|
|
34
|
-
"Enter a full absolute path for the new route (
|
|
34
|
+
"Enter a full absolute path for the new route (for example: /admin/users/:id/edit): ",
|
|
35
35
|
validate: (s: string) =>
|
|
36
36
|
s.trim()[0] == "/" ? true : "Should start with a '/'",
|
|
37
37
|
},
|
package/src/build.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { build, BuildResult } from "esbuild";
|
|
2
|
+
import { promises as fs } from "fs";
|
|
2
3
|
import { sassPlugin } from "esbuild-sass-plugin";
|
|
3
4
|
import * as chokidar from "chokidar";
|
|
4
5
|
import { default as glob } from "tiny-glob";
|
|
@@ -7,6 +8,15 @@ import { sleep } from "./utils/sleep";
|
|
|
7
8
|
import { generateCollections } from "./generate-collections";
|
|
8
9
|
import { generateRoutes } from "./generate-routes";
|
|
9
10
|
|
|
11
|
+
const generate_names = (function* generate_names() {
|
|
12
|
+
let base_name = "______unique_import_";
|
|
13
|
+
let count = 0;
|
|
14
|
+
while (true) {
|
|
15
|
+
yield base_name + count;
|
|
16
|
+
count++;
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
19
|
+
|
|
10
20
|
async function build_ts() {
|
|
11
21
|
await Promise.all([generateCollections(), generateRoutes()]);
|
|
12
22
|
const entryPoints = (await glob("./src/back/**/*.ts")).filter(
|
|
@@ -20,7 +30,52 @@ async function build_ts() {
|
|
|
20
30
|
logLevel: "info",
|
|
21
31
|
platform: "node",
|
|
22
32
|
target: "es2022",
|
|
23
|
-
format: "
|
|
33
|
+
format: "esm",
|
|
34
|
+
plugins: [
|
|
35
|
+
{
|
|
36
|
+
name: "remove-named-imports", // named imports sometime cause some esm incompatibilities, like the "is a CommonJS module, which may not support all module.exports as named exports." error
|
|
37
|
+
setup(build) {
|
|
38
|
+
build.onLoad({ filter: /.*/ }, async ({ path }) => {
|
|
39
|
+
const named_and_default_regex =
|
|
40
|
+
/^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
|
|
41
|
+
|
|
42
|
+
const old_content = await fs.readFile(
|
|
43
|
+
path,
|
|
44
|
+
"utf-8"
|
|
45
|
+
);
|
|
46
|
+
const contents = old_content.replace(
|
|
47
|
+
named_and_default_regex,
|
|
48
|
+
(
|
|
49
|
+
entire_string,
|
|
50
|
+
default_import_name,
|
|
51
|
+
_,
|
|
52
|
+
all_named,
|
|
53
|
+
module_path
|
|
54
|
+
) => {
|
|
55
|
+
const new_name =
|
|
56
|
+
generate_names.next().value;
|
|
57
|
+
return `import * as ${new_name} from ${module_path}; ${
|
|
58
|
+
default_import_name
|
|
59
|
+
? `const ${default_import_name.replace(
|
|
60
|
+
",",
|
|
61
|
+
""
|
|
62
|
+
)} = ${new_name}`
|
|
63
|
+
: ""
|
|
64
|
+
}; const ${all_named.replaceAll(
|
|
65
|
+
/\s+as\s+/g,
|
|
66
|
+
": "
|
|
67
|
+
)} = ${
|
|
68
|
+
/\s+default\s+as/.test(all_named)
|
|
69
|
+
? `${new_name};`
|
|
70
|
+
: `${new_name}.default || ${new_name};`
|
|
71
|
+
}`;
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
return { contents, loader: "ts" };
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
24
79
|
});
|
|
25
80
|
} catch (e) {
|
|
26
81
|
console.error(e.message);
|
package/src/generate-routes.ts
CHANGED
package/src/page/list.ts
CHANGED
|
@@ -120,35 +120,42 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
|
120
120
|
const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
|
|
121
121
|
const totalIems = await this.getTotalPages(ctx, itemsPerPage, values);
|
|
122
122
|
|
|
123
|
-
return tempstream/* HTML */ `<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
123
|
+
return tempstream/* HTML */ `<div class="list-pagination">
|
|
124
|
+
<div class="list-pagination__left">
|
|
125
|
+
${page > 1
|
|
126
|
+
? this.renderPageButton(ctx, 1, "Pierwsza strona")
|
|
127
|
+
: ""}
|
|
128
|
+
${page > 1
|
|
129
|
+
? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
|
|
130
|
+
: ""}
|
|
131
|
+
</div>
|
|
132
|
+
<div class="list-pagination__center">
|
|
133
|
+
<select onchange="if (this.value) Turbo.visit(this.value)">
|
|
134
|
+
${Array.from(naturalNumbers(1, totalIems)).map(
|
|
135
|
+
(n) => /* HTML */ `<option
|
|
136
|
+
value="${UrlWithNewParams(
|
|
137
|
+
ctx,
|
|
138
|
+
//eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
139
|
+
this.propsParser.overwriteProp(ctx, {
|
|
140
|
+
page: n,
|
|
141
|
+
} as Partial<Record<string, unknown>>)
|
|
142
|
+
)}"
|
|
143
|
+
${page === n ? "selected" : ""}
|
|
144
|
+
>
|
|
145
|
+
${n}
|
|
146
|
+
</option>`
|
|
147
|
+
)}
|
|
148
|
+
</select>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="list-pagination__right">
|
|
151
|
+
${page < totalIems
|
|
152
|
+
? this.renderPageButton(ctx, page + 1, "Następna strona")
|
|
153
|
+
: ""}
|
|
154
|
+
${page < totalIems
|
|
155
|
+
? this.renderPageButton(ctx, totalIems, "Ostatnia strona")
|
|
156
|
+
: ""}
|
|
157
|
+
</div>
|
|
158
|
+
</div>`;
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
private renderPageButton(ctx: Context, page: number, text: string) {
|
package/src/templates/form.ts
CHANGED
|
@@ -7,8 +7,8 @@ export async function formTemplate(
|
|
|
7
7
|
const rel = curryImportPath(newfilefullpath);
|
|
8
8
|
return `import { Context } from "koa";
|
|
9
9
|
import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen";
|
|
10
|
-
import html from "${rel("src/back/html")}";
|
|
11
|
-
import { Users } from "${rel("src/back/collections/collections")}";
|
|
10
|
+
import html from "${rel("src/back/html.js")}";
|
|
11
|
+
import { Users } from "${rel("src/back/collections/collections.js")}";
|
|
12
12
|
|
|
13
13
|
export const actionName = "${action_name}";
|
|
14
14
|
|
package/src/templates/list.ts
CHANGED
|
@@ -25,9 +25,9 @@ export const listTemplate = async (
|
|
|
25
25
|
import { CollectionItem } from "sealious";
|
|
26
26
|
import { tempstream } from "tempstream";
|
|
27
27
|
import { ${uppercase_collection} } from "${rel(
|
|
28
|
-
"src/back/collections/collections"
|
|
28
|
+
"src/back/collections/collections.js"
|
|
29
29
|
)}";
|
|
30
|
-
import html from "${rel("src/back/html.
|
|
30
|
+
import html from "${rel("src/back/html.js")}";
|
|
31
31
|
import { SealiousItemListPage, BaseListPageFields } from "@sealcode/sealgen";
|
|
32
32
|
|
|
33
33
|
export const actionName = "${action_name}";
|
|
@@ -49,7 +49,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
|
|
|
49
49
|
"${uppercase_collection}",
|
|
50
50
|
tempstream/* HTML */ \`<div>
|
|
51
51
|
<h2>${uppercase_collection} List</h2>
|
|
52
|
-
<table>
|
|
52
|
+
<table class="sealious-list">
|
|
53
53
|
\${this.renderTableHead(ctx, [
|
|
54
54
|
{ field: "id" },
|
|
55
55
|
...Object.keys(Patrons.fields).map((field) => ({
|
|
@@ -6,7 +6,7 @@ export async function multiformTemplate(
|
|
|
6
6
|
): Promise<string> {
|
|
7
7
|
const rel = curryImportPath(newfilefullpath);
|
|
8
8
|
return `import { Context } from "koa";
|
|
9
|
-
import html from "${rel("src/back/html")}";
|
|
9
|
+
import html from "${rel("src/back/html.js")}";
|
|
10
10
|
import { Controls, Fields, Form, FormMessage, Multiform } from "@sealcode/sealgen";
|
|
11
11
|
import { FlatTemplatable } from "tempstream";
|
|
12
12
|
|
package/src/templates/page.ts
CHANGED
|
@@ -7,7 +7,7 @@ export async function pageTemplate(
|
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
8
|
import { tempstream } from "tempstream";
|
|
9
9
|
import { Page } from "@sealcode/sealgen";
|
|
10
|
-
import html from "${rel("src/back/html")}";
|
|
10
|
+
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
|
|
12
12
|
export const actionName = "${action_name}";
|
|
13
13
|
|
|
@@ -3,25 +3,55 @@ import { curryImportPath } from "../utils/import-path";
|
|
|
3
3
|
export function testTemplate(action_name: string, new_file_fullpath: string) {
|
|
4
4
|
const rel = curryImportPath(new_file_fullpath);
|
|
5
5
|
return `import { withProdApp } from "${rel(
|
|
6
|
-
"src/back/test_utils/with-prod-app"
|
|
6
|
+
"src/back/test_utils/with-prod-app.js"
|
|
7
7
|
)}";
|
|
8
8
|
import { LONG_TEST_TIMEOUT, webhintURL } from "${rel(
|
|
9
|
-
"src/back/test_utils/webhint"
|
|
9
|
+
"src/back/test_utils/webhint.js"
|
|
10
10
|
)}";
|
|
11
|
-
import { ${action_name}URL } from "${rel("src/back/routes/urls")}";
|
|
11
|
+
import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
|
|
12
|
+
import { getBrowser } from "${rel("src/test_utils/browser-creator.js")}";
|
|
13
|
+
|
|
14
|
+
describe("${action_name} webhint", () => {
|
|
15
|
+
it(
|
|
16
|
+
"doesn't crash",
|
|
17
|
+
async function () {
|
|
18
|
+
return withProdApp(async ({ base_url, rest_api }) => {
|
|
19
|
+
await rest_api.get(${action_name}URL);
|
|
20
|
+
await webhintURL(base_url + ${action_name}URL);
|
|
21
|
+
// alternatively you can use webhintHTML for faster but less precise scans
|
|
22
|
+
// or for scanning responses of requests that use some form of authorization:
|
|
23
|
+
// const response = await rest_api.get(${action_name}URL);
|
|
24
|
+
// await webhintHTML(response);
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
VERY_LONG_TEST_TIMEOUT
|
|
28
|
+
);
|
|
29
|
+
});
|
|
12
30
|
|
|
13
31
|
describe("${action_name}", () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// await webhintHTML(response);
|
|
23
|
-
});
|
|
32
|
+
let page: Page;
|
|
33
|
+
let browser: Browser;
|
|
34
|
+
let context: BrowserContext;
|
|
35
|
+
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
browser = await getBrowser();
|
|
38
|
+
context = await browser.newContext();
|
|
39
|
+
page = await context.newPage();
|
|
24
40
|
});
|
|
41
|
+
|
|
42
|
+
afterEach(async () => {
|
|
43
|
+
await context.close();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it(
|
|
47
|
+
"works as expected",
|
|
48
|
+
async function () {
|
|
49
|
+
return withProdApp(async ({ base_url }) => {
|
|
50
|
+
await page.goto(base_url + ${action_name}URL);
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
VERY_LONG_TEST_TIMEOUT
|
|
54
|
+
);
|
|
25
55
|
});
|
|
26
56
|
`;
|
|
27
57
|
}
|
|
@@ -8,7 +8,7 @@ export async function statefulPageTemplate(
|
|
|
8
8
|
return `import { BaseContext } from "koa";
|
|
9
9
|
import { tempstream, Templatable } from "tempstream";
|
|
10
10
|
import { StatefulPage } from "@sealcode/sealgen";
|
|
11
|
-
import html from "${rel("src/back/html")}";
|
|
11
|
+
import html from "${rel("src/back/html.js")}";
|
|
12
12
|
|
|
13
13
|
export const actionName = "${action_name}";
|
|
14
14
|
|
package/src/utils/import-path.ts
CHANGED
|
@@ -8,7 +8,7 @@ export function importPath(
|
|
|
8
8
|
): string {
|
|
9
9
|
let result = relative(
|
|
10
10
|
dirname(target_locreq.resolve(project_module_path)),
|
|
11
|
-
target_locreq.resolve(project_target_path).replace(/.ts$/, "")
|
|
11
|
+
target_locreq.resolve(project_target_path).replace(/.ts$/, ".js")
|
|
12
12
|
);
|
|
13
13
|
if (result[0] != ".") {
|
|
14
14
|
result = "./" + result;
|