@sealcode/sealgen 0.2.1 → 0.3.2
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/.eslintrc.js +1 -0
- package/@types/build.d.ts +1 -0
- package/@types/cli.d.ts +2 -0
- package/@types/forms/controls/checkboxed-list-input.d.ts +16 -0
- package/@types/forms/controls/controls.d.ts +9 -0
- package/@types/forms/controls/dropdown.d.ts +20 -0
- package/@types/forms/controls/editable-collection-subset.d.ts +21 -0
- package/@types/forms/controls/form-control.d.ts +8 -0
- package/@types/forms/controls/form-field-control.d.ts +13 -0
- package/@types/forms/controls/form-header.d.ts +9 -0
- package/@types/forms/controls/form-paragraph.d.ts +7 -0
- package/@types/forms/controls/frame.d.ts +17 -0
- package/@types/forms/controls/simple-input.d.ts +28 -0
- package/@types/forms/controls.d.ts +0 -0
- package/@types/forms/field.d.ts +42 -0
- package/@types/forms/form-fields-list.d.ts +4 -0
- package/@types/forms/form.d.ts +42 -0
- package/@types/forms/validator.d.ts +3 -0
- package/@types/index.d.ts +15 -2
- package/@types/page/access-control.d.ts +6 -0
- package/@types/page/list.d.ts +59 -0
- package/@types/page/page.d.ts +26 -0
- package/@types/page/props-parser.d.ts +20 -0
- package/@types/run.d.ts +0 -0
- package/@types/templates/page.d.ts +1 -1
- package/@types/utils/natural-numbers.d.ts +1 -0
- package/@types/utils/sleep.d.ts +1 -0
- package/@types/utils/url-with-new-params.d.ts +2 -0
- package/@types/utils/utils.d.ts +9 -0
- package/@types/utils/walk.d.ts +1 -1
- package/lib/build.js +116 -0
- package/lib/build.js.map +1 -0
- package/lib/cli.js +30 -0
- package/lib/cli.js.map +1 -0
- package/lib/find-scss-includes.js +2 -1
- package/lib/find-scss-includes.js.map +1 -1
- package/lib/forms/controls/checkboxed-list-input.js +43 -0
- package/lib/forms/controls/checkboxed-list-input.js.map +1 -0
- package/lib/forms/controls/controls.js +22 -0
- package/lib/forms/controls/controls.js.map +1 -0
- package/lib/forms/controls/dropdown.js +40 -0
- package/lib/forms/controls/dropdown.js.map +1 -0
- package/lib/forms/controls/editable-collection-subset.js +73 -0
- package/lib/forms/controls/editable-collection-subset.js.map +1 -0
- package/lib/forms/controls/form-control.js +7 -0
- package/lib/forms/controls/form-control.js.map +1 -0
- package/lib/forms/controls/form-field-control.js +22 -0
- package/lib/forms/controls/form-field-control.js.map +1 -0
- package/lib/forms/controls/form-header.js +18 -0
- package/lib/forms/controls/form-header.js.map +1 -0
- package/lib/forms/controls/form-paragraph.js +16 -0
- package/lib/forms/controls/form-paragraph.js.map +1 -0
- package/lib/forms/controls/frame.js +29 -0
- package/lib/forms/controls/frame.js.map +1 -0
- package/lib/forms/controls/simple-input.js +50 -0
- package/lib/forms/controls/simple-input.js.map +1 -0
- package/lib/forms/controls.js +1 -0
- package/lib/forms/controls.js.map +1 -0
- package/lib/forms/field.js +80 -0
- package/lib/forms/field.js.map +1 -0
- package/lib/forms/form-fields-list.js +10 -0
- package/lib/forms/form-fields-list.js.map +1 -0
- package/lib/forms/form.js +162 -0
- package/lib/forms/form.js.map +1 -0
- package/lib/forms/validator.js +11 -0
- package/lib/forms/validator.js.map +1 -0
- package/lib/generate-routes.js +11 -4
- package/lib/generate-routes.js.map +1 -1
- package/lib/index.js +18 -25
- package/lib/index.js.map +1 -1
- package/lib/page/access-control.js +20 -0
- package/lib/page/access-control.js.map +1 -0
- package/lib/page/list.js +148 -0
- package/lib/page/list.js.map +1 -0
- package/lib/page/page.js +20 -0
- package/lib/page/page.js.map +1 -0
- package/lib/page/props-parser.js +74 -0
- package/lib/page/props-parser.js.map +1 -0
- package/lib/run.js +1 -0
- package/lib/run.js.map +1 -0
- package/lib/templates/form.js +10 -5
- package/lib/templates/form.js.map +1 -1
- package/lib/templates/list.js +3 -3
- package/lib/templates/list.js.map +1 -1
- package/lib/templates/page.js +5 -4
- package/lib/templates/page.js.map +1 -1
- package/lib/utils/escape-url-params.js +1 -0
- package/lib/utils/escape-url-params.js.map +1 -1
- package/lib/utils/list-collections.js +1 -1
- package/lib/utils/list-collections.js.map +1 -1
- package/lib/utils/natural-numbers.js +10 -0
- package/lib/utils/natural-numbers.js.map +1 -0
- package/lib/utils/sleep.js +8 -0
- package/lib/utils/sleep.js.map +1 -0
- package/lib/utils/url-with-new-params.js +12 -0
- package/lib/utils/url-with-new-params.js.map +1 -0
- package/lib/utils/utils.js +19 -0
- package/lib/utils/utils.js.map +1 -0
- package/lib/utils/walk.js +4 -4
- package/lib/utils/walk.js.map +1 -1
- package/package.json +17 -4
- package/src/build.ts +92 -0
- package/src/cli.ts +34 -0
- package/src/find-scss-includes.ts +3 -2
- package/src/forms/controls/checkboxed-list-input.ts +50 -0
- package/src/forms/controls/controls.ts +9 -0
- package/src/forms/controls/dropdown.ts +57 -0
- package/src/forms/controls/editable-collection-subset.ts +91 -0
- package/src/forms/controls/form-control.ts +13 -0
- package/src/forms/controls/form-field-control.ts +39 -0
- package/src/forms/controls/form-header.ts +16 -0
- package/src/forms/controls/form-paragraph.ts +11 -0
- package/src/forms/controls/frame.ts +26 -0
- package/src/forms/controls/simple-input.ts +73 -0
- package/src/forms/controls.ts +0 -0
- package/src/forms/field.ts +119 -0
- package/src/forms/form-fields-list.ts +7 -0
- package/src/forms/form.ts +242 -0
- package/src/forms/forms.scss +18 -0
- package/src/forms/validator.ts +10 -0
- package/src/generate-routes.ts +12 -9
- package/src/index.ts +15 -28
- package/src/page/access-control.ts +18 -0
- package/src/page/list.ts +214 -0
- package/src/page/page.ts +31 -0
- package/src/page/props-parser.ts +99 -0
- package/src/run.ts +0 -0
- package/src/templates/form.ts +10 -5
- package/src/templates/list.ts +3 -3
- package/src/templates/page.ts +6 -6
- package/src/utils/escape-url-params.ts +1 -0
- package/src/utils/list-collections.ts +2 -2
- package/src/utils/natural-numbers.ts +5 -0
- package/src/utils/sleep.ts +3 -0
- package/src/utils/url-with-new-params.ts +9 -0
- package/src/utils/utils.ts +10 -0
- package/src/utils/walk.ts +2 -2
- package/tsconfig.json +5 -2
- package/.log/ti-101379.log +0 -524
- package/.log/ti-131883.log +0 -505
- package/.log/ti-13490.log +0 -652
- package/.log/ti-138140.log +0 -505
- package/.log/ti-138288.log +0 -526
- package/.log/ti-46589.log +0 -675
- package/.log/tsserver.log +0 -1666
- package/src/tsconfig.json +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/templates/list.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AACvD,mCAAoC;AACpC,gEAA4D;AAErD,MAAM,YAAY,GAAG,KAAK,EAChC,WAAmB,EACnB,eAAuB,EACL,EAAE;IACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC9B,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,gDAAgD;QACzD,OAAO,EAAE,CACR,MAAM,kCAAe,EAAE,CACvB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACtB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,UAAU;SACjB,CAAC,CAAC;KACH,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAoB,CAAC;IACjD,MAAM,oBAAoB,GACzB,UAAU,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,6BAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,OAAO;;;WAGG,oBAAoB,YAAY,GAAG,CAC5C,kCAAkC,CAClC;oBACkB,GAAG,CAAC,kBAAkB,CAAC
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/templates/list.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AACvD,mCAAoC;AACpC,gEAA4D;AAErD,MAAM,YAAY,GAAG,KAAK,EAChC,WAAmB,EACnB,eAAuB,EACL,EAAE;IACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC9B,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,gDAAgD;QACzD,OAAO,EAAE,CACR,MAAM,kCAAe,EAAE,CACvB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACtB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,UAAU;SACjB,CAAC,CAAC;KACH,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAoB,CAAC;IACjD,MAAM,oBAAoB,GACzB,UAAU,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,6BAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,OAAO;;;WAGG,oBAAoB,YAAY,GAAG,CAC5C,kCAAkC,CAClC;oBACkB,GAAG,CAAC,kBAAkB,CAAC;;;;;;;;;6BASd,WAAW;;4BAEZ,WAAW,4CAA4C,oBAAoB;;;;;;;;;eASxF,oBAAoB;;sBAEb,oBAAoB;;;;;;;;mEAQyB,oBAAoB;;;KAGlF,oBAAoB;CACxB,CAAC;AACF,CAAC,CAAC;AA5DW,QAAA,YAAY,gBA4DvB"}
|
package/lib/templates/page.js
CHANGED
|
@@ -2,22 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pageTemplate = void 0;
|
|
4
4
|
const import_path_1 = require("../utils/import-path");
|
|
5
|
-
async function pageTemplate(action_name,
|
|
5
|
+
async function pageTemplate(action_name, newfilefullpath) {
|
|
6
|
+
const rel = import_path_1.curryImportPath(newfilefullpath);
|
|
6
7
|
return `import { BaseContext } from "koa";
|
|
7
8
|
import { tempstream } from "tempstream";
|
|
8
|
-
import { Page } from "
|
|
9
|
+
import { Page } from "@sealcode/sealgen";
|
|
10
|
+
import html from "${rel("src/back/html")}";
|
|
9
11
|
|
|
10
12
|
export const actionName = "${action_name}";
|
|
11
13
|
|
|
12
14
|
export default new (class ${action_name}Page extends Page {
|
|
13
|
-
|
|
14
15
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
15
16
|
async canAccess(_: BaseContext) {
|
|
16
17
|
return { canAccess: true, message: "" };
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
async render(ctx: BaseContext) {
|
|
20
|
-
return tempstream/* HTML */ \`<div></div
|
|
21
|
+
return html(ctx, "${action_name}", tempstream/* HTML */ \`<div></div>\`);
|
|
21
22
|
}
|
|
22
23
|
})();
|
|
23
24
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/templates/page.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/templates/page.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAChD,KAAK,UAAU,YAAY,CACjC,WAAmB,EACnB,eAAuB;IAEvB,MAAM,GAAG,GAAG,6BAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,OAAO;;;oBAGY,GAAG,CAAC,eAAe,CAAC;;6BAEX,WAAW;;4BAEZ,WAAW;;;;;;;sBAOjB,WAAW;;;CAGhC,CAAC;AACF,CAAC;AAvBD,oCAuBC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escape-url-params.js","sourceRoot":"","sources":["../../src/utils/escape-url-params.ts"],"names":[],"mappings":";;;AAAA,SAAgB,iBAAiB,CAAC,GAAW;IAC5C,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvD,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;
|
|
1
|
+
{"version":3,"file":"escape-url-params.js","sourceRoot":"","sources":["../../src/utils/escape-url-params.ts"],"names":[],"mappings":";;;AAAA,SAAgB,iBAAiB,CAAC,GAAW;IAC5C,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SACtB,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAND,8CAMC;AAED,SAAgB,mBAAmB,CAAC,GAAW;IAC9C,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACpE,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AALD,kDAKC"}
|
|
@@ -8,7 +8,7 @@ const locreq_1 = __importDefault(require("locreq"));
|
|
|
8
8
|
const walk_1 = require("./walk");
|
|
9
9
|
const target_locreq = locreq_1.default(process.cwd());
|
|
10
10
|
async function listCollections() {
|
|
11
|
-
const files = await walk_1.
|
|
11
|
+
const files = await walk_1.walkDir(target_locreq.resolve("src/back/collections"));
|
|
12
12
|
return files
|
|
13
13
|
.filter((f) => f.endsWith(".ts") &&
|
|
14
14
|
!f.endsWith(".test.ts") &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-collections.js","sourceRoot":"","sources":["../../src/utils/list-collections.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"list-collections.js","sourceRoot":"","sources":["../../src/utils/list-collections.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA6B;AAC7B,iCAAiC;AACjC,MAAM,aAAa,GAAG,gBAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAEtC,KAAK,UAAU,eAAe;IACpC,MAAM,KAAK,GAAG,MAAM,cAAO,CAAC,aAAa,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC3E,OAAO,KAAK;SACV,MAAM,CACN,CAAC,CAAC,EAAE,EAAE,CACL,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QACvB,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAC9B;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACzD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AAC3B,CAAC;AAXD,0CAWC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.naturalNumbers = void 0;
|
|
4
|
+
function* naturalNumbers(min, max) {
|
|
5
|
+
for (let i = min; i <= max; i++) {
|
|
6
|
+
yield i;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.naturalNumbers = naturalNumbers;
|
|
10
|
+
//# sourceMappingURL=natural-numbers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-numbers.js","sourceRoot":"","sources":["../../src/utils/natural-numbers.ts"],"names":[],"mappings":";;;AAAA,QAAe,CAAC,CAAC,cAAc,CAAC,GAAW,EAAE,GAAW;IACvD,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;QAChC,MAAM,CAAC,CAAC;KACR;AACF,CAAC;AAJD,wCAIC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":";;;AAAO,KAAK,UAAU,KAAK,CAAC,IAAY;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5D,CAAC;AAFD,sBAEC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UrlWithNewParams = void 0;
|
|
7
|
+
const qs_1 = __importDefault(require("qs"));
|
|
8
|
+
function UrlWithNewParams(ctx, query_params) {
|
|
9
|
+
return `${ctx.path}?${qs_1.default.stringify(query_params)}`;
|
|
10
|
+
}
|
|
11
|
+
exports.UrlWithNewParams = UrlWithNewParams;
|
|
12
|
+
//# sourceMappingURL=url-with-new-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-with-new-params.js","sourceRoot":"","sources":["../../src/utils/url-with-new-params.ts"],"names":[],"mappings":";;;;;;AACA,4CAAoB;AAEpB,SAAgB,gBAAgB,CAC/B,GAAgB,EAChB,YAAqC;IAErC,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,YAAE,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;AACpD,CAAC;AALD,4CAKC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.walkDir = exports.listCollections = exports.curryImportPath = exports.importPath = exports.exec = exports.UrlWithNewParams = exports.naturalNumbers = exports.sleep = void 0;
|
|
4
|
+
var sleep_1 = require("./sleep");
|
|
5
|
+
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return sleep_1.sleep; } });
|
|
6
|
+
var natural_numbers_1 = require("./natural-numbers");
|
|
7
|
+
Object.defineProperty(exports, "naturalNumbers", { enumerable: true, get: function () { return natural_numbers_1.naturalNumbers; } });
|
|
8
|
+
var url_with_new_params_1 = require("./url-with-new-params");
|
|
9
|
+
Object.defineProperty(exports, "UrlWithNewParams", { enumerable: true, get: function () { return url_with_new_params_1.UrlWithNewParams; } });
|
|
10
|
+
var exec_1 = require("./exec");
|
|
11
|
+
Object.defineProperty(exports, "exec", { enumerable: true, get: function () { return exec_1.exec; } });
|
|
12
|
+
var import_path_1 = require("./import-path");
|
|
13
|
+
Object.defineProperty(exports, "importPath", { enumerable: true, get: function () { return import_path_1.importPath; } });
|
|
14
|
+
Object.defineProperty(exports, "curryImportPath", { enumerable: true, get: function () { return import_path_1.curryImportPath; } });
|
|
15
|
+
var list_collections_1 = require("./list-collections");
|
|
16
|
+
Object.defineProperty(exports, "listCollections", { enumerable: true, get: function () { return list_collections_1.listCollections; } });
|
|
17
|
+
var walk_1 = require("./walk");
|
|
18
|
+
Object.defineProperty(exports, "walkDir", { enumerable: true, get: function () { return walk_1.walkDir; } });
|
|
19
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":";;;AAGA,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,6CAA4D;AAAnD,yGAAA,UAAU,OAAA;AAAE,8GAAA,eAAe,OAAA;AACpC,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,+BAAiC;AAAxB,+FAAA,OAAO,OAAA"}
|
package/lib/utils/walk.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.walkDir = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
-
async function
|
|
6
|
+
async function walkDir(dir) {
|
|
7
7
|
const entries = await fs_1.promises.readdir(dir);
|
|
8
8
|
let ret = [];
|
|
9
9
|
for (const entry of entries) {
|
|
@@ -12,7 +12,7 @@ async function walk(dir) {
|
|
|
12
12
|
const info = await fs_1.promises.stat(fullpath);
|
|
13
13
|
if (info.isDirectory()) {
|
|
14
14
|
// eslint-disable-next-line no-await-in-loop
|
|
15
|
-
ret = [...ret, ...(await
|
|
15
|
+
ret = [...ret, ...(await walkDir(fullpath))];
|
|
16
16
|
}
|
|
17
17
|
else {
|
|
18
18
|
ret = [...ret, fullpath];
|
|
@@ -20,5 +20,5 @@ async function walk(dir) {
|
|
|
20
20
|
}
|
|
21
21
|
return ret;
|
|
22
22
|
}
|
|
23
|
-
exports.
|
|
23
|
+
exports.walkDir = walkDir;
|
|
24
24
|
//# sourceMappingURL=walk.js.map
|
package/lib/utils/walk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/utils/walk.ts"],"names":[],"mappings":";;;AAAA,2BAAoC;AACpC,+BAA+B;AAExB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/utils/walk.ts"],"names":[],"mappings":";;;AAAA,2BAAoC;AACpC,+BAA+B;AAExB,KAAK,UAAU,OAAO,CAAC,GAAW;IACxC,MAAM,OAAO,GAAG,MAAM,aAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;QAC5B,MAAM,QAAQ,GAAG,cAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,4CAA4C;QAC5C,MAAM,IAAI,GAAG,MAAM,aAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAErC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACvB,4CAA4C;YAC5C,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SAC7C;aAAM;YACN,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC;SACzB;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAhBD,0BAgBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
"test-reports": "npm run build && rm -fr .xunit coverage && npm run test -- --cover --test-report"
|
|
11
11
|
},
|
|
12
12
|
"bin": {
|
|
13
|
-
"sealgen": "./lib/
|
|
13
|
+
"sealgen": "./lib/cli.js"
|
|
14
14
|
},
|
|
15
15
|
"author": "",
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"devDependencies": {
|
|
18
|
+
"@types/koa__router": "^8.0.4",
|
|
18
19
|
"@types/mocha": "^9.0.0",
|
|
19
20
|
"@types/prompts": "^2.0.14",
|
|
20
21
|
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
|
@@ -33,8 +34,20 @@
|
|
|
33
34
|
},
|
|
34
35
|
"types": "./@types/index.d.ts",
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@
|
|
37
|
+
"@koa/router": "^10.1.1",
|
|
38
|
+
"@sealcode/ts-predicates": "^0.4.0",
|
|
39
|
+
"esbuild": "^0.14.54",
|
|
40
|
+
"esbuild-sass-plugin": "^2.3.1",
|
|
41
|
+
"koa": "^2.13.0",
|
|
37
42
|
"locreq": "^2.0.2",
|
|
38
|
-
"
|
|
43
|
+
"merge": "^2.1.1",
|
|
44
|
+
"prompts": "^2.4.2",
|
|
45
|
+
"tempstream": "^0.0.19",
|
|
46
|
+
"tiny-glob": "^0.2.9"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@koa/router": "^10.1.1",
|
|
50
|
+
"koa": "^2.13.0",
|
|
51
|
+
"sealious": "0.14.x"
|
|
39
52
|
}
|
|
40
53
|
}
|
package/src/build.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { build, BuildResult } from "esbuild";
|
|
2
|
+
import { sassPlugin } from "esbuild-sass-plugin";
|
|
3
|
+
import * as chokidar from "chokidar";
|
|
4
|
+
import { default as glob } from "tiny-glob";
|
|
5
|
+
import { generateScssIncludes } from "./find-scss-includes";
|
|
6
|
+
import { sleep } from "./utils/sleep";
|
|
7
|
+
import { generateCollections } from "./generate-collections";
|
|
8
|
+
import { generateRoutes } from "./generate-routes";
|
|
9
|
+
|
|
10
|
+
async function build_ts() {
|
|
11
|
+
const [entryPoints] = await Promise.all([
|
|
12
|
+
glob("./src/back/**/*.ts"),
|
|
13
|
+
generateCollections(),
|
|
14
|
+
generateRoutes(),
|
|
15
|
+
]);
|
|
16
|
+
await build({
|
|
17
|
+
entryPoints,
|
|
18
|
+
sourcemap: true,
|
|
19
|
+
outdir: "./dist/back",
|
|
20
|
+
logLevel: "info",
|
|
21
|
+
platform: "node",
|
|
22
|
+
target: "node16",
|
|
23
|
+
format: "cjs",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function complex_build(watch: boolean): Promise<void> {
|
|
28
|
+
let scss_build: BuildResult | null = null;
|
|
29
|
+
if (watch) {
|
|
30
|
+
const scss_watcher = chokidar.watch("src", { ignoreInitial: true });
|
|
31
|
+
scss_watcher.on("all", async (_, path) => {
|
|
32
|
+
if (!scss_build) return;
|
|
33
|
+
if (path.endsWith(".scss") && !path.endsWith("/includes.scss")) {
|
|
34
|
+
// refresh the list of all scss files in includes.scss
|
|
35
|
+
await generateScssIncludes();
|
|
36
|
+
try {
|
|
37
|
+
await scss_build?.rebuild?.();
|
|
38
|
+
console.log(`Built main.scss [on ${path}]`);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error(e);
|
|
41
|
+
await sleep(200);
|
|
42
|
+
scss_build
|
|
43
|
+
?.rebuild?.()
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
45
|
+
.catch((e) => console.error(e?.message));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (
|
|
49
|
+
path.endsWith(".ts") &&
|
|
50
|
+
!path.endsWith("src/back/collections.ts") &&
|
|
51
|
+
!path.endsWith("src/back/routes/routes.ts")
|
|
52
|
+
) {
|
|
53
|
+
await build_ts();
|
|
54
|
+
console.log(`Finished TS build [on ${path}]`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
scss_build = await build({
|
|
61
|
+
entryPoints: ["./src/main.scss"],
|
|
62
|
+
sourcemap: true,
|
|
63
|
+
outfile: "./public/dist/style.css",
|
|
64
|
+
logLevel: "info",
|
|
65
|
+
incremental: watch,
|
|
66
|
+
plugins: [sassPlugin()],
|
|
67
|
+
});
|
|
68
|
+
await build_ts();
|
|
69
|
+
watch && scss_build?.rebuild?.();
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function buildProject(...args: string[]): Promise<void> {
|
|
76
|
+
const watch = args.includes("--watch");
|
|
77
|
+
await build({
|
|
78
|
+
entryPoints: ["./src/front/index.ts"],
|
|
79
|
+
sourcemap: true,
|
|
80
|
+
outfile: "./public/dist/bundle.js",
|
|
81
|
+
logLevel: "info",
|
|
82
|
+
bundle: true,
|
|
83
|
+
watch,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await complex_build(watch);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
90
|
+
console.error(e.message);
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addCollection } from "./add-collection";
|
|
3
|
+
import { addRoute } from "./add-route";
|
|
4
|
+
import { buildProject } from "./build";
|
|
5
|
+
import { generateScssIncludes } from "./find-scss-includes";
|
|
6
|
+
import { generateCollections } from "./generate-collections";
|
|
7
|
+
import { generateRoutes } from "./generate-routes";
|
|
8
|
+
|
|
9
|
+
const actions: Record<
|
|
10
|
+
string,
|
|
11
|
+
(...args: string[]) => Promise<void> | undefined
|
|
12
|
+
> = {
|
|
13
|
+
"add-collection": addCollection,
|
|
14
|
+
"add-route": addRoute,
|
|
15
|
+
"generate-collections": generateCollections,
|
|
16
|
+
"generate-routes": generateRoutes,
|
|
17
|
+
"generate-scss-includes": generateScssIncludes,
|
|
18
|
+
build: buildProject,
|
|
19
|
+
default: async function () {
|
|
20
|
+
console.log("Usage: `sealscript <action>`");
|
|
21
|
+
console.log(
|
|
22
|
+
`Available actions: ${Object.keys(actions)
|
|
23
|
+
.filter((e) => e != "default")
|
|
24
|
+
.join(", ")}`
|
|
25
|
+
);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
void (async function () {
|
|
30
|
+
const action = process.argv.at(2);
|
|
31
|
+
actions;
|
|
32
|
+
const fn = actions[action || "default"] || actions.default;
|
|
33
|
+
await fn(...process.argv.slice(3));
|
|
34
|
+
})();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { promises as fs } from "fs";
|
|
2
2
|
import _locreq from "locreq";
|
|
3
3
|
import { relative } from "path";
|
|
4
|
-
import {
|
|
4
|
+
import { walkDir } from "./utils/walk";
|
|
5
5
|
|
|
6
6
|
const target_locreq = _locreq(process.cwd());
|
|
7
7
|
|
|
8
8
|
export async function generateScssIncludes(): Promise<void> {
|
|
9
9
|
const files = await Promise.all(
|
|
10
|
-
(await
|
|
10
|
+
(await walkDir(target_locreq.resolve("src/")))
|
|
11
11
|
.filter(
|
|
12
12
|
(f) =>
|
|
13
13
|
f.endsWith(".scss") &&
|
|
@@ -23,6 +23,7 @@ export async function generateScssIncludes(): Promise<void> {
|
|
|
23
23
|
target_locreq.resolve("src/includes.scss"),
|
|
24
24
|
`// DO NOT EDIT! This file is generated automaticaly with npx sealgen generate-scss-includes
|
|
25
25
|
|
|
26
|
+
@import "../node_modules/@sealcode/sealgen/src/forms/forms.scss";
|
|
26
27
|
${files.map((path) => `@import "${path}";`).join("\n")}
|
|
27
28
|
`
|
|
28
29
|
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { is, predicates } from "@sealcode/ts-predicates";
|
|
2
|
+
import { BaseContext } from "koa";
|
|
3
|
+
import { tempstream } from "tempstream";
|
|
4
|
+
import { ChekboxedListField, FormField } from "../field";
|
|
5
|
+
import { Form, FormData } from "../form";
|
|
6
|
+
import { FormFieldsList } from "../form-fields-list";
|
|
7
|
+
import { FormFieldControl } from "./controls";
|
|
8
|
+
|
|
9
|
+
export class CheckboxedListInput extends FormFieldControl {
|
|
10
|
+
constructor(
|
|
11
|
+
public fieldname: string,
|
|
12
|
+
public options: { label: string } = { label: fieldname }
|
|
13
|
+
) {
|
|
14
|
+
super([fieldname]);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
isValidFieldName(form: Form) {
|
|
18
|
+
return form.fields.some((f) => f.name == this.fieldname);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async _render(ctx: BaseContext, fields: FormField[], data: FormData) {
|
|
22
|
+
// safe to disable this as isValidFieldName takes care of checking if the field is of this type
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
24
|
+
const field = FormFieldsList.getField(
|
|
25
|
+
fields,
|
|
26
|
+
this.fieldname
|
|
27
|
+
) as ChekboxedListField;
|
|
28
|
+
const pickedValues = data.values[field.name] || "";
|
|
29
|
+
if (!is(pickedValues, predicates.array(predicates.string))) {
|
|
30
|
+
throw new Error("picked values is not an array of strings");
|
|
31
|
+
}
|
|
32
|
+
const [options, isVisible] = await Promise.all([
|
|
33
|
+
field.generateOptions(ctx),
|
|
34
|
+
field.isVisible(ctx),
|
|
35
|
+
]);
|
|
36
|
+
return tempstream/* HTML */ `${isVisible
|
|
37
|
+
? Object.entries(options).map(
|
|
38
|
+
([value, text]) => /* HTML */ `<div>
|
|
39
|
+
<input
|
|
40
|
+
type="checkbox"
|
|
41
|
+
id="${field.name}.${value}"
|
|
42
|
+
name="${field.name}.${value}"
|
|
43
|
+
${pickedValues.includes(value) ? "checked" : ""}
|
|
44
|
+
/>
|
|
45
|
+
<label for="${field.name}.${value}">${text}</label>
|
|
46
|
+
</div>`
|
|
47
|
+
)
|
|
48
|
+
: ""}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { FormControl } from "./form-control";
|
|
2
|
+
export { FormFieldControl } from "./form-field-control";
|
|
3
|
+
export { EditableCollectionSubset } from "./editable-collection-subset";
|
|
4
|
+
export { Frame } from "./frame";
|
|
5
|
+
export { CheckboxedListInput } from "./checkboxed-list-input";
|
|
6
|
+
export { Dropdown } from "./dropdown";
|
|
7
|
+
export { SimpleInput } from "./simple-input";
|
|
8
|
+
export { FormHeader } from "./form-header";
|
|
9
|
+
export { FormParagraph } from "./form-paragraph";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { tempstream } from "tempstream";
|
|
3
|
+
import { FormField, PickFromListField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormFieldsList } from "../form-fields-list";
|
|
6
|
+
import { FormFieldControl } from "./controls";
|
|
7
|
+
|
|
8
|
+
export class Dropdown extends FormFieldControl {
|
|
9
|
+
constructor(
|
|
10
|
+
public fieldname: string,
|
|
11
|
+
public options: {
|
|
12
|
+
label: string;
|
|
13
|
+
autosubmit?: boolean;
|
|
14
|
+
autocomplete?: boolean;
|
|
15
|
+
} = {
|
|
16
|
+
label: fieldname,
|
|
17
|
+
autosubmit: false,
|
|
18
|
+
autocomplete: true,
|
|
19
|
+
}
|
|
20
|
+
) {
|
|
21
|
+
super([fieldname]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
areFieldNamesValid(fields: FormField[]) {
|
|
25
|
+
return (
|
|
26
|
+
super.areFieldNamesValid(fields) &&
|
|
27
|
+
FormFieldsList.getField(fields, this.fieldname) instanceof PickFromListField
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_render(ctx: BaseContext, fields: FormField[], data: FormData) {
|
|
32
|
+
// safe to disable this as isValidFieldName takes care of checking if the field is of this type
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
34
|
+
const field = FormFieldsList.getField(
|
|
35
|
+
fields,
|
|
36
|
+
this.fieldname
|
|
37
|
+
) as PickFromListField;
|
|
38
|
+
const picked_value = data.values[field.name] || "";
|
|
39
|
+
const id = field.name;
|
|
40
|
+
return tempstream/* HTML */ `<label for="${id}">${this.options.label}</label
|
|
41
|
+
><select
|
|
42
|
+
name="${this.fieldnames}"
|
|
43
|
+
id="${id}"
|
|
44
|
+
${this.options.autosubmit ? `onchange='this.form.submit()'` : ""}
|
|
45
|
+
${!this.options.autocomplete ? `autocomplete="off"` : ""}
|
|
46
|
+
>
|
|
47
|
+
${Promise.resolve(field.generateOptions(ctx)).then((options) =>
|
|
48
|
+
Object.entries(options).map(
|
|
49
|
+
([value, text]) =>
|
|
50
|
+
`<option value="${value}" ${
|
|
51
|
+
(value || "") == picked_value ? "selected" : ""
|
|
52
|
+
}>${text}</option>`
|
|
53
|
+
)
|
|
54
|
+
)}
|
|
55
|
+
</select>`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable, tempstream } from "tempstream";
|
|
3
|
+
import { FormField, PickFromListField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormFieldsList } from "../form-fields-list";
|
|
6
|
+
import { FormFieldControl } from "./controls";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This control has own forms in it so if you want to use it you
|
|
10
|
+
* probably shouldn't use `await super.render(ctx, data, path)` in
|
|
11
|
+
* render method of you from implementation and you should write
|
|
12
|
+
* your own implementation of this method. See forms that uses
|
|
13
|
+
* this control for reference.
|
|
14
|
+
*/
|
|
15
|
+
export class EditableCollectionSubset extends FormFieldControl {
|
|
16
|
+
constructor(
|
|
17
|
+
public fieldname: string,
|
|
18
|
+
public actionname: string,
|
|
19
|
+
public listLabel?: string,
|
|
20
|
+
public selectLabel?: string
|
|
21
|
+
) {
|
|
22
|
+
super([fieldname]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_render(
|
|
26
|
+
ctx: BaseContext,
|
|
27
|
+
fields: FormField[],
|
|
28
|
+
data: FormData<string>
|
|
29
|
+
): Templatable | Promise<Templatable> {
|
|
30
|
+
// safe to disable this as isValidFieldName takes care of checking if the field is of this type
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
32
|
+
const field = FormFieldsList.getField(
|
|
33
|
+
fields,
|
|
34
|
+
this.fieldname
|
|
35
|
+
) as PickFromListField;
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37
|
+
const values = data.values[this.fieldname] as string[];
|
|
38
|
+
|
|
39
|
+
return tempstream/* HTML */ `<div>
|
|
40
|
+
<ul>
|
|
41
|
+
${Promise.resolve(field.generateOptions(ctx)).then((options) =>
|
|
42
|
+
Object.entries(options)
|
|
43
|
+
.filter(([value]) => values.includes(value))
|
|
44
|
+
.map(
|
|
45
|
+
([value, text]) => /* HTML */ `
|
|
46
|
+
<li>
|
|
47
|
+
<form method="POST" action="${ctx.path}">
|
|
48
|
+
<span>${text}</span>
|
|
49
|
+
<input
|
|
50
|
+
type="hidden"
|
|
51
|
+
name="${this.fieldname}"
|
|
52
|
+
value="${value}"
|
|
53
|
+
/>
|
|
54
|
+
<input
|
|
55
|
+
type="hidden"
|
|
56
|
+
name="${this.actionname}"
|
|
57
|
+
value="list"
|
|
58
|
+
/>
|
|
59
|
+
<input
|
|
60
|
+
type="submit"
|
|
61
|
+
${this.listLabel
|
|
62
|
+
? `value="${this.listLabel}"`
|
|
63
|
+
: ""}
|
|
64
|
+
/>
|
|
65
|
+
</form>
|
|
66
|
+
</li>
|
|
67
|
+
`
|
|
68
|
+
)
|
|
69
|
+
)}
|
|
70
|
+
</ul>
|
|
71
|
+
<form method="POST" action="${ctx.path}">
|
|
72
|
+
<select name="${this.fieldname}">
|
|
73
|
+
${Promise.resolve(field.generateOptions(ctx)).then((options) =>
|
|
74
|
+
Object.entries(options)
|
|
75
|
+
.filter(([value]) => !values.includes(value))
|
|
76
|
+
.map(
|
|
77
|
+
([value, text]) =>
|
|
78
|
+
`<option value="${value}">${text}</option>`
|
|
79
|
+
)
|
|
80
|
+
)}
|
|
81
|
+
</select>
|
|
82
|
+
<input type="hidden" name="${this.actionname}" value="select" />
|
|
83
|
+
<input
|
|
84
|
+
type="submit"
|
|
85
|
+
${this.selectLabel ? `value="${this.selectLabel}"` : ""}
|
|
86
|
+
/>
|
|
87
|
+
</form>
|
|
88
|
+
</div>`;
|
|
89
|
+
}
|
|
90
|
+
role = <const>"input";
|
|
91
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable } from "tempstream";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
|
|
6
|
+
export abstract class FormControl {
|
|
7
|
+
abstract render(
|
|
8
|
+
ctx: BaseContext,
|
|
9
|
+
formFields: FormField[],
|
|
10
|
+
data: FormData
|
|
11
|
+
): Templatable | Promise<Templatable>;
|
|
12
|
+
abstract role: "input" | "decoration" | "messages" | "submit";
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BaseContext } from "koa";
|
|
2
|
+
import { Templatable } from "tempstream";
|
|
3
|
+
import { FormField } from "../field";
|
|
4
|
+
import { FormData } from "../form";
|
|
5
|
+
import { FormControl } from "./form-control";
|
|
6
|
+
|
|
7
|
+
export abstract class FormFieldControl extends FormControl {
|
|
8
|
+
role = <const>"input";
|
|
9
|
+
constructor(public fieldnames: string[]) {
|
|
10
|
+
super();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
areFieldNamesValid(fields: FormField[]) {
|
|
14
|
+
return this.fieldnames.every((fieldname) =>
|
|
15
|
+
fields.some((f) => f.name == fieldname)
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
abstract _render(
|
|
20
|
+
ctx: BaseContext,
|
|
21
|
+
fields: FormField[],
|
|
22
|
+
data: FormData
|
|
23
|
+
): Templatable | Promise<Templatable>;
|
|
24
|
+
|
|
25
|
+
render(
|
|
26
|
+
ctx: BaseContext,
|
|
27
|
+
fields: FormField[],
|
|
28
|
+
data: FormData
|
|
29
|
+
): Templatable | Promise<Templatable> {
|
|
30
|
+
if (!this.areFieldNamesValid(fields)) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Invalid field names given to form control: "${this.fieldnames.join(
|
|
33
|
+
", "
|
|
34
|
+
)}". Allowed fields are: ${fields.map((f) => f.name).join(", ")}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return this._render(ctx, fields, data);
|
|
38
|
+
}
|
|
39
|
+
}
|