create-mendix-widget-gleam 2.0.19 → 2.0.21

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 (65) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/i18n.mjs +394 -334
  4. package/src/index.mjs +284 -231
  5. package/src/licenses.mjs +147 -0
  6. package/src/prompts.mjs +247 -142
  7. package/src/scaffold.mjs +108 -97
  8. package/src/templates/claude_md.mjs +3 -3
  9. package/src/templates/readme_md.mjs +10 -10
  10. package/template/gleam.toml +2 -2
  11. package/template/package.json +6 -6
  12. package/template/src/__WidgetName__.xml +1 -1
  13. package/template/src/package.xml +2 -2
  14. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@command.cache +0 -0
  15. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache +0 -0
  16. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@cursor.cache_meta +0 -0
  17. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@event.cache +0 -0
  18. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@internal@consts.cache +0 -0
  19. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@stdout.cache +0 -0
  20. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@style.cache +0 -0
  21. package/tui/build/dev/javascript/etch/_gleam_artefacts/etch@terminal.cache +0 -0
  22. package/tui/build/dev/javascript/etch/etch/event.mjs +36 -30
  23. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@application.cache +0 -0
  24. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache +0 -0
  25. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache +0 -0
  26. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache +0 -0
  27. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@port.cache +0 -0
  28. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache +0 -0
  29. package/tui/build/dev/javascript/gleam_erlang/_gleam_artefacts/gleam@erlang@reference.cache +0 -0
  30. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@array.cache +0 -0
  31. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@promise.cache +0 -0
  32. package/tui/build/dev/javascript/gleam_javascript/_gleam_artefacts/gleam@javascript@symbol.cache +0 -0
  33. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache +0 -0
  34. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache +0 -0
  35. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_inline +0 -0
  36. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@bytes_tree.cache +0 -0
  37. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dict.cache +0 -0
  38. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache +0 -0
  39. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache +0 -0
  40. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@dynamic@decode.cache_meta +0 -0
  41. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@float.cache +0 -0
  42. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@function.cache +0 -0
  43. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@int.cache +0 -0
  44. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@io.cache +0 -0
  45. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@list.cache +0 -0
  46. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@option.cache +0 -0
  47. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@order.cache +0 -0
  48. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@pair.cache +0 -0
  49. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache +0 -0
  50. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@result.cache_inline +0 -0
  51. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@set.cache +0 -0
  52. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache +0 -0
  53. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta +0 -0
  54. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@string_tree.cache +0 -0
  55. package/tui/build/dev/javascript/gleam_stdlib/_gleam_artefacts/gleam@uri.cache +0 -0
  56. package/tui/build/dev/javascript/gleam_version +1 -1
  57. package/tui/build/dev/javascript/prelude.mjs +10 -26
  58. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache +0 -0
  59. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui.cache_meta +0 -0
  60. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache +0 -0
  61. package/tui/build/dev/javascript/tui/_gleam_artefacts/tui@prompt.cache_meta +0 -0
  62. package/tui/build/dev/javascript/tui/tui/prompt.mjs +713 -52
  63. package/tui/build/dev/javascript/tui/tui.mjs +438 -51
  64. package/tui/build/dev/javascript/tui/tui_ffi.mjs +12 -0
  65. package/template/LICENSE +0 -15
@@ -17,28 +17,57 @@ import {
17
17
  detect_pm,
18
18
  process_exit,
19
19
  is_valid_name,
20
+ get_current_year,
21
+ is_valid_version,
22
+ is_valid_org,
20
23
  split_words as split_words_ffi,
21
24
  } from "./tui_ffi.mjs";
22
25
 
23
26
  const FILEPATH = "src\\tui.gleam";
24
27
 
25
28
  export class Options extends $CustomType {
26
- constructor(project_name, pm, lang) {
29
+ constructor(project_name, organization, copyright, license, version, author, project_path, pm, lang) {
27
30
  super();
28
31
  this.project_name = project_name;
32
+ this.organization = organization;
33
+ this.copyright = copyright;
34
+ this.license = license;
35
+ this.version = version;
36
+ this.author = author;
37
+ this.project_path = project_path;
29
38
  this.pm = pm;
30
39
  this.lang = lang;
31
40
  }
32
41
  }
33
- export const Options$Options = (project_name, pm, lang) =>
34
- new Options(project_name, pm, lang);
42
+ export const Options$Options = (project_name, organization, copyright, license, version, author, project_path, pm, lang) =>
43
+ new Options(project_name,
44
+ organization,
45
+ copyright,
46
+ license,
47
+ version,
48
+ author,
49
+ project_path,
50
+ pm,
51
+ lang);
35
52
  export const Options$isOptions = (value) => value instanceof Options;
36
53
  export const Options$Options$project_name = (value) => value.project_name;
37
54
  export const Options$Options$0 = (value) => value.project_name;
55
+ export const Options$Options$organization = (value) => value.organization;
56
+ export const Options$Options$1 = (value) => value.organization;
57
+ export const Options$Options$copyright = (value) => value.copyright;
58
+ export const Options$Options$2 = (value) => value.copyright;
59
+ export const Options$Options$license = (value) => value.license;
60
+ export const Options$Options$3 = (value) => value.license;
61
+ export const Options$Options$version = (value) => value.version;
62
+ export const Options$Options$4 = (value) => value.version;
63
+ export const Options$Options$author = (value) => value.author;
64
+ export const Options$Options$5 = (value) => value.author;
65
+ export const Options$Options$project_path = (value) => value.project_path;
66
+ export const Options$Options$6 = (value) => value.project_path;
38
67
  export const Options$Options$pm = (value) => value.pm;
39
- export const Options$Options$1 = (value) => value.pm;
68
+ export const Options$Options$7 = (value) => value.pm;
40
69
  export const Options$Options$lang = (value) => value.lang;
41
- export const Options$Options$2 = (value) => value.lang;
70
+ export const Options$Options$8 = (value) => value.lang;
42
71
 
43
72
  function split_words(input) {
44
73
  let _pipe = split_words_ffi(input);
@@ -134,6 +163,126 @@ function t(lang, key) {
134
163
  } else {
135
164
  return key;
136
165
  }
166
+ } else if (key === "org.title") {
167
+ if (lang === "en") {
168
+ return "Organization";
169
+ } else if (lang === "ko") {
170
+ return "조직";
171
+ } else if (lang === "ja") {
172
+ return "組織";
173
+ } else {
174
+ return key;
175
+ }
176
+ } else if (key === "org.empty") {
177
+ if (lang === "en") {
178
+ return "Please enter an organization name.";
179
+ } else if (lang === "ko") {
180
+ return "조직 이름을 입력해주세요.";
181
+ } else if (lang === "ja") {
182
+ return "組織名を入力してください。";
183
+ } else {
184
+ return key;
185
+ }
186
+ } else if (key === "org.invalid") {
187
+ if (lang === "en") {
188
+ return "Lowercase letters, numbers, and hyphens only (a-z start)";
189
+ } else if (lang === "ko") {
190
+ return "소문자로 시작, 소문자/숫자/하이픈만 사용 가능";
191
+ } else if (lang === "ja") {
192
+ return "小文字で始まり、小文字/数字/ハイフンのみ使用可能";
193
+ } else {
194
+ return key;
195
+ }
196
+ } else if (key === "copyright.title") {
197
+ if (lang === "en") {
198
+ return "Copyright";
199
+ } else if (lang === "ko") {
200
+ return "저작권";
201
+ } else if (lang === "ja") {
202
+ return "著作権";
203
+ } else {
204
+ return key;
205
+ }
206
+ } else if (key === "copyright.empty") {
207
+ if (lang === "en") {
208
+ return "Please enter copyright text.";
209
+ } else if (lang === "ko") {
210
+ return "저작권 문구를 입력해주세요.";
211
+ } else if (lang === "ja") {
212
+ return "著作権テキストを入力してください。";
213
+ } else {
214
+ return key;
215
+ }
216
+ } else if (key === "license.title") {
217
+ if (lang === "en") {
218
+ return "License";
219
+ } else if (lang === "ko") {
220
+ return "라이센스";
221
+ } else if (lang === "ja") {
222
+ return "ライセンス";
223
+ } else {
224
+ return key;
225
+ }
226
+ } else if (key === "version.title") {
227
+ if (lang === "en") {
228
+ return "Version";
229
+ } else if (lang === "ko") {
230
+ return "버전";
231
+ } else if (lang === "ja") {
232
+ return "バージョン";
233
+ } else {
234
+ return key;
235
+ }
236
+ } else if (key === "version.invalid") {
237
+ if (lang === "en") {
238
+ return "Must be semver format (e.g. 0.0.1)";
239
+ } else if (lang === "ko") {
240
+ return "semver 형식이어야 합니다 (예: 0.0.1)";
241
+ } else if (lang === "ja") {
242
+ return "semver形式でなければなりません(例:0.0.1)";
243
+ } else {
244
+ return key;
245
+ }
246
+ } else if (key === "author.title") {
247
+ if (lang === "en") {
248
+ return "Author";
249
+ } else if (lang === "ko") {
250
+ return "작성자";
251
+ } else if (lang === "ja") {
252
+ return "作者";
253
+ } else {
254
+ return key;
255
+ }
256
+ } else if (key === "author.empty") {
257
+ if (lang === "en") {
258
+ return "Please enter author name.";
259
+ } else if (lang === "ko") {
260
+ return "작성자를 입력해주세요.";
261
+ } else if (lang === "ja") {
262
+ return "作者名を入力してください。";
263
+ } else {
264
+ return key;
265
+ }
266
+ } else if (key === "path.title") {
267
+ if (lang === "en") {
268
+ return "Project Path";
269
+ } else if (lang === "ko") {
270
+ return "프로젝트 경로";
271
+ } else if (lang === "ja") {
272
+ return "プロジェクトパス";
273
+ } else {
274
+ return key;
275
+ }
276
+ } else if (key === "path.empty") {
277
+ if (lang === "en") {
278
+ return "Please enter project path.";
279
+ } else if (lang === "ko") {
280
+ return "프로젝트 경로를 입력해주세요.";
281
+ } else if (lang === "ja") {
282
+ return "プロジェクトパスを入力してください。";
283
+ } else {
284
+ return key;
285
+ }
137
286
  } else if (key === "pm.title") {
138
287
  if (lang === "en") {
139
288
  return "Package Manager";
@@ -192,6 +341,38 @@ function validate_name(lang, value) {
192
341
  }
193
342
  }
194
343
 
344
+ function validate_org(lang, value) {
345
+ let trimmed = $string.trim(value);
346
+ if (trimmed === "") {
347
+ return new Some(t(lang, "org.empty"));
348
+ } else {
349
+ let $ = is_valid_org(trimmed);
350
+ if ($) {
351
+ return new None();
352
+ } else {
353
+ return new Some(t(lang, "org.invalid"));
354
+ }
355
+ }
356
+ }
357
+
358
+ function validate_version(lang, value) {
359
+ let $ = is_valid_version($string.trim(value));
360
+ if ($) {
361
+ return new None();
362
+ } else {
363
+ return new Some(t(lang, "version.invalid"));
364
+ }
365
+ }
366
+
367
+ function validate_not_empty(lang, error_key, value) {
368
+ let $ = $string.trim(value);
369
+ if ($ === "") {
370
+ return new Some(t(lang, error_key));
371
+ } else {
372
+ return new None();
373
+ }
374
+ }
375
+
195
376
  function name_preview(lang, value) {
196
377
  let words = split_words($string.trim(value));
197
378
  if (words instanceof $Empty) {
@@ -204,6 +385,10 @@ function name_preview(lang, value) {
204
385
  }
205
386
  }
206
387
 
388
+ function no_preview(_) {
389
+ return toList([]);
390
+ }
391
+
207
392
  function cleanup() {
208
393
  $stdout.execute(
209
394
  toList([new $command.ShowCursor(), new $command.LeaveAlternateScreen()]),
@@ -217,7 +402,7 @@ function cancel(lang) {
217
402
  cleanup();
218
403
  $io.println("\n" + t(lang, "cancelled"));
219
404
  process_exit(0);
220
- return $promise.resolve(new Options("", "", ""));
405
+ return $promise.resolve(new Options("", "", "", "", "", "", "", "", ""));
221
406
  }
222
407
 
223
408
  export function collect_options(cli_name) {
@@ -227,15 +412,15 @@ export function collect_options(cli_name) {
227
412
  "let_assert",
228
413
  FILEPATH,
229
414
  "tui",
230
- 163,
415
+ 265,
231
416
  "collect_options",
232
417
  "Pattern match failed, no pattern matched the value.",
233
418
  {
234
419
  value: $,
235
- start: 5543,
236
- end: 5582,
237
- pattern_start: 5554,
238
- pattern_end: 5559
420
+ start: 8812,
421
+ end: 8851,
422
+ pattern_start: 8823,
423
+ pattern_end: 8828
239
424
  }
240
425
  )
241
426
  }
@@ -275,51 +460,253 @@ export function collect_options(cli_name) {
275
460
  (name_result) => {
276
461
  if (name_result instanceof Ok) {
277
462
  let name = name_result[0];
278
- $stdout.execute(toList([new $command.HideCursor()]));
279
- let completed$1 = toList([
280
- ["Language", lang_label],
281
- ["Project", name],
282
- ]);
283
- let detected = detect_pm();
284
- let pms = toList(["npm", "yarn", "pnpm", "bun"]);
285
- let _block;
286
- if (detected === "yarn") {
287
- _block = 1;
288
- } else if (detected === "pnpm") {
289
- _block = 2;
290
- } else if (detected === "bun") {
291
- _block = 3;
292
- } else {
293
- _block = 0;
294
- }
295
- let default_idx = _block;
296
- let pm_labels = $list.map(
297
- pms,
298
- (pm) => {
299
- let $3 = pm === detected;
300
- if ($3) {
301
- return (pm + " ← ") + t(lang, "pm.detected");
302
- } else {
303
- return pm;
304
- }
305
- },
463
+ let completed$1 = $list.append(
464
+ completed,
465
+ toList([[t(lang, "name.title"), name]]),
306
466
  );
307
467
  return $promise.await$(
308
- $prompt.select(
468
+ $prompt.text_input(
309
469
  completed$1,
310
- t(lang, "pm.title"),
311
- pm_labels,
312
- default_idx,
313
- t(lang, "hint.select"),
470
+ t(lang, "org.title"),
471
+ "mendix",
472
+ (_capture) => { return validate_org(lang, _capture); },
473
+ no_preview,
474
+ t(lang, "hint.input"),
314
475
  ),
315
- (pm_idx) => {
316
- let $3 = pm_idx < 0;
317
- if ($3) {
318
- return cancel(lang);
476
+ (org_result) => {
477
+ if (org_result instanceof Ok) {
478
+ let org = org_result[0];
479
+ let completed$2 = $list.append(
480
+ completed$1,
481
+ toList([[t(lang, "org.title"), org]]),
482
+ );
483
+ let year = get_current_year();
484
+ let default_copyright = ("© Mendix Technology BV " + year) + ". All rights reserved.";
485
+ return $promise.await$(
486
+ $prompt.text_input(
487
+ completed$2,
488
+ t(lang, "copyright.title"),
489
+ default_copyright,
490
+ (_capture) => {
491
+ return validate_not_empty(
492
+ lang,
493
+ "copyright.empty",
494
+ _capture,
495
+ );
496
+ },
497
+ no_preview,
498
+ t(lang, "hint.input"),
499
+ ),
500
+ (copyright_result) => {
501
+ if (copyright_result instanceof Ok) {
502
+ let copyright = copyright_result[0];
503
+ let completed$3 = $list.append(
504
+ completed$2,
505
+ toList([[t(lang, "copyright.title"), copyright]]),
506
+ );
507
+ $stdout.execute(toList([new $command.HideCursor()]));
508
+ let licenses = toList([
509
+ "Apache-2.0",
510
+ "BlueOak-1.0.0",
511
+ "GPL-3.0-only",
512
+ "GPL-2.0-only",
513
+ "MIT",
514
+ "MPL-2.0",
515
+ ]);
516
+ return $promise.await$(
517
+ $prompt.select(
518
+ completed$3,
519
+ t(lang, "license.title"),
520
+ licenses,
521
+ 0,
522
+ t(lang, "hint.select"),
523
+ ),
524
+ (license_idx) => {
525
+ let $3 = license_idx < 0;
526
+ if ($3) {
527
+ return cancel(lang);
528
+ } else {
529
+ let license = $result.unwrap(
530
+ list_at(licenses, license_idx),
531
+ "Apache-2.0",
532
+ );
533
+ let completed$4 = $list.append(
534
+ completed$3,
535
+ toList([[t(lang, "license.title"), license]]),
536
+ );
537
+ $stdout.execute(
538
+ toList([new $command.ShowCursor()]),
539
+ );
540
+ return $promise.await$(
541
+ $prompt.text_input(
542
+ completed$4,
543
+ t(lang, "version.title"),
544
+ "0.0.1",
545
+ (_capture) => {
546
+ return validate_version(lang, _capture);
547
+ },
548
+ no_preview,
549
+ t(lang, "hint.input"),
550
+ ),
551
+ (version_result) => {
552
+ if (version_result instanceof Ok) {
553
+ let version = version_result[0];
554
+ let completed$5 = $list.append(
555
+ completed$4,
556
+ toList([
557
+ [t(lang, "version.title"), version],
558
+ ]),
559
+ );
560
+ return $promise.await$(
561
+ $prompt.text_input(
562
+ completed$5,
563
+ t(lang, "author.title"),
564
+ "A.N. Other",
565
+ (_capture) => {
566
+ return validate_not_empty(
567
+ lang,
568
+ "author.empty",
569
+ _capture,
570
+ );
571
+ },
572
+ no_preview,
573
+ t(lang, "hint.input"),
574
+ ),
575
+ (author_result) => {
576
+ if (author_result instanceof Ok) {
577
+ let author = author_result[0];
578
+ let completed$6 = $list.append(
579
+ completed$5,
580
+ toList([
581
+ [
582
+ t(lang, "author.title"),
583
+ author,
584
+ ],
585
+ ]),
586
+ );
587
+ return $promise.await$(
588
+ $prompt.text_input(
589
+ completed$6,
590
+ t(lang, "path.title"),
591
+ "./tests/testProject",
592
+ (_capture) => {
593
+ return validate_not_empty(
594
+ lang,
595
+ "path.empty",
596
+ _capture,
597
+ );
598
+ },
599
+ no_preview,
600
+ t(lang, "hint.input"),
601
+ ),
602
+ (path_result) => {
603
+ if (path_result instanceof Ok) {
604
+ let project_path = path_result[0];
605
+ let completed$7 = $list.append(
606
+ completed$6,
607
+ toList([
608
+ [
609
+ t(lang, "path.title"),
610
+ project_path,
611
+ ],
612
+ ]),
613
+ );
614
+ $stdout.execute(
615
+ toList([
616
+ new $command.HideCursor(),
617
+ ]),
618
+ );
619
+ let detected = detect_pm();
620
+ let pms = toList([
621
+ "npm",
622
+ "yarn",
623
+ "pnpm",
624
+ "bun",
625
+ ]);
626
+ let _block;
627
+ if (detected === "yarn") {
628
+ _block = 1;
629
+ } else if (detected === "pnpm") {
630
+ _block = 2;
631
+ } else if (detected === "bun") {
632
+ _block = 3;
633
+ } else {
634
+ _block = 0;
635
+ }
636
+ let default_idx = _block;
637
+ let pm_labels = $list.map(
638
+ pms,
639
+ (pm) => {
640
+ let $4 = pm === detected;
641
+ if ($4) {
642
+ return (pm + " ← ") + t(
643
+ lang,
644
+ "pm.detected",
645
+ );
646
+ } else {
647
+ return pm;
648
+ }
649
+ },
650
+ );
651
+ return $promise.await$(
652
+ $prompt.select(
653
+ completed$7,
654
+ t(lang, "pm.title"),
655
+ pm_labels,
656
+ default_idx,
657
+ t(lang, "hint.select"),
658
+ ),
659
+ (pm_idx) => {
660
+ let $4 = pm_idx < 0;
661
+ if ($4) {
662
+ return cancel(lang);
663
+ } else {
664
+ let pm = $result.unwrap(
665
+ list_at(pms, pm_idx),
666
+ "npm",
667
+ );
668
+ cleanup();
669
+ return $promise.resolve(
670
+ new Options(
671
+ name,
672
+ org,
673
+ copyright,
674
+ license,
675
+ version,
676
+ author,
677
+ project_path,
678
+ pm,
679
+ lang,
680
+ ),
681
+ );
682
+ }
683
+ },
684
+ );
685
+ } else {
686
+ return cancel(lang);
687
+ }
688
+ },
689
+ );
690
+ } else {
691
+ return cancel(lang);
692
+ }
693
+ },
694
+ );
695
+ } else {
696
+ return cancel(lang);
697
+ }
698
+ },
699
+ );
700
+ }
701
+ },
702
+ );
703
+ } else {
704
+ return cancel(lang);
705
+ }
706
+ },
707
+ );
319
708
  } else {
320
- let pm = $result.unwrap(list_at(pms, pm_idx), "npm");
321
- cleanup();
322
- return $promise.resolve(new Options(name, pm, lang));
709
+ return cancel(lang);
323
710
  }
324
711
  },
325
712
  );
@@ -21,6 +21,18 @@ export function is_valid_name(name) {
21
21
  return /^[a-zA-Z][a-zA-Z0-9\-_]*$/.test(name);
22
22
  }
23
23
 
24
+ export function get_current_year() {
25
+ return String(new Date().getFullYear());
26
+ }
27
+
28
+ export function is_valid_version(v) {
29
+ return /^\d+\.\d+\.\d+$/.test(v);
30
+ }
31
+
32
+ export function is_valid_org(v) {
33
+ return /^[a-z][a-z0-9\-]*$/.test(v);
34
+ }
35
+
24
36
  export function split_words(input) {
25
37
  let result = input.replace(/([a-z])([A-Z])/g, "$1 $2");
26
38
  result = result.replace(/([0-9])([a-zA-Z])/g, "$1 $2");
package/template/LICENSE DELETED
@@ -1,15 +0,0 @@
1
- The Apache License v2.0
2
-
3
- Copyright © Mendix Technology BV 2026. All rights reserved.
4
-
5
- Licensed under the Apache License, Version 2.0 (the "License");
6
- you may not use this file except in compliance with the License.
7
- You may obtain a copy of the License at
8
-
9
- http://www.apache.org/licenses/LICENSE-2.0
10
-
11
- Unless required by applicable law or agreed to in writing, software
12
- distributed under the License is distributed on an "AS IS" BASIS,
13
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- See the License for the specific language governing permissions and
15
- limitations under the License.