@sealcode/sealgen 0.7.11 → 0.7.13

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.
@@ -1,2 +1,2 @@
1
1
  import { FlatTemplatable } from "tempstream";
2
- export declare function tabs(tabs: Record<string, string>, selected_tab_style?: string, selected_index?: number): FlatTemplatable;
2
+ export declare function tabs(tabs: Record<string, FlatTemplatable>, selected_tab_style?: string, selected_index?: number): FlatTemplatable;
@@ -0,0 +1,6 @@
1
+ import { RegExpField } from "./regexp";
2
+ export declare class EmailField extends RegExpField {
3
+ error_message: string;
4
+ default_value: string;
5
+ constructor(required?: boolean, error_message?: string, default_value?: string);
6
+ }
@@ -36,3 +36,5 @@ export * from "./checkboxed-list";
36
36
  export * from "./collection-field";
37
37
  export * from "./number";
38
38
  export * from "./pick-from-list";
39
+ export * from "./regexp";
40
+ export * from "./email";
@@ -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
+ }
@@ -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 */ ` <div class="tab-label tab-label--mobile">
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":";;;AAEA,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,IAA4B,EAC5B,kBAAkB,GAAG,oBAAoB,EACzC,cAAc,GAAG,CAAC;IAElB,OAAO,UAAU,CAAC,GAAG,KAAK;GACxB,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;SACpB,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE;QACzB,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,UAAU,CAAC;OACd,KAAK;;2CAE+B,EAAE,KAAK,OAAO;;mBAEtC,EAAE,oBAAoB,EAAE;;;mBAGxB,EAAE,4BAA4B,EAAE;;;mBAGhC,EAAE,+BAA+B,EAAE;QAC9C,kBAAkB;;aAEb,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAChB,CAAC;AA1CD,oBA0CC"}
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/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) => {
19
- const url2 = new URL(url);
20
- url2.pathname += "/";
21
- ctx.redirect(url2.toString());
17
+ router.get(url.slice(0, -1), async (ctx, next) => {
18
+ const url2 = ctx.URL;
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
- router.use(url, (ctx) => ctx.set("content-type", "text/html;charset=utf-8"));
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;IACjB,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,yCAAyC;IACzC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;QACrB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CACvB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAClD,CAAC;AACH,CAAC;AAlBD,sBAkBC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.7.11",
3
+ "version": "0.7.13",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -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, 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
- .map(([title, content]) => {
78
- const id = name_to_id(title);
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
+ }
@@ -114,3 +114,5 @@ export * from "./checkboxed-list";
114
114
  export * from "./collection-field";
115
115
  export * from "./number";
116
116
  export * from "./pick-from-list";
117
+ export * from "./regexp";
118
+ export * from "./email";
@@ -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/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
- mountable.mount(router, url);
23
+
24
24
  // to automatically add trailing slashes:
25
- router.get(url.slice(0, -1), (ctx) => {
26
- const url2 = new URL(url);
27
- url2.pathname += "/";
28
- ctx.redirect(url2.toString());
25
+ router.get(url.slice(0, -1), async (ctx, next) => {
26
+ const url2 = ctx.URL;
27
+ if (!url2.pathname.endsWith("/")) {
28
+ url2.pathname += "/";
29
+ ctx.redirect(url2.toString());
30
+ }
31
+ await next();
29
32
  });
30
- router.use(url, (ctx) =>
31
- ctx.set("content-type", "text/html;charset=utf-8")
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
  }