@sealcode/sealgen 0.19.25 → 0.19.28

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 (247) hide show
  1. package/@types/forms/controls/dropdown.d.ts +6 -6
  2. package/@types/forms/controls/single-reference.d.ts +9 -6
  3. package/@types/forms/fields/field.d.ts +2 -2
  4. package/@types/forms/fields/pick-from-list.d.ts +2 -2
  5. package/@types/forms/fields/simple-form-field.d.ts +1 -1
  6. package/@types/forms/multiform.d.ts +4 -3
  7. package/@types/page/stateful-page.d.ts +1 -1
  8. package/@types/src/add-collection.d.ts +1 -0
  9. package/@types/src/add-crud.d.ts +3 -0
  10. package/@types/src/add-crud.test.d.ts +1 -0
  11. package/@types/src/add-jdd-component.d.ts +1 -0
  12. package/@types/src/add-list-route.test.d.ts +1 -0
  13. package/@types/src/add-route.d.ts +3 -0
  14. package/@types/src/add-route.test.d.ts +1 -0
  15. package/@types/src/build.d.ts +3 -0
  16. package/@types/src/builders/backend-ts-builder.d.ts +7 -0
  17. package/@types/src/builders/builder.d.ts +11 -0
  18. package/@types/src/builders/colors-builder.d.ts +10 -0
  19. package/@types/src/builders/css-builder.d.ts +19 -0
  20. package/@types/src/builders/fonts-builder.d.ts +7 -0
  21. package/@types/src/builders/frontend-ts-builder.d.ts +11 -0
  22. package/@types/src/cli.d.ts +2 -0
  23. package/@types/src/components/components.d.ts +2 -0
  24. package/@types/src/components/tabs.d.ts +2 -0
  25. package/@types/src/components/toggle-modal.d.ts +6 -0
  26. package/@types/src/controllers/password-generate-button.stimulus.d.ts +5 -0
  27. package/@types/src/controllers/sealgen-table.stimulus.d.ts +13 -0
  28. package/@types/src/embeddable-file-extensions.d.ts +1 -0
  29. package/@types/src/esbuild-plugins/load-assets.d.ts +5 -0
  30. package/@types/src/esbuild-plugins/rewrite-asset-imports.d.ts +5 -0
  31. package/@types/src/example.test.d.ts +1 -0
  32. package/@types/src/forms/controls/array.d.ts +33 -0
  33. package/@types/src/forms/controls/autocomplete.d.ts +22 -0
  34. package/@types/src/forms/controls/big-radio-group.d.ts +14 -0
  35. package/@types/src/forms/controls/checkbox-group.d.ts +21 -0
  36. package/@types/src/forms/controls/checkbox.d.ts +17 -0
  37. package/@types/src/forms/controls/checkboxed-list-input.d.ts +21 -0
  38. package/@types/src/forms/controls/checkboxed-list-input.test.d.ts +1 -0
  39. package/@types/src/forms/controls/collapsible-checkbox-group.d.ts +11 -0
  40. package/@types/src/forms/controls/collapsible-field-group.d.ts +21 -0
  41. package/@types/src/forms/controls/controls.d.ts +32 -0
  42. package/@types/src/forms/controls/derived-frame.d.ts +19 -0
  43. package/@types/src/forms/controls/derived.d.ts +13 -0
  44. package/@types/src/forms/controls/dropdown.d.ts +30 -0
  45. package/@types/src/forms/controls/editable-collection-subset.d.ts +20 -0
  46. package/@types/src/forms/controls/field-group.d.ts +23 -0
  47. package/@types/src/forms/controls/file.d.ts +12 -0
  48. package/@types/src/forms/controls/file.test.d.ts +1 -0
  49. package/@types/src/forms/controls/form-control.d.ts +23 -0
  50. package/@types/src/forms/controls/form-field-control.d.ts +13 -0
  51. package/@types/src/forms/controls/form-header.d.ts +8 -0
  52. package/@types/src/forms/controls/form-paragraph.d.ts +7 -0
  53. package/@types/src/forms/controls/frame.d.ts +17 -0
  54. package/@types/src/forms/controls/hidden-input.d.ts +9 -0
  55. package/@types/src/forms/controls/html.d.ts +11 -0
  56. package/@types/src/forms/controls/hybrid.d.ts +10 -0
  57. package/@types/src/forms/controls/image.d.ts +19 -0
  58. package/@types/src/forms/controls/image.test.d.ts +1 -0
  59. package/@types/src/forms/controls/multiple-files.d.ts +42 -0
  60. package/@types/src/forms/controls/multiple-images.d.ts +19 -0
  61. package/@types/src/forms/controls/number.d.ts +13 -0
  62. package/@types/src/forms/controls/password-with-generator.d.ts +6 -0
  63. package/@types/src/forms/controls/radio.d.ts +16 -0
  64. package/@types/src/forms/controls/simple-input.d.ts +35 -0
  65. package/@types/src/forms/controls/single-reference.d.ts +14 -0
  66. package/@types/src/forms/controls/single-reference.test.d.ts +1 -0
  67. package/@types/{forms/controls/table.d.sync-conflict-20260502-145940-GP5D735.ts → src/forms/controls/table.d.ts} +2 -0
  68. package/@types/src/forms/controls/textarea.d.ts +25 -0
  69. package/@types/src/forms/controls/tickable.d.ts +25 -0
  70. package/@types/src/forms/fields/boolean.d.ts +22 -0
  71. package/@types/src/forms/fields/boolean.test.d.ts +1 -0
  72. package/@types/src/forms/fields/checkboxed-list.d.ts +23 -0
  73. package/@types/src/forms/fields/collection-field.d.ts +22 -0
  74. package/@types/src/forms/fields/color.d.ts +4 -0
  75. package/@types/src/forms/fields/coordinates.d.ts +14 -0
  76. package/@types/src/forms/fields/date.d.ts +13 -0
  77. package/@types/src/forms/fields/datetime.d.ts +14 -0
  78. package/@types/src/forms/fields/deep-reverse-single-reference-list.d.ts +20 -0
  79. package/@types/src/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
  80. package/@types/src/forms/fields/email.d.ts +10 -0
  81. package/@types/src/forms/fields/email.test.d.ts +1 -0
  82. package/@types/src/forms/fields/enum-multiple-sealious.d.ts +16 -0
  83. package/@types/src/forms/fields/existing-sealious-value.d.ts +6 -0
  84. package/@types/src/forms/fields/field.d.ts +85 -0
  85. package/@types/src/forms/fields/field.test.d.ts +1 -0
  86. package/@types/src/forms/fields/fields.d.ts +34 -0
  87. package/@types/src/forms/fields/file.d.ts +25 -0
  88. package/@types/src/forms/fields/file.test.d.ts +1 -0
  89. package/@types/src/forms/fields/float.d.ts +4 -0
  90. package/@types/src/forms/fields/get-field-for-sealious.d.ts +33 -0
  91. package/@types/src/forms/fields/html.d.ts +6 -0
  92. package/@types/src/forms/fields/hybrid.d.ts +11 -0
  93. package/@types/src/forms/fields/image.d.ts +5 -0
  94. package/@types/src/forms/fields/int.d.ts +6 -0
  95. package/@types/src/forms/fields/item-draft.d.ts +20 -0
  96. package/@types/src/forms/fields/json.d.ts +13 -0
  97. package/@types/src/forms/fields/markdown.d.ts +6 -0
  98. package/@types/src/forms/fields/multiple-files.d.ts +16 -0
  99. package/@types/src/forms/fields/number.d.ts +25 -0
  100. package/@types/src/forms/fields/number.test.d.ts +1 -0
  101. package/@types/src/forms/fields/password.d.ts +10 -0
  102. package/@types/src/forms/fields/phone-number-with-country-code.d.ts +13 -0
  103. package/@types/src/forms/fields/phone-number.d.ts +17 -0
  104. package/@types/src/forms/fields/pick-from-list-sealious.d.ts +11 -0
  105. package/@types/src/forms/fields/pick-from-list.d.ts +15 -0
  106. package/@types/src/forms/fields/pick-from-list.test.d.ts +1 -0
  107. package/@types/src/forms/fields/proxy-field.d.ts +15 -0
  108. package/@types/src/forms/fields/regexp.d.ts +21 -0
  109. package/@types/src/forms/fields/regexp.test.d.ts +1 -0
  110. package/@types/src/forms/fields/simple-form-field.d.ts +31 -0
  111. package/@types/src/forms/fields/single-reference.d.ts +19 -0
  112. package/@types/src/forms/fields/structured-array.d.ts +23 -0
  113. package/@types/src/forms/fields/table.d.ts +16 -0
  114. package/@types/src/forms/fields/text.d.ts +6 -0
  115. package/@types/src/forms/fields/url.d.ts +6 -0
  116. package/@types/src/forms/form-types.d.ts +28 -0
  117. package/@types/src/forms/form.d.ts +34 -0
  118. package/@types/src/forms/form.test.d.ts +6 -0
  119. package/@types/src/forms/multiform.d.ts +23 -0
  120. package/@types/src/forms/multiform.test.d.ts +1 -0
  121. package/@types/src/generate-collections.d.ts +2 -0
  122. package/@types/src/generate-components.d.ts +1 -0
  123. package/@types/src/generate-routes.d.ts +5 -0
  124. package/@types/src/generate-routes.test.d.ts +1 -0
  125. package/@types/src/generate-stimulus.d.ts +1 -0
  126. package/@types/src/get-fonts.d.ts +2 -0
  127. package/@types/{index.d.sync-conflict-20260502-145557-GP5D735.ts → src/index.d.ts} +1 -0
  128. package/@types/src/make-env.d.ts +1 -0
  129. package/@types/src/make-hidden-inputs.d.ts +5 -0
  130. package/@types/src/mount.d.ts +6 -0
  131. package/@types/src/notifier.d.ts +2 -0
  132. package/@types/src/page/access-control.d.ts +6 -0
  133. package/@types/src/page/default-list-filters.d.ts +18 -0
  134. package/@types/src/page/list.d.ts +49 -0
  135. package/@types/src/page/mountable-with-fields.d.ts +49 -0
  136. package/@types/src/page/mountable-with-fields.test.d.ts +1 -0
  137. package/@types/src/page/mountable.d.ts +10 -0
  138. package/@types/src/page/page.d.ts +18 -0
  139. package/@types/src/page/props-parser.d.ts +15 -0
  140. package/@types/src/page/sealious-list.d.ts +20 -0
  141. package/@types/src/page/sealious-list.test.d.ts +1 -0
  142. package/@types/src/page/stateful-page.d.ts +63 -0
  143. package/@types/src/page/stateful-page.test.d.ts +1 -0
  144. package/@types/src/register-external.d.ts +2 -0
  145. package/@types/src/register-external.test.d.ts +1 -0
  146. package/@types/src/run.d.ts +1 -0
  147. package/@types/src/sanitize.d.ts +1 -0
  148. package/@types/src/target-locreq.d.ts +4 -0
  149. package/@types/src/templates/collection.d.ts +1 -0
  150. package/@types/src/templates/form.d.ts +14 -0
  151. package/@types/src/templates/form.test.d.ts +1 -0
  152. package/@types/src/templates/jdd-component.d.ts +1 -0
  153. package/@types/src/templates/jdd-editor.d.ts +1 -0
  154. package/@types/src/templates/list.d.ts +1 -0
  155. package/@types/src/templates/long-running-process.d.ts +1 -0
  156. package/@types/src/templates/multiform.d.ts +1 -0
  157. package/@types/src/templates/page.d.ts +1 -0
  158. package/@types/src/templates/post.d.ts +1 -0
  159. package/@types/src/templates/redirect.d.ts +1 -0
  160. package/@types/src/templates/route-test.d.ts +1 -0
  161. package/@types/src/templates/shared/collection-create-form.d.ts +1 -0
  162. package/@types/src/templates/shared/collection-edit-form.d.ts +1 -0
  163. package/@types/src/templates/shared/collection-list.d.ts +16 -0
  164. package/@types/src/templates/shared/item-delete.d.ts +1 -0
  165. package/@types/src/templates/shared/shared-crud-form-fields.d.ts +1 -0
  166. package/@types/src/templates/stateful-page.d.ts +1 -0
  167. package/@types/src/templates/stimulus-controller.d.ts +1 -0
  168. package/@types/src/templates/templates.d.ts +1 -0
  169. package/@types/src/test_utils/exec_async.d.ts +1 -0
  170. package/@types/src/test_utils/locator_is_visible.d.ts +2 -0
  171. package/@types/src/test_utils/test-on-real-app.d.ts +26 -0
  172. package/@types/src/utils/assert-throws.d.ts +1 -0
  173. package/@types/src/utils/base64.d.ts +2 -0
  174. package/@types/src/utils/browser-creator.d.ts +1 -0
  175. package/@types/src/utils/escape-url-params.d.ts +2 -0
  176. package/@types/src/utils/exec.d.ts +5 -0
  177. package/@types/src/utils/extract-fields-from-collection.d.ts +14 -0
  178. package/@types/src/utils/format-external-url.d.ts +1 -0
  179. package/@types/src/utils/import-path.d.ts +2 -0
  180. package/@types/src/utils/input-wrapper.d.ts +5 -0
  181. package/@types/src/utils/list-collections.d.ts +1 -0
  182. package/@types/src/utils/make-slug.d.ts +1 -0
  183. package/@types/src/utils/module-dirname.d.ts +1 -0
  184. package/@types/src/utils/natural-numbers.d.ts +1 -0
  185. package/@types/src/utils/prettier.d.ts +3 -0
  186. package/@types/src/utils/question.d.ts +1 -0
  187. package/@types/src/utils/render-attributes.d.ts +1 -0
  188. package/@types/src/utils/sleep.d.ts +1 -0
  189. package/@types/src/utils/translate.d.ts +4 -0
  190. package/@types/src/utils/url-with-new-params.d.ts +2 -0
  191. package/@types/src/utils/utils.d.ts +17 -0
  192. package/@types/src/utils/walk.d.ts +1 -0
  193. package/@types/src/utils/with-fallback.d.ts +2 -0
  194. package/@types/src/utils/wrap-attributes.d.ts +3 -0
  195. package/@types/src/utils/write-file.d.ts +1 -0
  196. package/lib/add-crud.test.js +1 -1
  197. package/lib/add-route.js +1 -3
  198. package/lib/builders/backend-ts-builder.js +1 -1
  199. package/lib/builders/colors-builder.js +4 -5
  200. package/lib/forms/controls/file.js +1 -1
  201. package/lib/forms/controls/multiple-files.js +6 -5
  202. package/lib/forms/controls/single-reference.js +4 -1
  203. package/lib/forms/fields/file.js +5 -5
  204. package/lib/forms/fields/image.js +1 -3
  205. package/lib/forms/fields/phone-number-with-country-code.js +0 -1
  206. package/lib/forms/fields/simple-form-field.js +1 -1
  207. package/lib/forms/fields/structured-array.js +1 -2
  208. package/lib/get-fonts.js +5 -1
  209. package/lib/page/mountable-with-fields.js +1 -2
  210. package/lib/page/mountable-with-fields.test.js +1 -1
  211. package/lib/page/sealious-list.js +3 -1
  212. package/package.json +3 -3
  213. package/src/add-route.ts +6 -8
  214. package/src/build.ts +1 -2
  215. package/src/builders/colors-builder.ts +11 -12
  216. package/src/cli.ts +4 -5
  217. package/src/controllers/sealgen-table.stimulus.ts +3 -3
  218. package/src/forms/controls/dropdown.ts +15 -13
  219. package/src/forms/controls/file.ts +1 -1
  220. package/src/forms/controls/multiple-files.ts +9 -12
  221. package/src/forms/controls/number.ts +8 -8
  222. package/src/forms/controls/single-reference.ts +25 -12
  223. package/src/forms/controls/table.ts +2 -2
  224. package/src/forms/controls/textarea.ts +4 -3
  225. package/src/forms/controls/tickable.ts +2 -2
  226. package/src/forms/fields/deep-reverse-single-reference-list.ts +2 -5
  227. package/src/forms/fields/deep-reverse-single-reference-table.ts +16 -14
  228. package/src/forms/fields/field.ts +4 -4
  229. package/src/forms/fields/file.ts +27 -21
  230. package/src/forms/fields/image.ts +1 -5
  231. package/src/forms/fields/phone-number-with-country-code.ts +1 -2
  232. package/src/forms/fields/pick-from-list.ts +2 -2
  233. package/src/forms/fields/simple-form-field.ts +3 -3
  234. package/src/forms/fields/structured-array.ts +2 -3
  235. package/src/forms/fields/table.ts +4 -7
  236. package/src/forms/multiform.ts +9 -6
  237. package/src/generate-routes.ts +3 -3
  238. package/src/get-fonts.ts +7 -3
  239. package/src/notifier.ts +1 -2
  240. package/src/page/list.ts +4 -4
  241. package/src/page/mountable-with-fields.test.ts +1 -1
  242. package/src/page/mountable-with-fields.ts +4 -4
  243. package/src/page/sealious-list.ts +17 -8
  244. package/src/page/stateful-page.ts +3 -3
  245. package/src/templates/jdd-editor.ts +1 -1
  246. package/src/test_utils/test-on-real-app.ts +5 -5
  247. package/tsconfig.json +3 -0
@@ -0,0 +1,2 @@
1
+ export declare function withFallback<T1, T2 extends NonNullable<unknown>>(value1: T1, value2: T2): NonNullable<T1> | T2;
2
+ export declare function withFallback<T1, T2, T3 extends NonNullable<unknown>>(value1: T1, value2: T2, value3?: T3): NonNullable<T2> | T3;
@@ -0,0 +1,3 @@
1
+ export declare function needsQuotes(str: string): boolean;
2
+ export declare function wrapAttribute(name: string): string;
3
+ export declare function wrapKeyName(name: string): string;
@@ -0,0 +1 @@
1
+ export declare function writeFile(path: string, content: string): Promise<void>;
@@ -10,7 +10,7 @@ describe("add crud test", () => {
10
10
  after(async () => {
11
11
  await page.close();
12
12
  });
13
- it.only("Generate simple sealious crud", async function() {
13
+ it("Generate simple sealious crud", async function() {
14
14
  const test_app = await RealAppTest.init();
15
15
  const path = "/sample";
16
16
  await test_app.runSealgenCommand(`add-collection --collection_name=sealcode-test`);
package/lib/add-route.js CHANGED
@@ -46,9 +46,7 @@ async function addRoute(params, app_directory = process.cwd()) {
46
46
  }
47
47
  ]);
48
48
  const { action, url, mode } = response;
49
- const extension = ["list", "lpr", "page", "sreact", "jdd-editor"].includes(
50
- mode
51
- ) ? "tsx" : "ts";
49
+ const extension = ["list", "lpr", "page", "sreact", "jdd-editor"].includes(mode) ? "tsx" : "ts";
52
50
  const base_file_name = escape_url_params(url) || "index";
53
51
  const file_path = target_locreq.resolve(
54
52
  `src/back/routes/${base_file_name}.${mode}.${extension}`
@@ -14,7 +14,7 @@ class BackendTSBuilder extends Builder {
14
14
  return "backend-ts";
15
15
  }
16
16
  ownsFile(file_path) {
17
- return (file_path.endsWith(".ts") || file_path.endsWith(".tsx")) && !file_path.endsWith("src/back/collections/collections.ts") && !file_path.endsWith("src/back/routes/routes.ts") && !file_path.endsWith("src/back/routes/urls.ts") && !file_path.endsWith("stimulus.ts") && !file_path.startsWith("src/front");
17
+ return (file_path.endsWith(".ts") || file_path.endsWith(".tsx")) && !file_path.endsWith("src/back/collections/collections.ts") && !file_path.endsWith("src/back/routes/routes.ts") && !file_path.endsWith("src/back/routes/urls.ts") && !file_path.endsWith("src/back/jdd-components/components.ts") && !file_path.endsWith("stimulus.ts") && !file_path.startsWith("src/front");
18
18
  }
19
19
  async dispose() {
20
20
  }
@@ -401,15 +401,14 @@ class ColorsBuilder extends Builder {
401
401
  document.addEventListener("click", (event) => {
402
402
  const box = event.target.closest(".color-box");
403
403
  if (box) {
404
- const css_var = box.classList.contains(
405
- "is-main"
406
- )
407
- ? \`var(--color-\${box.getAttribute(
404
+ const css_var =
405
+ box.classList.contains("is-main") ?
406
+ \`var(--color-\${box.getAttribute(
408
407
  "data-color-group-name"
409
408
  )}-\${box.getAttribute(
410
409
  "data-color-name"
411
410
  )})\`
412
- : \`var(--color-\${box.getAttribute(
411
+ : \`var(--color-\${box.getAttribute(
413
412
  "data-color-group-name"
414
413
  )}-\${box.getAttribute(
415
414
  "data-color-name"
@@ -63,7 +63,7 @@ class File extends SimpleInput {
63
63
  return {
64
64
  ...original,
65
65
  name: this.field.name + "[new]",
66
- required: original.required && !parsed?.old,
66
+ required: original.required && !parsed?.old || false,
67
67
  value: false
68
68
  };
69
69
  }
@@ -40,9 +40,7 @@ class MultipleFiles extends FormFieldControl {
40
40
  files = [files];
41
41
  }
42
42
  await Promise.all(
43
- files.map(
44
- (file) => this.addFileAssociation(ctx, file)
45
- )
43
+ files.map((file) => this.addFileAssociation(ctx, file))
46
44
  );
47
45
  ctx.body = this.renderFrame(
48
46
  ctx,
@@ -51,7 +49,10 @@ class MultipleFiles extends FormFieldControl {
51
49
  });
52
50
  }
53
51
  async deleteFileAssociation(ctx, file_item_id) {
54
- await ctx.$app.collections[this.field.collection_field.referencing_collection].removeByID(ctx.$context, file_item_id);
52
+ await this.getReferencingCollection().removeByID(
53
+ ctx.$context,
54
+ file_item_id
55
+ );
55
56
  }
56
57
  async addFileAssociation(ctx, file) {
57
58
  const file_field = this.getFileField();
@@ -63,7 +64,7 @@ class MultipleFiles extends FormFieldControl {
63
64
  [this.field.collection_field.referencing_field]: await this.field.getItemId(ctx),
64
65
  [file_field.name]: file
65
66
  };
66
- await ctx.$app.collections[this.field.collection_field.referencing_collection].create(ctx.$context, body);
67
+ await this.getReferencingCollection().create(ctx.$context, body);
67
68
  }
68
69
  getFrameRelativeURL() {
69
70
  return `${this.field.name}_files`;
@@ -8,7 +8,7 @@ class SingleReferenceDropdown extends FreeformDropdown {
8
8
  super(
9
9
  field,
10
10
  async (ctx) => {
11
- const { items } = await ctx.$app.collections[field.sealiousField.target_collection].list(ctx.$context).fetch();
11
+ const { items } = await this.getCollection(ctx).list(ctx.$context).fetch();
12
12
  return [
13
13
  { value: "", label: "--" },
14
14
  ...items.map((item) => ({
@@ -22,6 +22,9 @@ class SingleReferenceDropdown extends FreeformDropdown {
22
22
  this.field = field;
23
23
  this.options = options;
24
24
  }
25
+ getCollection(ctx) {
26
+ return ctx.$app.collections[this.field.sealiousField.target_collection];
27
+ }
25
28
  setOptionLabelGetter(getter) {
26
29
  this.options.getLabel = getter;
27
30
  return this;
@@ -27,21 +27,21 @@ class File extends FormField {
27
27
  raw_value,
28
28
  "old",
29
29
  predicates.instanceOf(PathFilePointer)
30
- ) ? await ctx.$app.fileManager.toPointer(
31
- raw_value.old
32
- ) : null;
30
+ ) ? await ctx.$app.fileManager.toPointer(raw_value.old) : null;
33
31
  const new_file = hasFieldOfType(
34
32
  raw_value,
35
33
  "new",
36
34
  predicates.or(
37
- predicates.array(predicates.instanceOf(PathFilePointer)),
35
+ predicates.array(
36
+ predicates.instanceOf(PathFilePointer)
37
+ ),
38
38
  predicates.instanceOf(PathFilePointer)
39
39
  )
40
40
  ) ? Array.isArray(raw_value.new) ? raw_value.new[0] : raw_value.new : null;
41
41
  result = {
42
42
  parsable: true,
43
43
  error: null,
44
- parsed_value: { old: old_file, new: new_file }
44
+ parsed_value: { old: old_file, new: new_file || null }
45
45
  };
46
46
  }
47
47
  return result;
@@ -2,9 +2,7 @@ import { Image as ImageControl } from "../controls/image.js";
2
2
  import { File as FileField } from "./file.js";
3
3
  class Image extends FileField {
4
4
  getControl() {
5
- return new ImageControl(
6
- this
7
- );
5
+ return new ImageControl(this);
8
6
  }
9
7
  }
10
8
  export {
@@ -22,7 +22,6 @@ class PhoneNumberWithCountryCode extends FormField {
22
22
  return {
23
23
  parsable: false,
24
24
  parsed_value: null,
25
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
26
25
  error: e.message
27
26
  };
28
27
  }
@@ -39,7 +39,7 @@ class TextBasedSimpleField extends SimpleFormField {
39
39
  }
40
40
  async postSealiousCreate(_ctx, _created_item, _formData) {
41
41
  }
42
- async postSealiousEdit(ctx, _edited_item, _formData) {
42
+ async postSealiousEdit(_ctx, _edited_item, _formData) {
43
43
  }
44
44
  getControl() {
45
45
  return new SimpleInput(this, {
@@ -53,8 +53,7 @@ class StructuredArray extends Table {
53
53
  key,
54
54
  await form_subfield.sealiousValueToForm(
55
55
  ctx,
56
- value,
57
- {}
56
+ value
58
57
  )
59
58
  ];
60
59
  })
package/lib/get-fonts.js CHANGED
@@ -75,7 +75,11 @@ async function getFonts(_ = {}) {
75
75
  fonts_css_file_path,
76
76
  content.replace(/@font-face {/g, "@font-face {\nfont-display: swap;")
77
77
  );
78
- await unlink("public/fonsta.config.json");
78
+ try {
79
+ await unlink("public/fonsta.config.json");
80
+ } catch {
81
+ console.info("No fonsta config present, using just google fonts");
82
+ }
79
83
  await rmdir("public/tmp");
80
84
  console.info("Downloaded new fonts pack from Font Squirrel");
81
85
  console.info("Downloaded new fonts pack");
@@ -10,8 +10,7 @@ class MountableWithFields extends Mountable {
10
10
  this.field_names_prefix = "";
11
11
  // useful for multiform, where many forms are merged into one and field assignment is made using the prefix
12
12
  this.form_id = "";
13
- if (!this.fields)
14
- this.fields = {};
13
+ this.fields = {};
15
14
  }
16
15
  /** most routes should be setup using .mount(), but mount runs before
17
16
  initialization so we don't yet have controls, app, etc ready for dynamic
@@ -16,7 +16,7 @@ describe("mountable-with-fields", () => {
16
16
  async onSubmit(ctx, form_values) {
17
17
  const data = await this.getParsedValues(ctx);
18
18
  data.not_required?.trim();
19
- data.required.trim();
19
+ (data.required || "").trim();
20
20
  const { parsed: data2 } = await this.fields.not_required.getParsedValue(
21
21
  ctx,
22
22
  form_values.raw_values
@@ -29,7 +29,9 @@ class SealiousItemListPage extends ListPage {
29
29
  }
30
30
  }
31
31
  if (Object.keys(filters).length) {
32
- list.filter(filters);
32
+ list.filter(
33
+ filters
34
+ );
33
35
  }
34
36
  }
35
37
  async makeQuery(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.19.25",
3
+ "version": "0.19.28",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -55,8 +55,8 @@
55
55
  "playwright": "^1.29.2",
56
56
  "source-map-support": "^0.5.21",
57
57
  "ts-node": "^10.9.1",
58
- "typescript": "5.9",
59
- "typescript-eslint": "^8.44.0",
58
+ "typescript": "6.0.3",
59
+ "typescript-eslint": "8.70",
60
60
  "wait-port": "^1.0.4"
61
61
  },
62
62
  "types": "./@types/index.d.ts",
package/src/add-route.ts CHANGED
@@ -54,20 +54,18 @@ export async function addRoute(
54
54
  ]);
55
55
 
56
56
  const { action, url, mode } = response as Record<string, string>;
57
- const extension = ["list", "lpr", "page", "sreact", "jdd-editor"].includes(
58
- mode
59
- )
60
- ? "tsx"
61
- : "ts";
57
+ const extension =
58
+ ["list", "lpr", "page", "sreact", "jdd-editor"].includes(mode!) ? "tsx"
59
+ : "ts";
62
60
 
63
- const base_file_name = escape_url_params(url) || "index";
61
+ const base_file_name = escape_url_params(url!) || "index";
64
62
  const file_path = target_locreq.resolve(
65
63
  `src/back/routes/${base_file_name}.${mode}.${extension}`
66
64
  );
67
65
  const test_file_path = target_locreq.resolve(
68
66
  `src/back/routes/${base_file_name}.test.ts`
69
67
  );
70
- const template = Templates[mode];
68
+ const template = Templates[mode!];
71
69
 
72
70
  if (!template) {
73
71
  throw new Error(`Could not get template ${mode}`);
@@ -78,7 +76,7 @@ export async function addRoute(
78
76
  return;
79
77
  }
80
78
  await fs.mkdir(resolve(file_path, "../"), { recursive: true });
81
- await fs.writeFile(file_path, await template(action, file_path));
79
+ await fs.writeFile(file_path, await template(action!, file_path));
82
80
  console.info(`${file_path} created`);
83
81
  console.info(`${test_file_path} created`);
84
82
  await generateRoutes();
package/src/build.ts CHANGED
@@ -126,8 +126,7 @@ export async function buildProject({
126
126
  await build(watch);
127
127
  } catch (e) {
128
128
  console.error("CAUGHT!");
129
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
130
- console.error(e.message);
129
+ console.error((e as Error).message);
131
130
  if (!watch) {
132
131
  process.exit(1);
133
132
  }
@@ -91,9 +91,9 @@ export class ColorsBuilder extends Builder {
91
91
  }) {
92
92
  const c = colord(color);
93
93
  return /* HTML */ `<div
94
- class="color-box ${c.isDark() ? "is-dark" : ""} ${is_main
95
- ? "is-main"
96
- : ""} ${c.toHsl().l > 90 ? "is-almost-white" : ""}"
94
+ class="color-box ${c.isDark() ? "is-dark" : ""} ${is_main ?
95
+ "is-main"
96
+ : ""} ${c.toHsl().l > 90 ? "is-almost-white" : ""}"
97
97
  style="background-color: ${color}; order: ${parseInt(shade_no)}"
98
98
  data-color-name="${name}"
99
99
  data-color-group-name="${group_name}"
@@ -107,7 +107,7 @@ export class ColorsBuilder extends Builder {
107
107
  key == "brand" ? -1 : 11
108
108
  )) {
109
109
  html_colors += `<h2>${group_name}</h2><div class="group">`;
110
- const colors = color_groups[group_name];
110
+ const colors = color_groups[group_name]!;
111
111
  for (const [color_name, color_info] of Object.entries(colors)) {
112
112
  html_colors += `<h3>${color_name}</h3><div class="shades">`;
113
113
  const main_color = color_info.color;
@@ -156,7 +156,7 @@ export class ColorsBuilder extends Builder {
156
156
 
157
157
  function colorCodeFind(color_varibale_name: string) {
158
158
  const parts = color_varibale_name.split("-").slice(2);
159
- const colorGroup = parts[1];
159
+ const colorGroup = parts[1]!;
160
160
  const colorName = parts.slice(2).join("-").replace(/\)$/, "");
161
161
  const colorCode = color_groups[colorGroup]?.[colorName]?.color;
162
162
 
@@ -171,8 +171,8 @@ export class ColorsBuilder extends Builder {
171
171
  ) {
172
172
  let roundedContrast = "";
173
173
  if (fg !== "") {
174
- const fg_code = colorCodeFind(fg);
175
- const bg_code = colorCodeFind(bg);
174
+ const fg_code = colorCodeFind(fg)!;
175
+ const bg_code = colorCodeFind(bg)!;
176
176
  const contrast = hex(fg_code, bg_code);
177
177
  roundedContrast = Math.round(contrast).toString();
178
178
  }
@@ -430,15 +430,14 @@ export class ColorsBuilder extends Builder {
430
430
  document.addEventListener("click", (event) => {
431
431
  const box = event.target.closest(".color-box");
432
432
  if (box) {
433
- const css_var = box.classList.contains(
434
- "is-main"
435
- )
436
- ? \`var(--color-\${box.getAttribute(
433
+ const css_var =
434
+ box.classList.contains("is-main") ?
435
+ \`var(--color-\${box.getAttribute(
437
436
  "data-color-group-name"
438
437
  )}-\${box.getAttribute(
439
438
  "data-color-name"
440
439
  )})\`
441
- : \`var(--color-\${box.getAttribute(
440
+ : \`var(--color-\${box.getAttribute(
442
441
  "data-color-group-name"
443
442
  )}-\${box.getAttribute(
444
443
  "data-color-name"
package/src/cli.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  import yargs from "yargs/yargs";
3
4
  import { addCollection } from "./add-collection.js";
4
5
  import { addJDDComponent } from "./add-jdd-component.js";
@@ -16,10 +17,8 @@ import {
16
17
  registerExternalStyles,
17
18
  } from "./register-external.js";
18
19
 
19
- const actions: Record<
20
- string,
21
- (args: Record<string, string | boolean>) => Promise<void> | undefined
22
- > = {
20
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
21
+ const actions: Record<string, (args: any) => Promise<void> | undefined> = {
23
22
  "add-collection": addCollection,
24
23
  "add-route": addRoute,
25
24
  "add-crud": addCRUD,
@@ -47,5 +46,5 @@ void (async function () {
47
46
  const action = process.argv.at(2);
48
47
  const fn = actions[action || "default"] || actions.default;
49
48
  const args = yargs(process.argv).argv as Record<string, string | boolean>;
50
- await fn(args);
49
+ await fn!(args);
51
50
  })();
@@ -47,7 +47,7 @@ export default class TableController extends Controller {
47
47
  swapRows(index_a: number, index_b: number) {
48
48
  const tbody = this.getTbody();
49
49
  const [a, b] = [index_a, index_b].sort().reverse(); // we want them in descending order
50
- tbody.insertBefore(tbody.children[a], tbody.children[b]);
50
+ tbody.insertBefore(tbody.children[a!]!, tbody.children[b!]!);
51
51
  this.reindex();
52
52
  }
53
53
 
@@ -101,13 +101,13 @@ export default class TableController extends Controller {
101
101
  // disable up/down buttons for first/last items
102
102
  // first reset all states to enabled
103
103
  this.element
104
- .querySelectorAll(
104
+ .querySelectorAll<HTMLButtonElement>(
105
105
  `[data-action="sealgen-table#moveUp"], [data-action="sealgen-table#moveDown"]`
106
106
  )
107
107
  .forEach((e: HTMLButtonElement) => (e.disabled = false));
108
108
  // then disable the ones at the top and bottom
109
109
  this.element
110
- .querySelectorAll(
110
+ .querySelectorAll<HTMLButtonElement>(
111
111
  'tr:first-child [data-action="sealgen-table#moveUp"], tr:last-child [data-action="sealgen-table#moveDown"]'
112
112
  )
113
113
  .forEach((e: HTMLButtonElement) => (e.disabled = true));
@@ -15,9 +15,9 @@ export type DropdownOptions = {
15
15
 
16
16
  export type DropdownOption = { value: string; label: string };
17
17
 
18
- export class FreeformDropdown extends SimpleInput {
18
+ export class FreeformDropdown<ParsedValue> extends SimpleInput {
19
19
  constructor(
20
- public field: FormField<boolean, string | null>,
20
+ public field: FormField<boolean, ParsedValue | null>,
21
21
  public _generateOptions: (ctx: Context) => Promise<DropdownOption[]>,
22
22
  public options: DropdownOptions = {
23
23
  label: field.label || field.name,
@@ -39,15 +39,15 @@ export class FreeformDropdown extends SimpleInput {
39
39
  return {
40
40
  ...original,
41
41
  ...Object.fromEntries([
42
- ...(this.options.autosubmit
43
- ? [
44
- [
45
- "onchange",
46
- ((original.onchange as string | undefined) ||
47
- "") + ";this.form.submit();",
48
- ],
49
- ]
50
- : []),
42
+ ...(this.options.autosubmit ?
43
+ [
44
+ [
45
+ "onchange",
46
+ ((original.onchange as string | undefined) || "") +
47
+ ";this.form.submit();",
48
+ ],
49
+ ]
50
+ : []),
51
51
  ]),
52
52
  } as Record<string, string>;
53
53
  }
@@ -74,9 +74,11 @@ export class FreeformDropdown extends SimpleInput {
74
74
  }
75
75
  }
76
76
 
77
- export class Dropdown extends FreeformDropdown {
77
+ export class Dropdown<
78
+ Required extends boolean,
79
+ > extends FreeformDropdown<string> {
78
80
  constructor(
79
- public field: PickFromListField<boolean>,
81
+ public field: PickFromListField<Required>,
80
82
  public options: DropdownOptions = {
81
83
  label: field.label || field.name,
82
84
  autosubmit: false,
@@ -79,7 +79,7 @@ export class File extends SimpleInput {
79
79
  return {
80
80
  ...original,
81
81
  name: this.field.name + "[new]",
82
- required: original.required && !parsed?.old,
82
+ required: (original.required && !parsed?.old) || false,
83
83
  value: false,
84
84
  };
85
85
  }
@@ -44,7 +44,7 @@ export class MultipleFiles extends FormFieldControl {
44
44
  router.post(
45
45
  this.getFrameRelativeURL() + "/delete/:file_item_id",
46
46
  async (ctx) => {
47
- await this.deleteFileAssociation(ctx, ctx.params.file_item_id);
47
+ await this.deleteFileAssociation(ctx, ctx.params.file_item_id!);
48
48
  ctx.body = this.renderFrame(
49
49
  ctx,
50
50
  await this.renderFrameContent(ctx)
@@ -62,9 +62,7 @@ export class MultipleFiles extends FormFieldControl {
62
62
  files = [files];
63
63
  }
64
64
  await Promise.all(
65
- files.map((file) =>
66
- this.addFileAssociation(ctx, file as unknown as FilePointer)
67
- )
65
+ files.map((file) => this.addFileAssociation(ctx, file))
68
66
  );
69
67
  ctx.body = this.renderFrame(
70
68
  ctx,
@@ -74,9 +72,10 @@ export class MultipleFiles extends FormFieldControl {
74
72
  }
75
73
 
76
74
  async deleteFileAssociation(ctx: Context, file_item_id: string) {
77
- await ctx.$app.collections[
78
- this.field.collection_field.referencing_collection
79
- ].removeByID(ctx.$context, file_item_id);
75
+ await this.getReferencingCollection().removeByID(
76
+ ctx.$context,
77
+ file_item_id
78
+ );
80
79
  }
81
80
 
82
81
  async addFileAssociation(ctx: Context, file: FilePointer) {
@@ -90,9 +89,7 @@ export class MultipleFiles extends FormFieldControl {
90
89
  await this.field.getItemId(ctx),
91
90
  [file_field.name]: file,
92
91
  };
93
- await ctx.$app.collections[
94
- this.field.collection_field.referencing_collection
95
- ].create(ctx.$context, body);
92
+ await this.getReferencingCollection().create(ctx.$context, body);
96
93
  }
97
94
 
98
95
  getFrameRelativeURL() {
@@ -124,7 +121,7 @@ export class MultipleFiles extends FormFieldControl {
124
121
  const result =
125
122
  this.field.collection_field.app.collections[
126
123
  this.field.collection_field.referencing_collection
127
- ];
124
+ ]!;
128
125
  return result;
129
126
  }
130
127
 
@@ -203,7 +200,7 @@ export class MultipleFiles extends FormFieldControl {
203
200
  .ids([item_id])
204
201
  .attach({ [this.field.collection_field.name]: true })
205
202
  .fetch();
206
- return item
203
+ return item!
207
204
  .getAttachments(this.field.collection_field.name)
208
205
  .filter((f) => f);
209
206
  }
@@ -5,8 +5,8 @@ import { SimpleInput, SimpleInputOptions } from "./simple-input.js";
5
5
  export type NumberOptions = SimpleInputOptions & Partial<{ step: number }>;
6
6
 
7
7
  export class Number extends SimpleInput {
8
- field: NumberField;
9
- options: NumberOptions;
8
+ field!: NumberField;
9
+ options!: NumberOptions;
10
10
  constructor(field: NumberField, options: NumberOptions) {
11
11
  super(field, options);
12
12
  }
@@ -22,12 +22,12 @@ export class Number extends SimpleInput {
22
22
  return {
23
23
  ...original,
24
24
  ...Object.fromEntries([
25
- ...(this.field.options.min
26
- ? [["min", this.field.options.min]]
27
- : []),
28
- ...(this.field.options.max
29
- ? [["max", this.field.options.max]]
30
- : []),
25
+ ...(this.field.options.min ?
26
+ [["min", this.field.options.min]]
27
+ : []),
28
+ ...(this.field.options.max ?
29
+ [["max", this.field.options.max]]
30
+ : []),
31
31
  ...(this.options.step ? [["step", this.options.step]] : []),
32
32
  ]),
33
33
  } as Record<string, string>;
@@ -1,17 +1,27 @@
1
- import { FieldTypes as SealiousFieldTypes } from "sealious";
1
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import { Context } from "koa";
4
+ import {
5
+ Field as SealiousField,
6
+ FieldTypes as SealiousFieldTypes,
7
+ } from "sealious";
2
8
  import { CollectionField } from "../fields/collection-field.js";
3
9
  import { DropdownOptions, FreeformDropdown } from "./dropdown.js";
4
10
  import { Collection, CollectionItem } from "sealious";
11
+ import { FormField } from "../../index.js";
12
+
13
+ export type ExtractFieldDecoded<F extends SealiousField<any, any, any>> =
14
+ F extends SealiousField<infer T, unknown, unknown> ? T : never;
5
15
 
6
16
  export class SingleReferenceDropdown<
7
17
  TargetCollection extends Collection,
8
- F extends SealiousFieldTypes.SingleReference,
18
+ SealiousField extends SealiousFieldTypes.SingleReference,
9
19
  Required extends boolean,
10
- > extends FreeformDropdown {
20
+ > extends FreeformDropdown<ExtractFieldDecoded<SealiousField>> {
11
21
  constructor(
12
- public field: CollectionField<F, Required>,
22
+ public field: CollectionField<SealiousField, Required>,
13
23
  public options: DropdownOptions & {
14
- getLabel?: (item: CollectionItem<Collection>) => string;
24
+ getLabel?: (item: CollectionItem<TargetCollection>) => string;
15
25
  } = {
16
26
  label: field.label || field.name,
17
27
  autosubmit: false,
@@ -19,20 +29,17 @@ export class SingleReferenceDropdown<
19
29
  }
20
30
  ) {
21
31
  super(
22
- field,
32
+ field as FormField<any, any>,
23
33
  async (ctx) => {
24
- const { items } = await ctx.$app.collections[
25
- field.sealiousField.target_collection
26
- ]
34
+ const { items } = await this.getCollection(ctx)
27
35
  .list(ctx.$context)
28
36
  .fetch();
29
37
  return [
30
38
  { value: "", label: "--" },
31
39
  ...items.map((item) => ({
32
40
  value: item.id,
33
- label: options.getLabel
34
- ? options.getLabel(item)
35
- : item.id,
41
+ label:
42
+ options.getLabel ? options.getLabel(item) : item.id,
36
43
  })),
37
44
  ];
38
45
  },
@@ -40,6 +47,12 @@ export class SingleReferenceDropdown<
40
47
  );
41
48
  }
42
49
 
50
+ getCollection(ctx: Context) {
51
+ return ctx.$app.collections[
52
+ this.field.sealiousField.target_collection
53
+ ]! as TargetCollection;
54
+ }
55
+
43
56
  setOptionLabelGetter(
44
57
  getter: (item: CollectionItem<TargetCollection>) => string
45
58
  ): this {