@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.
Files changed (146) hide show
  1. package/.eslintrc.js +1 -0
  2. package/@types/build.d.ts +1 -0
  3. package/@types/cli.d.ts +2 -0
  4. package/@types/forms/controls/checkboxed-list-input.d.ts +16 -0
  5. package/@types/forms/controls/controls.d.ts +9 -0
  6. package/@types/forms/controls/dropdown.d.ts +20 -0
  7. package/@types/forms/controls/editable-collection-subset.d.ts +21 -0
  8. package/@types/forms/controls/form-control.d.ts +8 -0
  9. package/@types/forms/controls/form-field-control.d.ts +13 -0
  10. package/@types/forms/controls/form-header.d.ts +9 -0
  11. package/@types/forms/controls/form-paragraph.d.ts +7 -0
  12. package/@types/forms/controls/frame.d.ts +17 -0
  13. package/@types/forms/controls/simple-input.d.ts +28 -0
  14. package/@types/forms/controls.d.ts +0 -0
  15. package/@types/forms/field.d.ts +42 -0
  16. package/@types/forms/form-fields-list.d.ts +4 -0
  17. package/@types/forms/form.d.ts +42 -0
  18. package/@types/forms/validator.d.ts +3 -0
  19. package/@types/index.d.ts +15 -2
  20. package/@types/page/access-control.d.ts +6 -0
  21. package/@types/page/list.d.ts +59 -0
  22. package/@types/page/page.d.ts +26 -0
  23. package/@types/page/props-parser.d.ts +20 -0
  24. package/@types/run.d.ts +0 -0
  25. package/@types/templates/page.d.ts +1 -1
  26. package/@types/utils/natural-numbers.d.ts +1 -0
  27. package/@types/utils/sleep.d.ts +1 -0
  28. package/@types/utils/url-with-new-params.d.ts +2 -0
  29. package/@types/utils/utils.d.ts +9 -0
  30. package/@types/utils/walk.d.ts +1 -1
  31. package/lib/build.js +116 -0
  32. package/lib/build.js.map +1 -0
  33. package/lib/cli.js +30 -0
  34. package/lib/cli.js.map +1 -0
  35. package/lib/find-scss-includes.js +2 -1
  36. package/lib/find-scss-includes.js.map +1 -1
  37. package/lib/forms/controls/checkboxed-list-input.js +43 -0
  38. package/lib/forms/controls/checkboxed-list-input.js.map +1 -0
  39. package/lib/forms/controls/controls.js +22 -0
  40. package/lib/forms/controls/controls.js.map +1 -0
  41. package/lib/forms/controls/dropdown.js +40 -0
  42. package/lib/forms/controls/dropdown.js.map +1 -0
  43. package/lib/forms/controls/editable-collection-subset.js +73 -0
  44. package/lib/forms/controls/editable-collection-subset.js.map +1 -0
  45. package/lib/forms/controls/form-control.js +7 -0
  46. package/lib/forms/controls/form-control.js.map +1 -0
  47. package/lib/forms/controls/form-field-control.js +22 -0
  48. package/lib/forms/controls/form-field-control.js.map +1 -0
  49. package/lib/forms/controls/form-header.js +18 -0
  50. package/lib/forms/controls/form-header.js.map +1 -0
  51. package/lib/forms/controls/form-paragraph.js +16 -0
  52. package/lib/forms/controls/form-paragraph.js.map +1 -0
  53. package/lib/forms/controls/frame.js +29 -0
  54. package/lib/forms/controls/frame.js.map +1 -0
  55. package/lib/forms/controls/simple-input.js +50 -0
  56. package/lib/forms/controls/simple-input.js.map +1 -0
  57. package/lib/forms/controls.js +1 -0
  58. package/lib/forms/controls.js.map +1 -0
  59. package/lib/forms/field.js +80 -0
  60. package/lib/forms/field.js.map +1 -0
  61. package/lib/forms/form-fields-list.js +10 -0
  62. package/lib/forms/form-fields-list.js.map +1 -0
  63. package/lib/forms/form.js +162 -0
  64. package/lib/forms/form.js.map +1 -0
  65. package/lib/forms/validator.js +11 -0
  66. package/lib/forms/validator.js.map +1 -0
  67. package/lib/generate-routes.js +11 -4
  68. package/lib/generate-routes.js.map +1 -1
  69. package/lib/index.js +18 -25
  70. package/lib/index.js.map +1 -1
  71. package/lib/page/access-control.js +20 -0
  72. package/lib/page/access-control.js.map +1 -0
  73. package/lib/page/list.js +148 -0
  74. package/lib/page/list.js.map +1 -0
  75. package/lib/page/page.js +20 -0
  76. package/lib/page/page.js.map +1 -0
  77. package/lib/page/props-parser.js +74 -0
  78. package/lib/page/props-parser.js.map +1 -0
  79. package/lib/run.js +1 -0
  80. package/lib/run.js.map +1 -0
  81. package/lib/templates/form.js +10 -5
  82. package/lib/templates/form.js.map +1 -1
  83. package/lib/templates/list.js +3 -3
  84. package/lib/templates/list.js.map +1 -1
  85. package/lib/templates/page.js +5 -4
  86. package/lib/templates/page.js.map +1 -1
  87. package/lib/utils/escape-url-params.js +1 -0
  88. package/lib/utils/escape-url-params.js.map +1 -1
  89. package/lib/utils/list-collections.js +1 -1
  90. package/lib/utils/list-collections.js.map +1 -1
  91. package/lib/utils/natural-numbers.js +10 -0
  92. package/lib/utils/natural-numbers.js.map +1 -0
  93. package/lib/utils/sleep.js +8 -0
  94. package/lib/utils/sleep.js.map +1 -0
  95. package/lib/utils/url-with-new-params.js +12 -0
  96. package/lib/utils/url-with-new-params.js.map +1 -0
  97. package/lib/utils/utils.js +19 -0
  98. package/lib/utils/utils.js.map +1 -0
  99. package/lib/utils/walk.js +4 -4
  100. package/lib/utils/walk.js.map +1 -1
  101. package/package.json +17 -4
  102. package/src/build.ts +92 -0
  103. package/src/cli.ts +34 -0
  104. package/src/find-scss-includes.ts +3 -2
  105. package/src/forms/controls/checkboxed-list-input.ts +50 -0
  106. package/src/forms/controls/controls.ts +9 -0
  107. package/src/forms/controls/dropdown.ts +57 -0
  108. package/src/forms/controls/editable-collection-subset.ts +91 -0
  109. package/src/forms/controls/form-control.ts +13 -0
  110. package/src/forms/controls/form-field-control.ts +39 -0
  111. package/src/forms/controls/form-header.ts +16 -0
  112. package/src/forms/controls/form-paragraph.ts +11 -0
  113. package/src/forms/controls/frame.ts +26 -0
  114. package/src/forms/controls/simple-input.ts +73 -0
  115. package/src/forms/controls.ts +0 -0
  116. package/src/forms/field.ts +119 -0
  117. package/src/forms/form-fields-list.ts +7 -0
  118. package/src/forms/form.ts +242 -0
  119. package/src/forms/forms.scss +18 -0
  120. package/src/forms/validator.ts +10 -0
  121. package/src/generate-routes.ts +12 -9
  122. package/src/index.ts +15 -28
  123. package/src/page/access-control.ts +18 -0
  124. package/src/page/list.ts +214 -0
  125. package/src/page/page.ts +31 -0
  126. package/src/page/props-parser.ts +99 -0
  127. package/src/run.ts +0 -0
  128. package/src/templates/form.ts +10 -5
  129. package/src/templates/list.ts +3 -3
  130. package/src/templates/page.ts +6 -6
  131. package/src/utils/escape-url-params.ts +1 -0
  132. package/src/utils/list-collections.ts +2 -2
  133. package/src/utils/natural-numbers.ts +5 -0
  134. package/src/utils/sleep.ts +3 -0
  135. package/src/utils/url-with-new-params.ts +9 -0
  136. package/src/utils/utils.ts +10 -0
  137. package/src/utils/walk.ts +2 -2
  138. package/tsconfig.json +5 -2
  139. package/.log/ti-101379.log +0 -524
  140. package/.log/ti-131883.log +0 -505
  141. package/.log/ti-13490.log +0 -652
  142. package/.log/ti-138140.log +0 -505
  143. package/.log/ti-138288.log +0 -526
  144. package/.log/ti-46589.log +0 -675
  145. package/.log/tsserver.log +0 -1666
  146. 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;;;;;;UAMjC,GAAG,CAAC,uBAAuB,CAAC;kCACJ,GAAG,CAAC,+BAA+B,CAAC;;6BAEzC,WAAW;;4BAEZ,WAAW,4CAA4C,oBAAoB;;;;;;;;;eASxF,oBAAoB;;sBAEb,oBAAoB;;;;;;;;mEAQyB,oBAAoB;;;KAGlF,oBAAoB;CACxB,CAAC;AACF,CAAC,CAAC;AA5DW,QAAA,YAAY,gBA4DvB"}
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"}
@@ -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, fullpath) {
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 "${import_path_1.importPath(fullpath, "src/back/page/page")}";
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,sDAAkD;AAE3C,KAAK,UAAU,YAAY,CACjC,WAAmB,EACnB,QAAgB;IAEhB,OAAO;;wBAEgB,wBAAU,CAAC,QAAQ,EAAE,oBAAoB,CAAC;;6BAErC,WAAW;;4BAEZ,WAAW;;;;;;;;;;;CAWtC,CAAC;AACF,CAAC;AAtBD,oCAsBC"}
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"}
@@ -5,6 +5,7 @@ function escape_url_params(url) {
5
5
  return url
6
6
  .split("/")
7
7
  .map((e) => (e.startsWith(":") ? `[${e.slice(1)}]` : e))
8
+ .filter((e) => e != "")
8
9
  .join("/");
9
10
  }
10
11
  exports.escape_url_params = escape_url_params;
@@ -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;AALD,8CAKC;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"}
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.walk(target_locreq.resolve("src/back/collections"));
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,iCAA8B;AAC9B,MAAM,aAAa,GAAG,gBAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAEtC,KAAK,UAAU,eAAe;IACpC,MAAM,KAAK,GAAG,MAAM,WAAI,CAAC,aAAa,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACxE,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"}
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,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = void 0;
4
+ async function sleep(time) {
5
+ return new Promise((resolve) => setTimeout(resolve, time));
6
+ }
7
+ exports.sleep = sleep;
8
+ //# sourceMappingURL=sleep.js.map
@@ -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.walk = void 0;
3
+ exports.walkDir = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
- async function walk(dir) {
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 walk(fullpath))];
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.walk = walk;
23
+ exports.walkDir = walkDir;
24
24
  //# sourceMappingURL=walk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/utils/walk.ts"],"names":[],"mappings":";;;AAAA,2BAAoC;AACpC,+BAA+B;AAExB,KAAK,UAAU,IAAI,CAAC,GAAW;IACrC,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,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SAC1C;aAAM;YACN,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC;SACzB;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAhBD,oBAgBC"}
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.1",
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/index.js"
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
- "@sealcode/ts-predicates": "^0.2.1",
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
- "prompts": "^2.4.2"
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 { walk } from "./utils/walk";
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 walk(target_locreq.resolve("src/")))
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
+ }