@sealcode/sealgen 0.8.52 → 0.8.53
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/forms/controls/array.d.ts +1 -1
- package/@types/forms/controls/checkbox-group.d.ts +1 -1
- package/@types/forms/controls/collapsible-field-group.d.ts +1 -1
- package/@types/forms/controls/derived-frame.d.ts +1 -0
- package/@types/forms/controls/dropdown.d.ts +2 -2
- package/@types/forms/controls/form-field-control.d.ts +1 -1
- package/@types/forms/controls/html.d.ts +1 -1
- package/@types/forms/controls/multiple-files.d.ts +1 -1
- package/@types/forms/controls/number.d.ts +1 -1
- package/@types/forms/controls/simple-input.d.ts +1 -1
- package/@types/forms/controls/tickable.d.ts +1 -1
- package/@types/forms/fields/field.d.ts +6 -6
- package/@types/forms/fields/file.d.ts +1 -1
- package/@types/forms/form.d.ts +7 -7
- package/@types/index.d.ts +1 -0
- package/@types/page/list.d.ts +13 -17
- package/@types/page/mountable-with-fields.d.ts +2 -2
- package/@types/page/props-parser.d.ts +1 -1
- package/@types/page/sealious-list.d.ts +18 -0
- package/@types/utils/utils.d.ts +3 -3
- package/lib/add-collection.js +7 -7
- package/lib/add-route.js +7 -7
- package/lib/add-route.test.js +4 -4
- package/lib/build.js +14 -10
- package/lib/components/components.js +5 -1
- package/lib/components/tabs.js +2 -2
- package/lib/components/toggle-modal.js +2 -2
- package/lib/find-scss-includes.js +3 -3
- package/lib/forms/controls/array.js +5 -5
- package/lib/forms/controls/big-radio-group.js +2 -2
- package/lib/forms/controls/checkboxed-list-input.js +3 -3
- package/lib/forms/controls/collapsible-field-group.js +1 -1
- package/lib/forms/controls/controls.js +5 -1
- package/lib/forms/controls/derived-frame.js +3 -3
- package/lib/forms/controls/derived.js +2 -2
- package/lib/forms/controls/dropdown.js +2 -2
- package/lib/forms/controls/editable-collection-subset.js +3 -3
- package/lib/forms/controls/field-group.js +1 -1
- package/lib/forms/controls/file.js +1 -1
- package/lib/forms/controls/hidden-input.js +1 -1
- package/lib/forms/controls/multiple-files.js +5 -5
- package/lib/forms/controls/multiple-photos.js +1 -1
- package/lib/forms/controls/photo.js +1 -1
- package/lib/forms/controls/simple-input.js +2 -2
- package/lib/forms/controls/tickable.js +3 -3
- package/lib/forms/fields/boolean.js +3 -3
- package/lib/forms/fields/checkboxed-list.js +3 -3
- package/lib/forms/fields/enum-multiple.js +3 -3
- package/lib/forms/fields/enum.js +2 -2
- package/lib/forms/fields/field.js +6 -2
- package/lib/forms/fields/file.js +6 -6
- package/lib/forms/fields/number.js +5 -5
- package/lib/forms/fields/pick-from-list.js +1 -1
- package/lib/forms/fields/regexp.js +2 -2
- package/lib/forms/fields/simple-form-field.js +4 -4
- package/lib/forms/form.js +9 -9
- package/lib/forms/form.test.js +12 -12
- package/lib/forms/multiform.js +5 -5
- package/lib/forms/multiform.test.js +26 -26
- package/lib/generate-collections.js +8 -4
- package/lib/generate-routes.js +12 -8
- package/lib/index.js +6 -1
- package/lib/make-env.js +1 -1
- package/lib/make-hidden-inputs.js +3 -3
- package/lib/page/list.js +66 -53
- package/lib/page/mountable-with-fields.js +2 -2
- package/lib/page/page.js +1 -1
- package/lib/page/sealious-list.js +53 -0
- package/lib/page/stateful-page.js +9 -9
- package/lib/templates/form.js +1 -1
- package/lib/templates/list.js +9 -8
- package/lib/templates/multiform.js +1 -1
- package/lib/templates/page.js +1 -1
- package/lib/templates/route-test.js +1 -1
- package/lib/templates/stateful-page.js +1 -1
- package/lib/test_utils/locator_is_visible.js +1 -1
- package/lib/utils/exec.js +1 -1
- package/lib/utils/import-path.js +2 -2
- package/lib/utils/input-wrapper.js +1 -1
- package/lib/utils/list-collections.js +2 -2
- package/lib/utils/prettier.js +6 -2
- package/lib/utils/question.js +1 -1
- package/lib/utils/render-attributes.js +1 -1
- package/lib/utils/utils.js +5 -1
- package/lib/utils/walk.js +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/page/list.ts +70 -67
- package/src/page/sealious-list.ts +76 -0
- package/src/templates/list.ts +7 -6
package/lib/forms/multiform.js
CHANGED
|
@@ -14,8 +14,8 @@ class Multiform extends mountable_with_fields_1.MountableWithFields {
|
|
|
14
14
|
init() {
|
|
15
15
|
super.init();
|
|
16
16
|
for (const [key, form] of Object.entries(this.forms)) {
|
|
17
|
-
if (key !== sanitize_1.attribute(key)) {
|
|
18
|
-
throw new Error(`Form name "${key}" is not url-safe. Try: "${sanitize_1.attribute(key)}"`);
|
|
17
|
+
if (key !== (0, sanitize_1.attribute)(key)) {
|
|
18
|
+
throw new Error(`Form name "${key}" is not url-safe. Try: "${(0, sanitize_1.attribute)(key)}"`);
|
|
19
19
|
}
|
|
20
20
|
form.makeOpenFormTag = () => `<div>`;
|
|
21
21
|
form.makeCloseFormTag = () => `</div>`;
|
|
@@ -53,7 +53,7 @@ class Multiform extends mountable_with_fields_1.MountableWithFields {
|
|
|
53
53
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
54
|
getSubformsToRender(ctx) {
|
|
55
55
|
const requested_frame = ctx.headers["turbo-frame"];
|
|
56
|
-
if (!ts_predicates_1.is(requested_frame, ts_predicates_1.predicates.or(ts_predicates_1.predicates.undefined, ts_predicates_1.predicates.string))) {
|
|
56
|
+
if (!(0, ts_predicates_1.is)(requested_frame, ts_predicates_1.predicates.or(ts_predicates_1.predicates.undefined, ts_predicates_1.predicates.string))) {
|
|
57
57
|
throw new Error("Wrong turbo-frame header value type");
|
|
58
58
|
}
|
|
59
59
|
const forms_to_render = requested_frame && this.forms[requested_frame]
|
|
@@ -82,7 +82,7 @@ class Multiform extends mountable_with_fields_1.MountableWithFields {
|
|
|
82
82
|
return result;
|
|
83
83
|
}
|
|
84
84
|
async render(ctx, messages, prerenderedForms = {}, show_field_errors) {
|
|
85
|
-
return tempstream_1.tempstream /* HTML */ `${this.renderMessages(ctx, {
|
|
85
|
+
return (0, tempstream_1.tempstream /* HTML */) `${this.renderMessages(ctx, {
|
|
86
86
|
raw_values: {},
|
|
87
87
|
messages,
|
|
88
88
|
})}
|
|
@@ -96,7 +96,7 @@ class Multiform extends mountable_with_fields_1.MountableWithFields {
|
|
|
96
96
|
></form>
|
|
97
97
|
${this.getSubformsToRender(ctx).map(([form_name]) => {
|
|
98
98
|
const frame_form_id = this.name + "_" + form_name + "_frame_form";
|
|
99
|
-
return tempstream_1.tempstream /* HTML */ `<turbo-frame
|
|
99
|
+
return (0, tempstream_1.tempstream /* HTML */) `<turbo-frame
|
|
100
100
|
id="${form_name}"
|
|
101
101
|
contains-subform
|
|
102
102
|
subform-id="${frame_form_id}"
|
|
@@ -48,12 +48,12 @@ function multiform_factory(canAccessFun1, canAccessFun2) {
|
|
|
48
48
|
super(...arguments);
|
|
49
49
|
this.name = "multiform_test";
|
|
50
50
|
this.forms = {
|
|
51
|
-
form1: form_test_1.form_factory(canAccessFun1),
|
|
52
|
-
form2: form_test_1.form_factory(canAccessFun2),
|
|
51
|
+
form1: (0, form_test_1.form_factory)(canAccessFun1),
|
|
52
|
+
form2: (0, form_test_1.form_factory)(canAccessFun2),
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
async render(...args) {
|
|
56
|
-
return tempstream_1.tempstream /* HTML */ `<!DOCTYPE html>
|
|
56
|
+
return (0, tempstream_1.tempstream /* HTML */) `<!DOCTYPE html>
|
|
57
57
|
<html>
|
|
58
58
|
<head>
|
|
59
59
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -71,7 +71,7 @@ function multiform_factory(canAccessFun1, canAccessFun2) {
|
|
|
71
71
|
async function tests(js_enabled) {
|
|
72
72
|
let page;
|
|
73
73
|
before(async () => {
|
|
74
|
-
const browser = await browser_creator_1.getBrowser();
|
|
74
|
+
const browser = await (0, browser_creator_1.getBrowser)();
|
|
75
75
|
const context = await browser.newContext({
|
|
76
76
|
javaScriptEnabled: js_enabled,
|
|
77
77
|
});
|
|
@@ -85,18 +85,18 @@ async function tests(js_enabled) {
|
|
|
85
85
|
});
|
|
86
86
|
it("checking whether only one submit handler is run", async () => {
|
|
87
87
|
await page.getByText("Form1 done!").click();
|
|
88
|
-
await utils_1.assertThrowsAsync(async () => {
|
|
88
|
+
await (0, utils_1.assertThrowsAsync)(async () => {
|
|
89
89
|
return page.getByText("Form2 done!").click({ timeout: 500 });
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
92
|
it("checking whether the input in the not submitted form prevails", async () => {
|
|
93
|
-
await test_1.expect(page.getByLabel("name")).toHaveValue("sample2");
|
|
93
|
+
await (0, test_1.expect)(page.getByLabel("name")).toHaveValue("sample2");
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
async function general_form_validation_e2e_tests(js_enabled) {
|
|
97
97
|
let browser;
|
|
98
98
|
let page;
|
|
99
|
-
browser = await browser_creator_1.getBrowser();
|
|
99
|
+
browser = await (0, browser_creator_1.getBrowser)();
|
|
100
100
|
const context = await browser.newContext({
|
|
101
101
|
javaScriptEnabled: js_enabled,
|
|
102
102
|
});
|
|
@@ -107,7 +107,7 @@ async function general_form_validation_e2e_tests(js_enabled) {
|
|
|
107
107
|
await page.getByPlaceholder("password").click();
|
|
108
108
|
await page.getByPlaceholder("password").fill("test");
|
|
109
109
|
await page.locator("#multiform_test_form2_submit").click();
|
|
110
|
-
utils_1.assertThrowsAsync(async () => {
|
|
110
|
+
(0, utils_1.assertThrowsAsync)(async () => {
|
|
111
111
|
page.getByText("Incorrect input").click({ timeout: 500 });
|
|
112
112
|
});
|
|
113
113
|
}
|
|
@@ -115,7 +115,7 @@ async function individual_field_validation_e2e_tests(javaScriptEnabled) {
|
|
|
115
115
|
let browser;
|
|
116
116
|
let page;
|
|
117
117
|
before(async () => {
|
|
118
|
-
browser = await browser_creator_1.getBrowser();
|
|
118
|
+
browser = await (0, browser_creator_1.getBrowser)();
|
|
119
119
|
const context = await browser.newContext({
|
|
120
120
|
javaScriptEnabled,
|
|
121
121
|
});
|
|
@@ -132,7 +132,7 @@ async function individual_field_validation_e2e_tests(javaScriptEnabled) {
|
|
|
132
132
|
await page.getByPlaceholder("text").click();
|
|
133
133
|
await page.getByPlaceholder("text").fill("yes@an.email");
|
|
134
134
|
await page.locator("#multiform_test_form1_submit").click();
|
|
135
|
-
utils_1.assertThrowsAsync(async () => {
|
|
135
|
+
(0, utils_1.assertThrowsAsync)(async () => {
|
|
136
136
|
return page.getByText("Please enter a proper email address").click({ timeout: 500 });
|
|
137
137
|
});
|
|
138
138
|
});
|
|
@@ -143,14 +143,14 @@ describe("multiform test", () => {
|
|
|
143
143
|
before(async () => {
|
|
144
144
|
const app = new koa_1.default();
|
|
145
145
|
const router = new router_1.default();
|
|
146
|
-
mount_1.mount(router, "/", new (class extends multiform_1.Multiform {
|
|
146
|
+
(0, mount_1.mount)(router, "/", new (class extends multiform_1.Multiform {
|
|
147
147
|
constructor() {
|
|
148
148
|
super(...arguments);
|
|
149
149
|
this.name = "multiform_test";
|
|
150
150
|
this.forms = { form1, form2 };
|
|
151
151
|
}
|
|
152
152
|
async render(ctx, messages, prerenderedForms, show_field_errors = true) {
|
|
153
|
-
return tempstream_1.tempstream /* HTML */ `<!DOCTYPE html>
|
|
153
|
+
return (0, tempstream_1.tempstream /* HTML */) `<!DOCTYPE html>
|
|
154
154
|
<html>
|
|
155
155
|
<head>
|
|
156
156
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -180,14 +180,14 @@ describe("multiform test", () => {
|
|
|
180
180
|
before(async () => {
|
|
181
181
|
const app = new koa_1.default();
|
|
182
182
|
const router = new router_1.default();
|
|
183
|
-
mount_1.mount(router, "/", multiform_factory(async (ctx) => {
|
|
183
|
+
(0, mount_1.mount)(router, "/", multiform_factory(async (ctx) => {
|
|
184
184
|
return { canAccess: true, message: "" };
|
|
185
185
|
}, async (ctx) => {
|
|
186
186
|
return { canAccess: true, message: "" };
|
|
187
187
|
}), true);
|
|
188
188
|
app.use(router.routes()).use(router.allowedMethods());
|
|
189
189
|
server = app.listen(8080);
|
|
190
|
-
const browser = await browser_creator_1.getBrowser();
|
|
190
|
+
const browser = await (0, browser_creator_1.getBrowser)();
|
|
191
191
|
const context = await browser.newContext();
|
|
192
192
|
page = await context.newPage();
|
|
193
193
|
});
|
|
@@ -218,14 +218,14 @@ describe("multiform test", () => {
|
|
|
218
218
|
before(async () => {
|
|
219
219
|
const app = new koa_1.default();
|
|
220
220
|
const router = new router_1.default();
|
|
221
|
-
mount_1.mount(router, "/", multiform_factory(async (ctx) => {
|
|
221
|
+
(0, mount_1.mount)(router, "/", multiform_factory(async (ctx) => {
|
|
222
222
|
return { canAccess: false, message: "" };
|
|
223
223
|
}, async (ctx) => {
|
|
224
224
|
return { canAccess: false, message: "" };
|
|
225
225
|
}), true);
|
|
226
226
|
app.use(router.routes()).use(router.allowedMethods());
|
|
227
227
|
server = app.listen(8080);
|
|
228
|
-
const browser = await browser_creator_1.getBrowser();
|
|
228
|
+
const browser = await (0, browser_creator_1.getBrowser)();
|
|
229
229
|
const context = await browser.newContext();
|
|
230
230
|
page = await context.newPage();
|
|
231
231
|
});
|
|
@@ -234,7 +234,7 @@ describe("multiform test", () => {
|
|
|
234
234
|
});
|
|
235
235
|
it("check wether forms didnt render", async () => {
|
|
236
236
|
await page.goto("http://localhost:8080");
|
|
237
|
-
await utils_1.assertThrowsAsync(async () => {
|
|
237
|
+
await (0, utils_1.assertThrowsAsync)(async () => {
|
|
238
238
|
return page
|
|
239
239
|
.locator("#form1")
|
|
240
240
|
.getByText("This is a test:")
|
|
@@ -257,14 +257,14 @@ describe("multiform test", () => {
|
|
|
257
257
|
before(async () => {
|
|
258
258
|
const app = new koa_1.default();
|
|
259
259
|
const router = new router_1.default();
|
|
260
|
-
mount_1.mount(router, "/", multiform_factory(async (ctx) => {
|
|
260
|
+
(0, mount_1.mount)(router, "/", multiform_factory(async (ctx) => {
|
|
261
261
|
return { canAccess: true, message: "" };
|
|
262
262
|
}, async (ctx) => {
|
|
263
263
|
return { canAccess: false, message: "" };
|
|
264
264
|
}), true);
|
|
265
265
|
app.use(router.routes()).use(router.allowedMethods());
|
|
266
266
|
server = app.listen(8080);
|
|
267
|
-
const browser = await browser_creator_1.getBrowser();
|
|
267
|
+
const browser = await (0, browser_creator_1.getBrowser)();
|
|
268
268
|
const context = await browser.newContext({});
|
|
269
269
|
page = await context.newPage();
|
|
270
270
|
});
|
|
@@ -288,7 +288,7 @@ describe("multiform test", () => {
|
|
|
288
288
|
});
|
|
289
289
|
it("check wether form2 does not render", async () => {
|
|
290
290
|
await page.goto("http://localhost:8080");
|
|
291
|
-
await utils_1.assertThrowsAsync(async () => {
|
|
291
|
+
await (0, utils_1.assertThrowsAsync)(async () => {
|
|
292
292
|
return page
|
|
293
293
|
.locator("#form2")
|
|
294
294
|
.getByText("This is a test:")
|
|
@@ -314,7 +314,7 @@ describe("multiform test", () => {
|
|
|
314
314
|
before(async () => {
|
|
315
315
|
const app = new koa_1.default();
|
|
316
316
|
const router = new router_1.default();
|
|
317
|
-
mount_1.mount(router, "/", new (class extends multiform_1.Multiform {
|
|
317
|
+
(0, mount_1.mount)(router, "/", new (class extends multiform_1.Multiform {
|
|
318
318
|
constructor() {
|
|
319
319
|
super(...arguments);
|
|
320
320
|
this.name = "multiform_test";
|
|
@@ -343,11 +343,11 @@ describe("multiform test", () => {
|
|
|
343
343
|
return { valid: true, error: "" };
|
|
344
344
|
}
|
|
345
345
|
})(),
|
|
346
|
-
form2: form_test_1.form_factory(),
|
|
346
|
+
form2: (0, form_test_1.form_factory)(),
|
|
347
347
|
};
|
|
348
348
|
}
|
|
349
349
|
async render(...args) {
|
|
350
|
-
return tempstream_1.tempstream /* HTML */ `<!DOCTYPE html>
|
|
350
|
+
return (0, tempstream_1.tempstream /* HTML */) `<!DOCTYPE html>
|
|
351
351
|
<html>
|
|
352
352
|
<head>
|
|
353
353
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -378,7 +378,7 @@ describe("multiform test", () => {
|
|
|
378
378
|
const fields = {
|
|
379
379
|
text: new __1.Fields.EmailField(true),
|
|
380
380
|
};
|
|
381
|
-
mount_1.mount(router, "/", new (class extends multiform_1.Multiform {
|
|
381
|
+
(0, mount_1.mount)(router, "/", new (class extends multiform_1.Multiform {
|
|
382
382
|
constructor() {
|
|
383
383
|
super(...arguments);
|
|
384
384
|
this.name = "multiform_test";
|
|
@@ -399,11 +399,11 @@ describe("multiform test", () => {
|
|
|
399
399
|
return;
|
|
400
400
|
}
|
|
401
401
|
})(),
|
|
402
|
-
form2: form_test_1.form_factory(),
|
|
402
|
+
form2: (0, form_test_1.form_factory)(),
|
|
403
403
|
};
|
|
404
404
|
}
|
|
405
405
|
async render(...args) {
|
|
406
|
-
return tempstream_1.tempstream /* HTML */ `<!DOCTYPE html>
|
|
406
|
+
return (0, tempstream_1.tempstream /* HTML */) `<!DOCTYPE html>
|
|
407
407
|
<html>
|
|
408
408
|
<head>
|
|
409
409
|
<title>Multiform Test - Sealgen</title>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -28,14 +32,14 @@ const prettier = __importStar(require("prettier"));
|
|
|
28
32
|
const fs_1 = require("fs");
|
|
29
33
|
const ts_predicates_1 = require("@sealcode/ts-predicates");
|
|
30
34
|
const prettier_1 = require("./utils/prettier");
|
|
31
|
-
const target_locreq = locreq_1.default(process.cwd());
|
|
35
|
+
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
32
36
|
async function extractCollectionClassname(full_file_path) {
|
|
33
37
|
const file_content = await fs_1.promises.readFile(full_file_path, "utf-8");
|
|
34
38
|
const result = /export default class (\w+)/.exec(file_content);
|
|
35
39
|
if (result === null) {
|
|
36
40
|
throw new Error("Missing 'export default class' statement?");
|
|
37
41
|
}
|
|
38
|
-
return ts_predicates_1.assertType(result[1], ts_predicates_1.predicates.string, `Missing export default class in '${full_file_path}'?`);
|
|
42
|
+
return (0, ts_predicates_1.assertType)(result[1], ts_predicates_1.predicates.string, `Missing export default class in '${full_file_path}'?`);
|
|
39
43
|
}
|
|
40
44
|
async function generateCollections() {
|
|
41
45
|
const collections_dir = target_locreq.resolve("src/back/collections");
|
|
@@ -70,7 +74,7 @@ ${file_data
|
|
|
70
74
|
.map(({ class_name, urlname }) => ` "${urlname}": ${class_name},`)
|
|
71
75
|
.join("\n")}
|
|
72
76
|
};`;
|
|
73
|
-
await fs_1.promises.writeFile(target_locreq.resolve("src/back/collections/collections.ts"), prettier.format(content, await prettier_1.getPrettierConfig()));
|
|
77
|
+
await fs_1.promises.writeFile(target_locreq.resolve("src/back/collections/collections.ts"), prettier.format(content, await (0, prettier_1.getPrettierConfig)()));
|
|
74
78
|
// eslint-disable-next-line no-console
|
|
75
79
|
console.log("Successfuly generated new src/back/collections/collections.ts file");
|
|
76
80
|
}
|
package/lib/generate-routes.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -32,14 +36,14 @@ const import_path_1 = require("./utils/import-path");
|
|
|
32
36
|
const ts_predicates_1 = require("@sealcode/ts-predicates");
|
|
33
37
|
const escape_url_params_1 = require("./utils/escape-url-params");
|
|
34
38
|
const prettier_1 = require("./utils/prettier");
|
|
35
|
-
const target_locreq = locreq_1.default(process.cwd());
|
|
39
|
+
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
36
40
|
async function extractActionName(full_file_path) {
|
|
37
41
|
const file_content = await fs_1.promises.readFile(full_file_path, "utf-8");
|
|
38
42
|
const result = /export const actionName = "(\w+)"/.exec(file_content);
|
|
39
43
|
if (result === null) {
|
|
40
44
|
throw new Error("Missing 'export const actionName' statement?");
|
|
41
45
|
}
|
|
42
|
-
return ts_predicates_1.assertType(result[1], ts_predicates_1.predicates.string, "Missing export default class?");
|
|
46
|
+
return (0, ts_predicates_1.assertType)(result[1], ts_predicates_1.predicates.string, "Missing export default class?");
|
|
43
47
|
}
|
|
44
48
|
function generateURL(actionName, url) {
|
|
45
49
|
const parts = url.split("/");
|
|
@@ -60,7 +64,7 @@ function generateURL(actionName, url) {
|
|
|
60
64
|
${actionName}URL.rawURL = "${url}";`;
|
|
61
65
|
}
|
|
62
66
|
async function generateRoutes() {
|
|
63
|
-
const files = await Promise.all((await walk_1.walkDir(target_locreq.resolve("src/back/routes")))
|
|
67
|
+
const files = await Promise.all((await (0, walk_1.walkDir)(target_locreq.resolve("src/back/routes")))
|
|
64
68
|
.filter((f) => f.endsWith(".page.ts") ||
|
|
65
69
|
f.endsWith(".form.ts") ||
|
|
66
70
|
f.endsWith(".multiform.ts") ||
|
|
@@ -71,8 +75,8 @@ async function generateRoutes() {
|
|
|
71
75
|
.map(async (fullpath) => ({
|
|
72
76
|
fullpath,
|
|
73
77
|
actionName: await extractActionName(fullpath),
|
|
74
|
-
url: escape_url_params_1.unescape_url_params("/" +
|
|
75
|
-
path_1.relative(target_locreq.resolve("src/back/routes"), fullpath).replace(/\..+/, "") +
|
|
78
|
+
url: (0, escape_url_params_1.unescape_url_params)("/" +
|
|
79
|
+
(0, path_1.relative)(target_locreq.resolve("src/back/routes"), fullpath).replace(/\..+/, "") +
|
|
76
80
|
"/" // trailing slash is important here, as it enables to use the entire path while building relative URLs. For example, while visiting /users/123, the path ./add-photo leads to /users/add-photo. While visiting /users/123/ (note the trailing slash), the path ./add-photo leads to /users/123/add-photo
|
|
77
81
|
),
|
|
78
82
|
})));
|
|
@@ -83,7 +87,7 @@ import { mount } from "@sealcode/sealgen";
|
|
|
83
87
|
import * as URLs from "./urls"
|
|
84
88
|
|
|
85
89
|
${files
|
|
86
|
-
.map(({ actionName, fullpath }) => `import { default as ${actionName} } from "${import_path_1.importPath(target_locreq.resolve("src/back/routes/routes.ts"), fullpath)}";`)
|
|
90
|
+
.map(({ actionName, fullpath }) => `import { default as ${actionName} } from "${(0, import_path_1.importPath)(target_locreq.resolve("src/back/routes/routes.ts"), fullpath)}";`)
|
|
87
91
|
.join("\n")}
|
|
88
92
|
|
|
89
93
|
export default function mountAutoRoutes(router: Router) {
|
|
@@ -96,7 +100,7 @@ ${files
|
|
|
96
100
|
.map(({ actionName, url }) => generateURL(actionName, url))
|
|
97
101
|
.join("\n")}
|
|
98
102
|
`;
|
|
99
|
-
const prettier_config = await prettier_1.getPrettierConfig();
|
|
103
|
+
const prettier_config = await (0, prettier_1.getPrettierConfig)();
|
|
100
104
|
await fs_1.promises.writeFile(target_locreq.resolve("src/back/routes/routes.ts"), prettier.format(routes_content, prettier_config));
|
|
101
105
|
await fs_1.promises.writeFile(target_locreq.resolve("src/back/routes/urls.ts"), prettier.format(urls_content, prettier_config));
|
|
102
106
|
// eslint-disable-next-line no-console
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -32,6 +36,7 @@ __exportStar(require("./forms/form"), exports);
|
|
|
32
36
|
__exportStar(require("./page/props-parser"), exports);
|
|
33
37
|
__exportStar(require("./utils/utils"), exports);
|
|
34
38
|
__exportStar(require("./page/list"), exports);
|
|
39
|
+
__exportStar(require("./page/sealious-list"), exports);
|
|
35
40
|
__exportStar(require("./utils/translate"), exports);
|
|
36
41
|
exports.sanitize = __importStar(require("./sanitize"));
|
|
37
42
|
__exportStar(require("./forms/multiform"), exports);
|
package/lib/make-env.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.makeEnv = void 0;
|
|
|
7
7
|
const os_1 = __importDefault(require("os"));
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
9
|
const locreq_1 = __importDefault(require("locreq"));
|
|
10
|
-
const target_locreq = locreq_1.default(process.cwd());
|
|
10
|
+
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
11
11
|
async function makeEnv() {
|
|
12
12
|
const { uid, gid } = os_1.default.userInfo();
|
|
13
13
|
const content = `USER_ID=${uid}
|
|
@@ -4,14 +4,14 @@ exports.makeHiddenInputs = void 0;
|
|
|
4
4
|
const tempstream_1 = require("tempstream");
|
|
5
5
|
const sanitize_1 = require("./sanitize");
|
|
6
6
|
function makeHiddenInputs(ctx, fields, values, fields_to_skip) {
|
|
7
|
-
return tempstream_1.tempstream `${Object.entries(fields)
|
|
7
|
+
return (0, tempstream_1.tempstream) `${Object.entries(fields)
|
|
8
8
|
.filter(([key]) => !fields_to_skip.includes(key))
|
|
9
|
-
.map(([key, field]) => tempstream_1.tempstream /* HTML */ `<input
|
|
9
|
+
.map(([key, field]) => (0, tempstream_1.tempstream /* HTML */) `<input
|
|
10
10
|
type="hidden"
|
|
11
11
|
name="${key}"
|
|
12
12
|
value="${field
|
|
13
13
|
.getValue(ctx, values)
|
|
14
|
-
.then((r) => sanitize_1.attribute(JSON.stringify(r.raw) || ""))}"
|
|
14
|
+
.then((r) => (0, sanitize_1.attribute)(JSON.stringify(r.raw) || ""))}"
|
|
15
15
|
/>`)}`;
|
|
16
16
|
}
|
|
17
17
|
exports.makeHiddenInputs = makeHiddenInputs;
|
package/lib/page/list.js
CHANGED
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
6
|
+
exports.ListPage = exports.BaseListPageFields = exports.BasePagePropsShape = void 0;
|
|
4
7
|
const tempstream_1 = require("tempstream");
|
|
5
|
-
const access_control_1 = require("./access-control");
|
|
6
8
|
const page_1 = require("./page");
|
|
7
9
|
const field_1 = require("../forms/fields/field");
|
|
8
10
|
const utils_1 = require("../utils/utils");
|
|
9
11
|
const make_hidden_inputs_1 = require("../make-hidden-inputs");
|
|
12
|
+
const qs_1 = __importDefault(require("qs"));
|
|
10
13
|
exports.BasePagePropsShape = {};
|
|
11
14
|
exports.BaseListPageFields = {
|
|
12
15
|
page: new field_1.NumberField(false, 1),
|
|
13
16
|
itemsPerPage: new field_1.NumberField(false, 12),
|
|
17
|
+
sort: new field_1.SimpleFormField(false),
|
|
14
18
|
};
|
|
19
|
+
const SORT_SEPARATOR = ":";
|
|
20
|
+
function decodeSort(s) {
|
|
21
|
+
if (typeof s !== "string" || !s.includes(SORT_SEPARATOR)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
let order = s.split(SORT_SEPARATOR)[1];
|
|
25
|
+
const field = s.split(SORT_SEPARATOR)[0];
|
|
26
|
+
if (order !== "asc" && order !== "desc") {
|
|
27
|
+
order = "asc";
|
|
28
|
+
return {
|
|
29
|
+
field,
|
|
30
|
+
order: order,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return { field, order };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function encodeSort(field, order) {
|
|
38
|
+
return [field, order].join(SORT_SEPARATOR);
|
|
39
|
+
}
|
|
15
40
|
class ListPage extends page_1.Page {
|
|
16
41
|
constructor() {
|
|
17
42
|
super(...arguments);
|
|
@@ -25,7 +50,7 @@ class ListPage extends page_1.Page {
|
|
|
25
50
|
}
|
|
26
51
|
}
|
|
27
52
|
renderListContainer(_, content) {
|
|
28
|
-
return tempstream_1.tempstream `<div>${content}</div>`;
|
|
53
|
+
return (0, tempstream_1.tempstream) `<div>${content}</div>`;
|
|
29
54
|
}
|
|
30
55
|
async getPaginationConfig(ctx) {
|
|
31
56
|
const values = await this.extractRawValues(ctx);
|
|
@@ -39,28 +64,28 @@ class ListPage extends page_1.Page {
|
|
|
39
64
|
}
|
|
40
65
|
const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
|
|
41
66
|
const items_promise = this.getItems(ctx, page, itemsPerPage, values);
|
|
42
|
-
return tempstream_1.tempstream `${(items
|
|
67
|
+
return (0, tempstream_1.tempstream) `${(items
|
|
43
68
|
? Promise.resolve(items)
|
|
44
69
|
: items_promise).then((items) => items.map((item, index) => this.renderItem(ctx, item, index)))}`;
|
|
45
70
|
}
|
|
46
71
|
async render(ctx) {
|
|
47
72
|
const values = await this.extractRawValues(ctx);
|
|
48
|
-
return tempstream_1.tempstream `${this.renderPagination(ctx, values)}
|
|
73
|
+
return (0, tempstream_1.tempstream) `${this.renderPagination(ctx, values)}
|
|
49
74
|
${this.renderFilters(ctx)}
|
|
50
75
|
${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
51
76
|
}
|
|
52
77
|
async renderPagination(ctx, values) {
|
|
53
78
|
const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
|
|
54
79
|
const totalIems = await this.getTotalPages(ctx, itemsPerPage, values);
|
|
55
|
-
return tempstream_1.tempstream /* HTML */ `<center>
|
|
80
|
+
return (0, tempstream_1.tempstream /* HTML */) `<center>
|
|
56
81
|
${page > 1 ? this.renderPageButton(ctx, 1, "Pierwsza strona") : ""}
|
|
57
82
|
${page > 1
|
|
58
83
|
? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
|
|
59
84
|
: ""}
|
|
60
85
|
|
|
61
86
|
<select onchange="if (this.value) Turbo.visit(this.value)">
|
|
62
|
-
${Array.from(utils_1.naturalNumbers(1, totalIems)).map((n) => /* HTML */ `<option
|
|
63
|
-
value="${utils_1.UrlWithNewParams(ctx,
|
|
87
|
+
${Array.from((0, utils_1.naturalNumbers)(1, totalIems)).map((n) => /* HTML */ `<option
|
|
88
|
+
value="${(0, utils_1.UrlWithNewParams)(ctx,
|
|
64
89
|
//eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
65
90
|
this.propsParser.overwriteProp(ctx, {
|
|
66
91
|
page: n,
|
|
@@ -80,7 +105,7 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
|
80
105
|
}
|
|
81
106
|
renderPageButton(ctx, page, text) {
|
|
82
107
|
return /* HTML */ `<a
|
|
83
|
-
href="${utils_1.UrlWithNewParams(ctx,
|
|
108
|
+
href="${(0, utils_1.UrlWithNewParams)(ctx,
|
|
84
109
|
//eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
85
110
|
this.propsParser.overwriteProp(ctx, {
|
|
86
111
|
page,
|
|
@@ -98,10 +123,21 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
|
98
123
|
}
|
|
99
124
|
return filter;
|
|
100
125
|
}
|
|
126
|
+
async getSort(ctx) {
|
|
127
|
+
const { sort } = await this.extractRawValues(ctx);
|
|
128
|
+
return decodeSort(sort);
|
|
129
|
+
}
|
|
130
|
+
makeSortLink(ctx, field, order) {
|
|
131
|
+
const url = new URL(ctx.url, "https://example.com");
|
|
132
|
+
const params = qs_1.default.parse(url.search.slice(1));
|
|
133
|
+
params.sort = encodeSort(field, order);
|
|
134
|
+
url.search = qs_1.default.stringify(params);
|
|
135
|
+
return url.pathname + url.search;
|
|
136
|
+
}
|
|
101
137
|
async renderFilters(ctx) {
|
|
102
138
|
const values = await this.extractRawValues(ctx);
|
|
103
|
-
return tempstream_1.tempstream /* HTML */ `<form method="GET">
|
|
104
|
-
${make_hidden_inputs_1.makeHiddenInputs(ctx, this.fields, values, [
|
|
139
|
+
return (0, tempstream_1.tempstream /* HTML */) `<form method="GET">
|
|
140
|
+
${(0, make_hidden_inputs_1.makeHiddenInputs)(ctx, this.fields, values, [
|
|
105
141
|
"page",
|
|
106
142
|
...Object.values(this.filterFields).map((f) => f.name),
|
|
107
143
|
])}
|
|
@@ -111,48 +147,25 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
|
|
|
111
147
|
})}
|
|
112
148
|
</form>`;
|
|
113
149
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const filters = await this.getFilterValues(ctx);
|
|
133
|
-
for (const key in filters) {
|
|
134
|
-
if (filters[key] === undefined || filters[key] == "") {
|
|
135
|
-
delete filters[key];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
if (Object.keys(filters).length) {
|
|
139
|
-
list.filter(filters);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async makeQuery(ctx) {
|
|
143
|
-
return this.collection.list(await this.getContextForList(ctx));
|
|
144
|
-
}
|
|
145
|
-
async getItems(ctx, page, itemsPerPage) {
|
|
146
|
-
const query = await this.makeQuery(ctx);
|
|
147
|
-
await this.addFilter(ctx, query);
|
|
148
|
-
const { items } = await query
|
|
149
|
-
.paginate({ items: itemsPerPage, page })
|
|
150
|
-
.fetch();
|
|
151
|
-
return items;
|
|
152
|
-
}
|
|
153
|
-
async renderItem(_, item, index) {
|
|
154
|
-
return `<div>${item.id}</div>`;
|
|
150
|
+
renderHeading(ctx, field, label = field) {
|
|
151
|
+
const current_sort = decodeSort(qs_1.default.parse(new URL(ctx.url, "https://www.example.com").search.slice(1))["sort"]);
|
|
152
|
+
const current_order = current_sort?.field == field ? current_sort.order : null;
|
|
153
|
+
const order = current_order == "desc" ? "asc" : "desc";
|
|
154
|
+
return /* HTML */ `<th>
|
|
155
|
+
<a href="${this.makeSortLink(ctx, field, order)}"
|
|
156
|
+
>${label}
|
|
157
|
+
${(current_order && (current_order == "asc" ? "↑" : "↓")) ||
|
|
158
|
+
""}</a
|
|
159
|
+
>
|
|
160
|
+
</th>`;
|
|
161
|
+
}
|
|
162
|
+
renderTableHead(ctx, fields) {
|
|
163
|
+
return (0, tempstream_1.tempstream /* HTML */) `<thead>
|
|
164
|
+
<tr>
|
|
165
|
+
${fields.map(({ label, field }) => this.renderHeading(ctx, field, label))}
|
|
166
|
+
</tr>
|
|
167
|
+
</thead>`;
|
|
155
168
|
}
|
|
156
169
|
}
|
|
157
|
-
exports.
|
|
170
|
+
exports.ListPage = ListPage;
|
|
158
171
|
//# sourceMappingURL=list.js.map
|
|
@@ -52,13 +52,13 @@ class MountableWithFields extends mountable_1.Mountable {
|
|
|
52
52
|
return { valid, field_errors, form_messages };
|
|
53
53
|
}
|
|
54
54
|
renderControls(fctx) {
|
|
55
|
-
return tempstream_1.tempstream /* HTML */ `${this.controls.map((control) => control.render(fctx))}`;
|
|
55
|
+
return (0, tempstream_1.tempstream /* HTML */) `${this.controls.map((control) => control.render(fctx))}`;
|
|
56
56
|
}
|
|
57
57
|
async renderError(_, error) {
|
|
58
58
|
return error.message;
|
|
59
59
|
}
|
|
60
60
|
renderMessages(_, data) {
|
|
61
|
-
return tempstream_1.tempstream /* HTML */ `<div class="form-messages">
|
|
61
|
+
return (0, tempstream_1.tempstream /* HTML */) `<div class="form-messages">
|
|
62
62
|
${data.messages.map((message) => `<div class="form-message form-message--${message.type}">${message.text}</div>`)}
|
|
63
63
|
</div>`;
|
|
64
64
|
}
|
package/lib/page/page.js
CHANGED
|
@@ -20,7 +20,7 @@ class Page extends mountable_with_fields_1.MountableWithFields {
|
|
|
20
20
|
return { canAccess: true, message: "" };
|
|
21
21
|
}
|
|
22
22
|
async renderError(_, error) {
|
|
23
|
-
return tempstream_1.tempstream /* HTML */ `<div>${error.message}</div>`;
|
|
23
|
+
return (0, tempstream_1.tempstream /* HTML */) `<div>${error.message}</div>`;
|
|
24
24
|
}
|
|
25
25
|
async extractRawValues(ctx) {
|
|
26
26
|
return this.propsParser.decode(ctx) || {};
|