@sealcode/sealgen 0.7.12 → 0.7.14
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/components/tabs.d.ts +1 -1
- package/@types/forms/fields/email.d.ts +6 -0
- package/@types/forms/fields/field.d.ts +2 -0
- package/@types/forms/fields/regexp.d.ts +15 -0
- package/@types/forms/form.d.ts +2 -1
- package/lib/components/tabs.js +5 -6
- package/lib/components/tabs.js.map +1 -1
- package/lib/forms/fields/email.js +13 -0
- package/lib/forms/fields/email.js.map +1 -0
- package/lib/forms/fields/field.js +2 -0
- package/lib/forms/fields/field.js.map +1 -1
- package/lib/forms/fields/regexp.js +43 -0
- package/lib/forms/fields/regexp.js.map +1 -0
- package/lib/forms/form.js +7 -3
- package/lib/forms/form.js.map +1 -1
- package/lib/mount.js +15 -5
- package/lib/mount.js.map +1 -1
- package/package.json +1 -1
- package/src/components/tabs.ts +7 -9
- package/src/forms/fields/email.ts +16 -0
- package/src/forms/fields/field.ts +2 -0
- package/src/forms/fields/regexp.ts +51 -0
- package/src/forms/form.ts +12 -3
- package/src/mount.ts +18 -7
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FlatTemplatable } from "tempstream";
|
|
2
|
-
export declare function tabs(tabs: Record<string,
|
|
2
|
+
export declare function tabs(tabs: Record<string, FlatTemplatable>, selected_tab_style?: string, selected_index?: number): FlatTemplatable;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Context } from "koa";
|
|
2
|
+
import { FormDataValue } from "../form";
|
|
3
|
+
import { FieldParseResult, FormField } from "./field";
|
|
4
|
+
export declare class RegExpField extends FormField<string> {
|
|
5
|
+
regexp: RegExp;
|
|
6
|
+
error_message: string;
|
|
7
|
+
default_value: string;
|
|
8
|
+
constructor(required: boolean | undefined, regexp: RegExp, error_message: string, default_value?: string);
|
|
9
|
+
isValueValid(_: Context, value: unknown): Promise<{
|
|
10
|
+
valid: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
}>;
|
|
13
|
+
parse(_: Context, value: FormDataValue): Promise<FieldParseResult<string>>;
|
|
14
|
+
getEmptyValue(): string;
|
|
15
|
+
}
|
package/@types/forms/form.d.ts
CHANGED
|
@@ -38,7 +38,8 @@ export declare abstract class Form<F extends Fields> extends MountableWithFields
|
|
|
38
38
|
renderError(_: Context, error: PageErrorMessage): Promise<FlatTemplatable>;
|
|
39
39
|
makeSubmitButton(): FlatTemplatable;
|
|
40
40
|
render(ctx: Context, data: FormData): Promise<FlatTemplatable>;
|
|
41
|
-
|
|
41
|
+
makeFormClasses(_ctx: Context): Promise<string[]>;
|
|
42
|
+
makeOpenFormTag(ctx: Context): FlatTemplatable;
|
|
42
43
|
makeCloseFormTag(): FlatTemplatable;
|
|
43
44
|
onValuesInvalid(ctx: Context, form_messages: FormMessage[]): Promise<FormReaction>;
|
|
44
45
|
onError(ctx: Context, data: FormData, error: unknown): Promise<FormReaction>;
|
package/lib/components/tabs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tabs = void 0;
|
|
4
|
+
const tempstream_1 = require("tempstream");
|
|
4
5
|
function name_to_id(str) {
|
|
5
6
|
return str.replace(/\W/g, "-");
|
|
6
7
|
}
|
|
@@ -51,7 +52,7 @@ const style = /* HTML */ `<style>
|
|
|
51
52
|
}
|
|
52
53
|
</style>`;
|
|
53
54
|
function tabs(tabs, selected_tab_style = "font-weight: bold;", selected_index = 0) {
|
|
54
|
-
return /* HTML */ `${style}
|
|
55
|
+
return /* HTML */ tempstream_1.tempstream `${style}
|
|
55
56
|
${Object.keys(tabs)
|
|
56
57
|
.map((tab_title, index) => {
|
|
57
58
|
const id = name_to_id(tab_title);
|
|
@@ -68,10 +69,9 @@ function tabs(tabs, selected_tab_style = "font-weight: bold;", selected_index =
|
|
|
68
69
|
</label>`;
|
|
69
70
|
})
|
|
70
71
|
.join("\n")}
|
|
71
|
-
${Object.entries(tabs)
|
|
72
|
-
.map(([title, content]) => {
|
|
72
|
+
${Object.entries(tabs).map(([title, content]) => {
|
|
73
73
|
const id = name_to_id(title);
|
|
74
|
-
return /* HTML */
|
|
74
|
+
return /* HTML */ tempstream_1.tempstream `<div class="tab-label tab-label--mobile">
|
|
75
75
|
${title}
|
|
76
76
|
</div>
|
|
77
77
|
<div class="tab-content tab-content--${id}">${content}</div>
|
|
@@ -86,8 +86,7 @@ function tabs(tabs, selected_tab_style = "font-weight: bold;", selected_index =
|
|
|
86
86
|
${selected_tab_style}
|
|
87
87
|
}
|
|
88
88
|
</style>`;
|
|
89
|
-
})
|
|
90
|
-
.join("\n")}`;
|
|
89
|
+
})}`;
|
|
91
90
|
}
|
|
92
91
|
exports.tabs = tabs;
|
|
93
92
|
//# sourceMappingURL=tabs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/components/tabs.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/components/tabs.ts"],"names":[],"mappings":";;;AAAA,2CAAyD;AAEzD,SAAS,UAAU,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,KAAK,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA6ChB,CAAC;AAEV,SAAgB,IAAI,CACnB,IAAqC,EACrC,kBAAkB,GAAG,oBAAoB,EACzC,cAAc,GAAG,CAAC;IAElB,OAAO,UAAU,CAAC,uBAAU,CAAA,GAAG,KAAK;GAClC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;SACjB,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;QACzB,MAAM,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACjC,OAAO,UAAU,CAAC;;;WAGV,EAAE;yBACY,EAAE;;OAEpB,cAAc,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;;yCAEN,EAAE,UAAU,EAAE;OAChD,SAAS;aACH,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC;GACV,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE;QAC/C,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,UAAU,CAAC,uBAAU,CAAA;OACvB,KAAK;;2CAE+B,EAAE,KAAK,OAAO;;mBAEtC,EAAE,oBAAoB,EAAE;;;mBAGxB,EAAE,4BAA4B,EAAE;;;mBAGhC,EAAE,+BAA+B,EAAE;QAC9C,kBAAkB;;aAEb,CAAC;IACb,CAAC,CAAC,EAAE,CAAC;AACN,CAAC;AAxCD,oBAwCC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmailField = void 0;
|
|
4
|
+
const regexp_1 = require("./regexp");
|
|
5
|
+
class EmailField extends regexp_1.RegExpField {
|
|
6
|
+
constructor(required = false, error_message = "Please enter a proper email address", default_value = "") {
|
|
7
|
+
super(required, /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, error_message, default_value);
|
|
8
|
+
this.error_message = error_message;
|
|
9
|
+
this.default_value = default_value;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.EmailField = EmailField;
|
|
13
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../../../src/forms/fields/email.ts"],"names":[],"mappings":";;;AAAA,qCAAuC;AAEvC,MAAa,UAAW,SAAQ,oBAAW;IAC1C,YACC,QAAQ,GAAG,KAAK,EACT,gBAAgB,qCAAqC,EACrD,gBAAgB,EAAE;QAEzB,KAAK,CACJ,QAAQ,EACR,sJAAsJ,EACtJ,aAAa,EACb,aAAa,CACb,CAAC;QARK,kBAAa,GAAb,aAAa,CAAwC;QACrD,kBAAa,GAAb,aAAa,CAAK;IAQ1B,CAAC;CACD;AAbD,gCAaC"}
|
|
@@ -67,4 +67,6 @@ __exportStar(require("./checkboxed-list"), exports);
|
|
|
67
67
|
__exportStar(require("./collection-field"), exports);
|
|
68
68
|
__exportStar(require("./number"), exports);
|
|
69
69
|
__exportStar(require("./pick-from-list"), exports);
|
|
70
|
+
__exportStar(require("./regexp"), exports);
|
|
71
|
+
__exportStar(require("./email"), exports);
|
|
70
72
|
//# sourceMappingURL=field.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../../src/forms/fields/field.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,qDAA0C;AAqB1C,MAAsB,SAAS;IAE9B,YAAmB,WAAoB,KAAK;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAEhD,IAAI,CAAC,SAAiB;QACrB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACvB,CAAC;IAEM,KAAK,CAAC,SAAS,CACrB,GAAY,EACZ,KAAkB;QAElB,IACC,IAAI,CAAC,QAAQ;YACb,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,EACtD;YACD,OAAO;gBACN,KAAK,EAAE,KAAK;gBAEZ,OAAO,EAAE,aAAC,CACT,GAAG,EACH,mBAAmB,EACnB,EAAE,EACF,wBAAwB,CACxB;aACD,CAAC;SACF;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAIM,KAAK,CAAC,YAAY,CACxB,GAAY,EACZ,KAAkB;QAElB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAOD,KAAK,CAAC,QAAQ,CACb,GAAY,EACZ,eAA8C;QAO9C,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YAC9C,gCAAgC;YAChC,OAAO;gBACN,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC5B,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,EAAE;gBACX,GAAG,EAAE,EAAE;aACP,CAAC;SACF;QACD,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,EACL,QAAQ,EACR,YAAY,EACZ,KAAK,EAAE,WAAW,GAClB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE;YACd,OAAO;gBACN,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC5B,GAAG;gBACH,OAAO,EAAE,WAAW,IAAI,OAAO;aAC/B,CAAC;SACF;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAC9C,GAAG,EACH,YAA2B,CAC3B,CAAC;QACF,OAAO;YACN,MAAM,EAAE,YAA2B;YACnC,KAAK;YACL,OAAO;YACP,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;SAC/B,CAAC;IACH,CAAC;CACD;AAvFD,8BAuFC;AAED,sDAAoC;AACpC,oDAAkC;AAClC,qDAAmC;AACnC,2CAAyB;AACzB,mDAAiC"}
|
|
1
|
+
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../../src/forms/fields/field.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,qDAA0C;AAqB1C,MAAsB,SAAS;IAE9B,YAAmB,WAAoB,KAAK;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAEhD,IAAI,CAAC,SAAiB;QACrB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACvB,CAAC;IAEM,KAAK,CAAC,SAAS,CACrB,GAAY,EACZ,KAAkB;QAElB,IACC,IAAI,CAAC,QAAQ;YACb,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,EACtD;YACD,OAAO;gBACN,KAAK,EAAE,KAAK;gBAEZ,OAAO,EAAE,aAAC,CACT,GAAG,EACH,mBAAmB,EACnB,EAAE,EACF,wBAAwB,CACxB;aACD,CAAC;SACF;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAIM,KAAK,CAAC,YAAY,CACxB,GAAY,EACZ,KAAkB;QAElB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAOD,KAAK,CAAC,QAAQ,CACb,GAAY,EACZ,eAA8C;QAO9C,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;YAC9C,gCAAgC;YAChC,OAAO;gBACN,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC5B,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,EAAE;gBACX,GAAG,EAAE,EAAE;aACP,CAAC;SACF;QACD,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,EACL,QAAQ,EACR,YAAY,EACZ,KAAK,EAAE,WAAW,GAClB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE;YACd,OAAO;gBACN,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC5B,GAAG;gBACH,OAAO,EAAE,WAAW,IAAI,OAAO;aAC/B,CAAC;SACF;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAC9C,GAAG,EACH,YAA2B,CAC3B,CAAC;QACF,OAAO;YACN,MAAM,EAAE,YAA2B;YACnC,KAAK;YACL,OAAO;YACP,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;SAC/B,CAAC;IACH,CAAC;CACD;AAvFD,8BAuFC;AAED,sDAAoC;AACpC,oDAAkC;AAClC,qDAAmC;AACnC,2CAAyB;AACzB,mDAAiC;AACjC,2CAAyB;AACzB,0CAAwB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RegExpField = void 0;
|
|
4
|
+
const ts_predicates_1 = require("@sealcode/ts-predicates");
|
|
5
|
+
const field_1 = require("./field");
|
|
6
|
+
class RegExpField extends field_1.FormField {
|
|
7
|
+
constructor(required = false, regexp, error_message, default_value = "") {
|
|
8
|
+
super(required);
|
|
9
|
+
this.regexp = regexp;
|
|
10
|
+
this.error_message = error_message;
|
|
11
|
+
this.default_value = default_value;
|
|
12
|
+
}
|
|
13
|
+
async isValueValid(_, value) {
|
|
14
|
+
if (!ts_predicates_1.is(value, ts_predicates_1.predicates.string)) {
|
|
15
|
+
return { valid: false, message: "expected a string" };
|
|
16
|
+
}
|
|
17
|
+
if (this.regexp.exec(value)) {
|
|
18
|
+
return { valid: true, message: "" };
|
|
19
|
+
}
|
|
20
|
+
return { valid: false, message: this.error_message };
|
|
21
|
+
}
|
|
22
|
+
async parse(_, value) {
|
|
23
|
+
if (ts_predicates_1.is(value, ts_predicates_1.predicates.string)) {
|
|
24
|
+
return {
|
|
25
|
+
parsable: true,
|
|
26
|
+
parsed_value: value,
|
|
27
|
+
error: null,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return {
|
|
32
|
+
parsable: false,
|
|
33
|
+
parsed_value: null,
|
|
34
|
+
error: "Please enter a string",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getEmptyValue() {
|
|
39
|
+
return this.default_value || "";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.RegExpField = RegExpField;
|
|
43
|
+
//# sourceMappingURL=regexp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regexp.js","sourceRoot":"","sources":["../../../src/forms/fields/regexp.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAGzD,mCAAsD;AAEtD,MAAa,WAAY,SAAQ,iBAAiB;IACjD,YACC,QAAQ,GAAG,KAAK,EACT,MAAc,EACd,aAAqB,EACrB,gBAAwB,EAAE;QAEjC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAJT,WAAM,GAAN,MAAM,CAAQ;QACd,kBAAa,GAAb,aAAa,CAAQ;QACrB,kBAAa,GAAb,aAAa,CAAa;IAGlC,CAAC;IAEM,KAAK,CAAC,YAAY,CACxB,CAAU,EACV,KAAc;QAEd,IAAI,CAAC,kBAAE,CAAC,KAAK,EAAE,0BAAU,CAAC,MAAM,CAAC,EAAE;YAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;SACtD;QACD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAC5B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;SACpC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,KAAK,CACV,CAAU,EACV,KAAoB;QAEpB,IAAI,kBAAE,CAAC,KAAK,EAAE,0BAAU,CAAC,MAAM,CAAC,EAAE;YACjC,OAAO;gBACN,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,KAAK;gBACnB,KAAK,EAAE,IAAI;aACX,CAAC;SACF;aAAM;YACN,OAAO;gBACN,QAAQ,EAAE,KAAK;gBACf,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,uBAAuB;aAC9B,CAAC;SACF;IACF,CAAC;IAEM,aAAa;QACnB,OAAO,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;IACjC,CAAC;CACD;AA7CD,kCA6CC"}
|
package/lib/forms/form.js
CHANGED
|
@@ -28,15 +28,19 @@ class Form extends mountable_with_fields_1.MountableWithFields {
|
|
|
28
28
|
/>`;
|
|
29
29
|
}
|
|
30
30
|
async render(ctx, data) {
|
|
31
|
-
return tempstream_1.tempstream /* HTML */ `${this.makeOpenFormTag()}
|
|
31
|
+
return tempstream_1.tempstream /* HTML */ `${this.makeOpenFormTag(ctx)}
|
|
32
32
|
${!this.controls.some((control) => control.role == "messages")
|
|
33
33
|
? this.renderMessages(ctx, data)
|
|
34
34
|
: ""}
|
|
35
35
|
${this.renderControls(ctx, data)} ${this.makeSubmitButton()}
|
|
36
36
|
${this.makeCloseFormTag()}`;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
+
async makeFormClasses(_ctx) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
makeOpenFormTag(ctx) {
|
|
43
|
+
return tempstream_1.tempstream `<form method="POST" action="${this.action}" class="${this.makeFormClasses(ctx).then((classes) => classes.join(" "))}">`;
|
|
40
44
|
}
|
|
41
45
|
makeCloseFormTag() {
|
|
42
46
|
return `</form>`;
|
package/lib/forms/form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/forms/form.ts"],"names":[],"mappings":";;;AAEA,2CAAyD;AACzD,2DAKiC;AAEjC,yEAIuC;AA0BvC,MAAsB,IAAuB,SAAQ,2CAAsB;IAA3E;;QACC,0BAAqB,GAAG,MAAM,CAAC;QAC/B,qBAAgB,GAAG,QAAQ,CAAC;QAC5B,WAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/forms/form.ts"],"names":[],"mappings":"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"}
|
package/lib/mount.js
CHANGED
|
@@ -13,14 +13,24 @@ async function handleHtmlPromise(ctx, next) {
|
|
|
13
13
|
function mount(router, url, mountable) {
|
|
14
14
|
router.use(url, sealious_1.Middlewares.extractContext(), sealious_1.Middlewares.parseBody(), handleHtmlPromise);
|
|
15
15
|
mountable.init();
|
|
16
|
-
mountable.mount(router, url);
|
|
17
16
|
// to automatically add trailing slashes:
|
|
18
|
-
router.get(url.slice(0, -1), (ctx) => {
|
|
17
|
+
router.get(url.slice(0, -1), async (ctx, next) => {
|
|
19
18
|
const url2 = ctx.URL;
|
|
20
|
-
url2.pathname
|
|
21
|
-
|
|
19
|
+
if (!url2.pathname.endsWith("/")) {
|
|
20
|
+
url2.pathname += "/";
|
|
21
|
+
ctx.redirect(url2.toString());
|
|
22
|
+
}
|
|
23
|
+
await next();
|
|
24
|
+
});
|
|
25
|
+
router.use(url, async (ctx, next) => {
|
|
26
|
+
ctx.set("content-type", "text/html;charset=utf-8");
|
|
27
|
+
if (!(await mountable.canAccess(ctx)).canAccess) {
|
|
28
|
+
ctx.body = "no access";
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
await next();
|
|
22
32
|
});
|
|
23
|
-
|
|
33
|
+
mountable.mount(router, url);
|
|
24
34
|
}
|
|
25
35
|
exports.mount = mount;
|
|
26
36
|
//# sourceMappingURL=mount.js.map
|
package/lib/mount.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":";;;AAEA,uCAAuC;AAGvC,KAAK,UAAU,iBAAiB,CAAC,GAAY,EAAE,IAAc;IAC5D,MAAM,IAAI,EAAE,CAAC;IACb,IAAI,GAAG,CAAC,IAAI,YAAY,OAAO,EAAE;QAChC,mEAAmE;QACnE,GAAG,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC;KAC1B;IACD,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,KAAK,CAAC,MAAc,EAAE,GAAW,EAAE,SAAoB;IACtE,MAAM,CAAC,GAAG,CACT,GAAG,EACH,sBAAW,CAAC,cAAc,EAAE,EAC5B,sBAAW,CAAC,SAAS,EAAE,EACvB,iBAAiB,CACjB,CAAC;IACF,SAAS,CAAC,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":";;;AAEA,uCAAuC;AAGvC,KAAK,UAAU,iBAAiB,CAAC,GAAY,EAAE,IAAc;IAC5D,MAAM,IAAI,EAAE,CAAC;IACb,IAAI,GAAG,CAAC,IAAI,YAAY,OAAO,EAAE;QAChC,mEAAmE;QACnE,GAAG,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC;KAC1B;IACD,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,KAAK,CAAC,MAAc,EAAE,GAAW,EAAE,SAAoB;IACtE,MAAM,CAAC,GAAG,CACT,GAAG,EACH,sBAAW,CAAC,cAAc,EAAE,EAC5B,sBAAW,CAAC,SAAS,EAAE,EACvB,iBAAiB,CACjB,CAAC;IACF,SAAS,CAAC,IAAI,EAAE,CAAC;IAEjB,yCAAyC;IACzC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAChD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACjC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;YACrB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;SAC9B;QACD,MAAM,IAAI,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACnC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE;YAChD,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;YACvB,OAAO;SACP;QACD,MAAM,IAAI,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AA7BD,sBA6BC"}
|
package/package.json
CHANGED
package/src/components/tabs.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FlatTemplatable } from "tempstream";
|
|
1
|
+
import { FlatTemplatable, tempstream } from "tempstream";
|
|
2
2
|
|
|
3
3
|
function name_to_id(str: string) {
|
|
4
4
|
return str.replace(/\W/g, "-");
|
|
@@ -52,11 +52,11 @@ const style = /* HTML */ `<style>
|
|
|
52
52
|
</style>`;
|
|
53
53
|
|
|
54
54
|
export function tabs(
|
|
55
|
-
tabs: Record<string,
|
|
55
|
+
tabs: Record<string, FlatTemplatable>,
|
|
56
56
|
selected_tab_style = "font-weight: bold;",
|
|
57
57
|
selected_index = 0
|
|
58
58
|
): FlatTemplatable {
|
|
59
|
-
return /* HTML */ `${style}
|
|
59
|
+
return /* HTML */ tempstream`${style}
|
|
60
60
|
${Object.keys(tabs)
|
|
61
61
|
.map((tab_title, index) => {
|
|
62
62
|
const id = name_to_id(tab_title);
|
|
@@ -73,10 +73,9 @@ export function tabs(
|
|
|
73
73
|
</label>`;
|
|
74
74
|
})
|
|
75
75
|
.join("\n")}
|
|
76
|
-
${Object.entries(tabs)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return /* HTML */ ` <div class="tab-label tab-label--mobile">
|
|
76
|
+
${Object.entries(tabs).map(([title, content]) => {
|
|
77
|
+
const id = name_to_id(title);
|
|
78
|
+
return /* HTML */ tempstream`<div class="tab-label tab-label--mobile">
|
|
80
79
|
${title}
|
|
81
80
|
</div>
|
|
82
81
|
<div class="tab-content tab-content--${id}">${content}</div>
|
|
@@ -91,6 +90,5 @@ export function tabs(
|
|
|
91
90
|
${selected_tab_style}
|
|
92
91
|
}
|
|
93
92
|
</style>`;
|
|
94
|
-
|
|
95
|
-
.join("\n")}`;
|
|
93
|
+
})}`;
|
|
96
94
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RegExpField } from "./regexp";
|
|
2
|
+
|
|
3
|
+
export class EmailField extends RegExpField {
|
|
4
|
+
constructor(
|
|
5
|
+
required = false,
|
|
6
|
+
public error_message = "Please enter a proper email address",
|
|
7
|
+
public default_value = ""
|
|
8
|
+
) {
|
|
9
|
+
super(
|
|
10
|
+
required,
|
|
11
|
+
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
12
|
+
error_message,
|
|
13
|
+
default_value
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
+
import { Context } from "koa";
|
|
3
|
+
import { FormDataValue } from "../form";
|
|
4
|
+
import { FieldParseResult, FormField } from "./field";
|
|
5
|
+
|
|
6
|
+
export class RegExpField extends FormField<string> {
|
|
7
|
+
constructor(
|
|
8
|
+
required = false,
|
|
9
|
+
public regexp: RegExp,
|
|
10
|
+
public error_message: string,
|
|
11
|
+
public default_value: string = ""
|
|
12
|
+
) {
|
|
13
|
+
super(required);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async isValueValid(
|
|
17
|
+
_: Context,
|
|
18
|
+
value: unknown
|
|
19
|
+
): Promise<{ valid: boolean; message: string }> {
|
|
20
|
+
if (!is(value, predicates.string)) {
|
|
21
|
+
return { valid: false, message: "expected a string" };
|
|
22
|
+
}
|
|
23
|
+
if (this.regexp.exec(value)) {
|
|
24
|
+
return { valid: true, message: "" };
|
|
25
|
+
}
|
|
26
|
+
return { valid: false, message: this.error_message };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async parse(
|
|
30
|
+
_: Context,
|
|
31
|
+
value: FormDataValue
|
|
32
|
+
): Promise<FieldParseResult<string>> {
|
|
33
|
+
if (is(value, predicates.string)) {
|
|
34
|
+
return {
|
|
35
|
+
parsable: true,
|
|
36
|
+
parsed_value: value,
|
|
37
|
+
error: null,
|
|
38
|
+
};
|
|
39
|
+
} else {
|
|
40
|
+
return {
|
|
41
|
+
parsable: false,
|
|
42
|
+
parsed_value: null,
|
|
43
|
+
error: "Please enter a string",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public getEmptyValue(): string {
|
|
49
|
+
return this.default_value || "";
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/forms/form.ts
CHANGED
|
@@ -67,7 +67,7 @@ export abstract class Form<F extends Fields> extends MountableWithFields<F> {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
async render(ctx: Context, data: FormData): Promise<FlatTemplatable> {
|
|
70
|
-
return tempstream/* HTML */ `${this.makeOpenFormTag()}
|
|
70
|
+
return tempstream/* HTML */ `${this.makeOpenFormTag(ctx)}
|
|
71
71
|
${!this.controls.some((control) => control.role == "messages")
|
|
72
72
|
? this.renderMessages(ctx, data)
|
|
73
73
|
: ""}
|
|
@@ -75,8 +75,17 @@ export abstract class Form<F extends Fields> extends MountableWithFields<F> {
|
|
|
75
75
|
${this.makeCloseFormTag()}`;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
79
|
+
public async makeFormClasses(_ctx: Context): Promise<string[]> {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public makeOpenFormTag(ctx: Context): FlatTemplatable {
|
|
84
|
+
return tempstream`<form method="POST" action="${
|
|
85
|
+
this.action
|
|
86
|
+
}" class="${this.makeFormClasses(ctx).then((classes) =>
|
|
87
|
+
classes.join(" ")
|
|
88
|
+
)}">`;
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
public makeCloseFormTag(): FlatTemplatable {
|
package/src/mount.ts
CHANGED
|
@@ -20,14 +20,25 @@ export function mount(router: Router, url: string, mountable: Mountable): void {
|
|
|
20
20
|
handleHtmlPromise
|
|
21
21
|
);
|
|
22
22
|
mountable.init();
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
// to automatically add trailing slashes:
|
|
25
|
-
router.get(url.slice(0, -1), (ctx) => {
|
|
25
|
+
router.get(url.slice(0, -1), async (ctx, next) => {
|
|
26
26
|
const url2 = ctx.URL;
|
|
27
|
-
url2.pathname
|
|
28
|
-
|
|
27
|
+
if (!url2.pathname.endsWith("/")) {
|
|
28
|
+
url2.pathname += "/";
|
|
29
|
+
ctx.redirect(url2.toString());
|
|
30
|
+
}
|
|
31
|
+
await next();
|
|
29
32
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
router.use(url, async (ctx, next) => {
|
|
35
|
+
ctx.set("content-type", "text/html;charset=utf-8");
|
|
36
|
+
if (!(await mountable.canAccess(ctx)).canAccess) {
|
|
37
|
+
ctx.body = "no access";
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
await next();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
mountable.mount(router, url);
|
|
33
44
|
}
|