@skalfa/skalfa-app 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/skalfa-framework/skalfa/main/logo/logo-skalfa-full.png" alt="Skalfa Logo" width="300" />
2
+ <img src="https://skalfa.sejedigital.com/images/logo-skalfa.png" alt="Skalfa Logo" width="300" />
3
3
  </p>
4
4
 
5
5
  # @skalfa/skalfa-app
package/bun.lock CHANGED
@@ -3,7 +3,7 @@
3
3
  "configVersion": 0,
4
4
  "workspaces": {
5
5
  "": {
6
- "name": "next-light",
6
+ "name": "@skalfa/skalfa-app",
7
7
  "dependencies": {
8
8
  "@fortawesome/fontawesome-svg-core": "^6.7.2",
9
9
  "@fortawesome/free-brands-svg-icons": "^6.7.2",
@@ -11,7 +11,7 @@
11
11
  "@fortawesome/free-solid-svg-icons": "^6.7.2",
12
12
  "@fortawesome/react-fontawesome": "^0.2.2",
13
13
  "@react-google-maps/api": "^2.20.7",
14
- "@skalfa/skalfa-app-core": "^1.0.0",
14
+ "@skalfa/skalfa-app-core": "^1.0.3",
15
15
  "@tailwindcss/postcss": "^4.0.0",
16
16
  "axios": "^1.12.0",
17
17
  "moment": "^2.30.1",
@@ -41,9 +41,9 @@
41
41
 
42
42
  "@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
43
43
 
44
- "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="],
44
+ "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
45
45
 
46
- "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
46
+ "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
47
47
 
48
48
  "@eslint/config-array": ["@eslint/config-array@0.19.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA=="],
49
49
 
@@ -169,7 +169,7 @@
169
169
 
170
170
  "@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.10.5", "", {}, "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A=="],
171
171
 
172
- "@skalfa/skalfa-app-core": ["@skalfa/skalfa-app-core@1.0.0", "", { "dependencies": { "axios": "^1.12.0", "clsx": "^2.1.1", "crypto-js": "^4.2.0", "js-cookie": "^3.0.5", "lz-string": "^1.5.0", "moment": "^2.30.1", "tailwind-merge": "^3.0.2", "validator": "^13.15.22" }, "peerDependencies": { "next": "^15.0.0 || ^16.0.0", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-i3uPl1iZTJABSEx5aFmbYzT0JYoZc5CC4vlOL7o2H9gqBoapx0iUySsu0IM3j0CjSJtdaJF9upQ9phAwaRDTVw=="],
172
+ "@skalfa/skalfa-app-core": ["@skalfa/skalfa-app-core@1.0.3", "", { "dependencies": { "axios": "^1.12.0", "clsx": "^2.1.1", "crypto-js": "^4.2.0", "js-cookie": "^3.0.5", "lz-string": "^1.5.0", "moment": "^2.30.1", "tailwind-merge": "^3.0.2", "validator": "^13.15.22" }, "peerDependencies": { "next": "^15.0.0 || ^16.0.0", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-nEGXFnXxyvwzQvcGY3gBOjFHYyvhIYoLLGetQ3p7sC2I31Ase/BkoseEYkC5vEAefep9OVxiLD6IsJKSDQ3VeQ=="],
173
173
 
174
174
  "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
175
175
 
@@ -219,21 +219,25 @@
219
219
 
220
220
  "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
221
221
 
222
- "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.20.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.20.0", "@typescript-eslint/type-utils": "8.20.0", "@typescript-eslint/utils": "8.20.0", "@typescript-eslint/visitor-keys": "8.20.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A=="],
222
+ "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.62.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.62.1", "@typescript-eslint/type-utils": "8.62.1", "@typescript-eslint/utils": "8.62.1", "@typescript-eslint/visitor-keys": "8.62.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.62.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA=="],
223
223
 
224
- "@typescript-eslint/parser": ["@typescript-eslint/parser@8.20.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.20.0", "@typescript-eslint/types": "8.20.0", "@typescript-eslint/typescript-estree": "8.20.0", "@typescript-eslint/visitor-keys": "8.20.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g=="],
224
+ "@typescript-eslint/parser": ["@typescript-eslint/parser@8.62.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.62.1", "@typescript-eslint/types": "8.62.1", "@typescript-eslint/typescript-estree": "8.62.1", "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA=="],
225
225
 
226
- "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.20.0", "", { "dependencies": { "@typescript-eslint/types": "8.20.0", "@typescript-eslint/visitor-keys": "8.20.0" } }, "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw=="],
226
+ "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.62.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.62.1", "@typescript-eslint/types": "^8.62.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg=="],
227
227
 
228
- "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.20.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.20.0", "@typescript-eslint/utils": "8.20.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA=="],
228
+ "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.62.1", "", { "dependencies": { "@typescript-eslint/types": "8.62.1", "@typescript-eslint/visitor-keys": "8.62.1" } }, "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg=="],
229
229
 
230
- "@typescript-eslint/types": ["@typescript-eslint/types@8.20.0", "", {}, "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA=="],
230
+ "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.62.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g=="],
231
231
 
232
- "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.20.0", "", { "dependencies": { "@typescript-eslint/types": "8.20.0", "@typescript-eslint/visitor-keys": "8.20.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA=="],
232
+ "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.62.1", "", { "dependencies": { "@typescript-eslint/types": "8.62.1", "@typescript-eslint/typescript-estree": "8.62.1", "@typescript-eslint/utils": "8.62.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg=="],
233
233
 
234
- "@typescript-eslint/utils": ["@typescript-eslint/utils@8.20.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.20.0", "@typescript-eslint/types": "8.20.0", "@typescript-eslint/typescript-estree": "8.20.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA=="],
234
+ "@typescript-eslint/types": ["@typescript-eslint/types@8.62.1", "", {}, "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q=="],
235
235
 
236
- "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.20.0", "", { "dependencies": { "@typescript-eslint/types": "8.20.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA=="],
236
+ "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.62.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.62.1", "@typescript-eslint/tsconfig-utils": "8.62.1", "@typescript-eslint/types": "8.62.1", "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA=="],
237
+
238
+ "@typescript-eslint/utils": ["@typescript-eslint/utils@8.62.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.62.1", "@typescript-eslint/types": "8.62.1", "@typescript-eslint/typescript-estree": "8.62.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g=="],
239
+
240
+ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.62.1", "", { "dependencies": { "@typescript-eslint/types": "8.62.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g=="],
237
241
 
238
242
  "acorn": ["acorn@8.14.0", "", { "bin": "bin/acorn" }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
239
243
 
@@ -419,6 +423,8 @@
419
423
 
420
424
  "fastq": ["fastq@1.18.0", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw=="],
421
425
 
426
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
427
+
422
428
  "figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA=="],
423
429
 
424
430
  "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
@@ -431,7 +437,7 @@
431
437
 
432
438
  "flatted": ["flatted@3.3.2", "", {}, "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA=="],
433
439
 
434
- "follow-redirects": ["follow-redirects@1.16.0", "", { "peerDependencies": { "debug": "*" }, "optionalPeers": ["debug"] }, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="],
440
+ "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="],
435
441
 
436
442
  "for-each": ["for-each@0.3.3", "", { "dependencies": { "is-callable": "^1.1.3" } }, "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw=="],
437
443
 
@@ -463,8 +469,6 @@
463
469
 
464
470
  "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
465
471
 
466
- "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
467
-
468
472
  "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
469
473
 
470
474
  "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
@@ -477,7 +481,7 @@
477
481
 
478
482
  "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
479
483
 
480
- "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
484
+ "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
481
485
 
482
486
  "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
483
487
 
@@ -791,11 +795,13 @@
791
795
 
792
796
  "tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
793
797
 
798
+ "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
799
+
794
800
  "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
795
801
 
796
802
  "tree-kill": ["tree-kill@1.2.2", "", { "bin": "cli.js" }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
797
803
 
798
- "ts-api-utils": ["ts-api-utils@2.0.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ=="],
804
+ "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
799
805
 
800
806
  "tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
801
807
 
@@ -847,12 +853,14 @@
847
853
 
848
854
  "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
849
855
 
850
- "@typescript-eslint/typescript-estree/fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
856
+ "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
851
857
 
852
- "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
858
+ "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="],
853
859
 
854
860
  "@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
855
861
 
862
+ "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
863
+
856
864
  "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
857
865
 
858
866
  "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
@@ -869,9 +877,9 @@
869
877
 
870
878
  "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
871
879
 
872
- "figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
880
+ "fdir/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
873
881
 
874
- "form-data/hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
882
+ "figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
875
883
 
876
884
  "is-bun-module/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
877
885
 
@@ -887,9 +895,9 @@
887
895
 
888
896
  "string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
889
897
 
890
- "@typescript-eslint/typescript-estree/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
898
+ "tinyglobby/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
891
899
 
892
- "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
900
+ "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="],
893
901
 
894
902
  "eslint-import-resolver-typescript/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
895
903
 
@@ -901,6 +909,8 @@
901
909
 
902
910
  "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
903
911
 
912
+ "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
913
+
904
914
  "pkg-conf/find-up/locate-path/p-locate": ["p-locate@2.0.0", "", { "dependencies": { "p-limit": "^1.1.0" } }, "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg=="],
905
915
 
906
916
  "pkg-conf/find-up/locate-path/path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="],
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "@skalfa/skalfa-app",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "scripts": {
5
- "dev": "concurrently --raw \"bun run barrels\" \"next dev\"",
5
+ "dev": "concurrently --raw \"bun run skalfa watch:barrels\" \"next dev\"",
6
6
  "build": "next build",
7
7
  "start": "next start",
8
8
  "test": "bun tsc --noEmit",
9
9
  "lint": "npx eslint app/* components/* utils/* contexts/* schema/*",
10
- "light": "bun utils/commands/light.ts",
11
- "barrels": "bun run utils/commands/barrels.ts"
10
+ "skalfa": "bun run utils/commands/skalfa.ts"
12
11
  },
13
12
  "dependencies": {
14
13
  "@fortawesome/fontawesome-svg-core": "^6.7.2",
@@ -17,7 +16,7 @@
17
16
  "@fortawesome/free-solid-svg-icons": "^6.7.2",
18
17
  "@fortawesome/react-fontawesome": "^0.2.2",
19
18
  "@react-google-maps/api": "^2.20.7",
20
- "@skalfa/skalfa-app-core": "^1.0.0",
19
+ "@skalfa/skalfa-app-core": "^1.0.3",
21
20
  "@tailwindcss/postcss": "^4.0.0",
22
21
  "axios": "^1.12.0",
23
22
  "moment": "^2.30.1",
@@ -0,0 +1,3 @@
1
+ import { runCli } from "@skalfa/skalfa-app-core";
2
+
3
+ runCli();
@@ -1,103 +0,0 @@
1
- [
2
- {
3
- "model" : "iam/user",
4
- "schema" : {
5
- "name" : "type:string,200 required min:1 max:200 fillable searchable selectable",
6
- "email" : "type:string,100 unique index required min:5 max:100 fillable searchable selectable",
7
- "password" : "type:string,200 required min:8 max:50 fillable hidden",
8
- "image" : "type:string,100 required fillable selectable file",
9
- "email_verification_at" : "type:timestamp"
10
- },
11
- "relations": {
12
- "roles": "[]:Role expandable fillable",
13
- "permission": "[1]Permission"
14
- },
15
- "seeders" : [
16
- ["Admin", "admin@mail.com", "$2b$10$tPX5QhnM.vUEDmDpht6O4OarVyTh43NTxhkzFrNxfRijJ3uhSHcli", null, "0001-01-01 01:01:01.000+00"],
17
- ["User", "user@mail.com", "$2b$10$tPX5QhnM.vUEDmDpht6O4OarVyTh43NTxhkzFrNxfRijJ3uhSHcli", null, "0001-01-01 01:01:01.000+00"]
18
- ],
19
- "migrations" : false,
20
-
21
- "pages": {
22
- "iam/user": {
23
- "features": "create import export print",
24
- "schema": {
25
- "Nama" : "name column:sortable form:text|required|min:1|max:200|6",
26
- "Email" : "email column:sortable form:text|required|email|min:5|max:100|6",
27
- "Password" : "password form:input-password|required,create|min:8|max:50",
28
- "Foto" : "image form:image|6"
29
- }
30
- }
31
- }
32
- },
33
- {
34
- "model" : "iam/role",
35
- "schema" : {
36
- "name" : "type:string,25 index required min:1 max:25 fillable searchable selectable"
37
- },
38
- "controllers" : ["iam/role"],
39
- "seeders" : [["Admin"], ["User"]],
40
- "migrations" : false,
41
-
42
- "pages": {
43
- "iam/user": {
44
- "features": "create",
45
- "schema": {
46
- "Nama" : "name column:sortable form:text|required|min:1|max:25"
47
- }
48
- }
49
- }
50
- },
51
- {
52
- "model" : "iam/user-role",
53
- "schema" : {
54
- "user_id" : "type:bigInteger unsigned index required fillable selectable",
55
- "role_id" : "type:bigInteger unsigned index required fillable selectable"
56
- },
57
- "relations": {
58
- "role" : "Role",
59
- "user" : "User"
60
- },
61
- "controllers" : false,
62
- "seeders" : [[1, 1], [2, 2]],
63
- "migrations" : false,
64
- "pages": false
65
- },
66
- {
67
- "model" : "iam/role-permission",
68
- "schema" : {
69
- "user_id" : "type:bigInteger unsigned index fillable selectable",
70
- "role_id" : "type:bigInteger unsigned index fillable selectable",
71
- "permissions" : "type:json nullable fillable selectable"
72
- },
73
- "migrations" : false
74
- },
75
- {
76
- "model" : "iam/user-access-token",
77
- "controllers" : false,
78
- "schema" : {
79
- "user_id" : "type:bigInteger unsigned index fillable selectable",
80
- "agent" : "type:string,100 nullable index fillable selectable",
81
- "token" : "type:string,200 fillable selectable hidden",
82
- "permissions" : "type:json nullable fillable selectable",
83
- "last_used_ip" : "type:string,100 nullable fillable selectable",
84
- "last_used_at" : "type:timestamp nullable fillable selectable",
85
- "expired_at" : "type:timestamp nullable fillable selectable"
86
- },
87
- "migrations" : false,
88
- "pages": false
89
- },
90
- {
91
- "model" : "iam/user-mail-token",
92
- "controllers" : false,
93
- "schema" : {
94
- "user_id" : "type:bigInteger unsigned index fillable selectable",
95
- "type" : "type:string,10 fillable selectable hidden",
96
- "token" : "type:string,200 fillable selectable hidden",
97
- "used_at" : "type:timestamp fillable selectable",
98
- "expired_at" : "type:timestamp fillable selectable"
99
- },
100
- "migrations" : false,
101
- "pages": false
102
- }
103
- ]
package/langs/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./validation.langs";
@@ -1,17 +0,0 @@
1
- export const validationLangs = {
2
- required: "Please fill in this field!",
3
- min: "Field must contain more than @min Character!",
4
- max: "Field must be less than @max Character!",
5
- min_max: "Field must be @min - @max Character!",
6
- phone: "Please enter valid mobile number!",
7
- url: "Please enter valid url!",
8
- uppercase: "Field must be at least 1 uppercase!",
9
- lowercase: "Field must be at least 1 lowercase!",
10
- numeric: "Field must be at least 1 numeric!",
11
- email: "Please enter valid email!",
12
- in: "Field must be one of @keywords",
13
- not_in: "Field can't one of @keywords",
14
- regex: "Please enter valid format",
15
- invalid_file_type: "Only allow extensions @extension",
16
- max_file_size: "Max file size @maxFileSize Mb",
17
- };
@@ -1,28 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { exec } from "child_process";
4
- import { logger } from "./logger";
5
-
6
- const rootDir = path.resolve();
7
- const configText = fs.readFileSync("barrels.json", "utf8");
8
- const config = JSON.parse(configText);
9
- const directories: string[] = Array.isArray(config.directory) ? config.directory : [config.directory];
10
-
11
-
12
- directories.forEach((dir) => {
13
- const absoluteDir = path.join(rootDir, dir);
14
-
15
- if (!fs.existsSync(absoluteDir)) {
16
- logger.error(`Barrels error: ${absoluteDir} directory not found`)
17
- return;
18
- }
19
-
20
- fs.watch(absoluteDir, { recursive: true }, (_, filename) => {
21
- if (filename && (filename.endsWith(".ts") || filename.endsWith(".tsx")) && filename !== "index.ts") {
22
- exec("npx barrelsby -c barrels.json", { cwd: rootDir })
23
- logger.info("Barrels updated " + absoluteDir + "/index.ts")
24
- }
25
- });
26
- });
27
-
28
- logger.start("Barrels watched " + directories.join(", "))
@@ -1,421 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { ValidationRules, conversion } from "@skalfa/skalfa-app-core";
4
- import { logger } from "./logger";
5
-
6
-
7
-
8
- type SchemaMap = Record<string, string>
9
-
10
- type ColumnItem = {
11
- selector ?: string
12
- label : string
13
- sortable ?: boolean
14
- item ?: string
15
- }
16
-
17
- type FormItem = {
18
- type ?: string
19
- col ?: number
20
- construction : {
21
- name : string
22
- label : string
23
- placeholder : string
24
- validations : ValidationRules[]
25
- serverOptionControl ?: {
26
- path : string
27
- }
28
- fields ?: FormItem[]
29
- wrap ?: boolean
30
- }
31
- }
32
-
33
- type DetailItem = {
34
- label : string
35
- item : string
36
- }
37
-
38
- type ParsedSchema = {
39
- columns : ColumnItem[]
40
- forms : FormItem[]
41
- details : DetailItem[]
42
- }
43
-
44
- type BlueprintPage = {
45
- features ?: string
46
- path ?: string
47
- schema ?: Record<string, string>
48
- }
49
-
50
- type BlueprintStruct = {
51
- model : string
52
- controllers ?: string[]
53
- schema ?: SchemaMap
54
- pages ?: false | Record<string, BlueprintPage>
55
- [key: string]: any
56
- }
57
-
58
- type LoadedBlueprintFile = {
59
- file : string
60
- blueprints : BlueprintStruct[]
61
- }
62
-
63
-
64
-
65
- const renderJS = (value: unknown, indent = 0): string => {
66
- const pad = " ".repeat(indent)
67
-
68
- if (Array.isArray(value)) {
69
- if (!value.length) return "[]"
70
-
71
- if (value.every(v => typeof v === "string")) {
72
- return `[${value.map(v => JSON.stringify(v)).join(", ")}]`
73
- }
74
-
75
- return `[\n${value
76
- .map(v => pad + " " + renderJS(v, indent + 2))
77
- .join(",\n")}\n${pad}]`
78
- }
79
-
80
- if (value && typeof value === "object") {
81
- const entries = Object.entries(value as Record<string, unknown>)
82
- if (!entries.length) return "{}"
83
-
84
- return `{\n${entries
85
- .map(([k, v]) => `${pad} ${k}: ${renderJS(v, indent + 2)}`)
86
- .join(",\n")}\n${pad}}`
87
- }
88
-
89
- if (typeof value === "string") return JSON.stringify(value)
90
-
91
- return String(value)
92
- }
93
-
94
- function extractValidationArray(def: string = ""): ValidationRules[] {
95
- const rules: ValidationRules[] = []
96
-
97
- if (def.includes("required")) rules.push("required")
98
-
99
- if (def.includes("email")) rules.push("email")
100
-
101
- if (def.includes("url")) rules.push("url")
102
-
103
- const min = def.match(/min,(\d+)/)
104
- if (min) rules.push(`min:${min[1]}`)
105
-
106
- const max = def.match(/max,(\d+)/)
107
- if (max) rules.push(`max:${max[1]}`)
108
-
109
- return rules
110
- }
111
-
112
- function extractFormType(rules: string[]): string | undefined {
113
- const rule = rules.find(r => r.startsWith("form:"))
114
- return rule ? rule.replace("form:", "") : undefined
115
- }
116
-
117
- function inferFormType(pageDef = "", modelDef = ""): string {
118
- const explicit = pageDef.split("|")
119
- if (explicit && explicit[0] && explicit[0] != "text") return explicit[0]
120
-
121
- if (modelDef.includes("type:integer") || modelDef.includes("type:float")) {
122
- return "number"
123
- }
124
-
125
- if (modelDef.includes("type:date")) return "date"
126
- if (modelDef.includes("type:datetime")) return "datetime"
127
- if (modelDef.includes("type:image")) return "image"
128
-
129
- return "default"
130
- }
131
-
132
- function parseFeatures(features?: string): { controlBar: string[]; action: string[] } {
133
- const controlBar: string[] = []
134
- const action: string[] = []
135
-
136
- if (!features) {
137
- return { controlBar: ["CREATE"], action: ["EDIT", "DELETE"] }
138
- }
139
-
140
- const list = features.split(" ")
141
-
142
- if (list.includes("create")) controlBar.push("CREATE")
143
-
144
- controlBar.push("SEARCH", "SORT", "SELECTABLE")
145
-
146
- if (list.includes("import")) controlBar.push("IMPORT")
147
- if (list.includes("export")) controlBar.push("EXPORT")
148
- if (list.includes("print")) controlBar.push("PRINT")
149
-
150
- if (list.includes("update") || list.includes("edit")) action.push("EDIT")
151
- if (list.includes("delete")) action.push("DELETE")
152
- if (list.includes("detail")) action.push("DETAIL")
153
-
154
- return { controlBar, action }
155
- }
156
-
157
- function parseModelSchema(schema: SchemaMap = {}): ParsedSchema {
158
- const columns: ColumnItem[] = []
159
- const forms: FormItem[] = []
160
- const details: DetailItem[] = []
161
-
162
- for (const [field, def] of Object.entries(schema)) {
163
- const label = conversion.strPascal(field, " ")
164
-
165
- if (def.includes("selectable")) {
166
- columns.push({ selector: field, label })
167
- details.push({ label, item: field })
168
- }
169
-
170
- if (def.includes("fillable")) {
171
- const fieldType = inferFormType("", def);
172
- forms.push({
173
- ...(fieldType != "default" ? { type: fieldType } : {}),
174
- construction: {
175
- name: field,
176
- label,
177
- placeholder: "Masukkan " + label.toLowerCase(),
178
- validations: extractValidationArray(def)
179
- }
180
- })
181
- }
182
- }
183
-
184
- return { columns, forms, details }
185
- }
186
-
187
- function resolvePath(page: BlueprintPage, controllers: string[] | boolean | undefined, model: string): string {
188
- if (page.path) return page.path
189
-
190
- if (Array.isArray(controllers)) {
191
- const match = controllers
192
- if (match) return "/" + match[1]
193
- }
194
-
195
- return "/" + model.split("/").pop()
196
- }
197
-
198
- function parsePageSchema(pageSchema: Record<string, string>, modelSchema: SchemaMap = {}): ParsedSchema {
199
- const columns: ColumnItem[] = []
200
- const forms: FormItem[] = []
201
- const details: DetailItem[] = []
202
-
203
- for (const [field, def] of Object.entries(pageSchema)) {
204
- const rules = def.replace(/\|/g, " ").split(" ").filter(Boolean)
205
-
206
- const defaultLabel = conversion.strPascal(field, " ")
207
-
208
- const colLabelRule = rules.find(r => r.includes("column:label,"))
209
- const colLabel = conversion.strPascal(colLabelRule ? colLabelRule.split(",")[1] : defaultLabel, " ")
210
-
211
- const formLabelRule = rules.find(r => r.includes("form:label,"))
212
- const formLabel = conversion.strPascal(formLabelRule ? formLabelRule.split(",")[1] : (colLabelRule ? colLabel : defaultLabel), " ")
213
-
214
- const detailLabel = colLabelRule ? colLabel : (formLabelRule ? formLabel : defaultLabel)
215
-
216
- const hasColumn = rules.some(r => r.includes("column:"))
217
- const hasForm = rules.some(r => r.includes("form:")) || rules.every(r => !r.includes("column:"))
218
-
219
- const hasDetail = rules.includes("detail")
220
-
221
- if (hasColumn) {
222
- columns.push({
223
- selector: field,
224
- label: colLabel,
225
- ...(rules.includes("column:sortable") || rules.includes("sortable") ? { sortable: true } : {})
226
- })
227
- if (!hasDetail) details.push({ label: detailLabel, item: field })
228
- }
229
-
230
- if (hasForm) {
231
- const typeRules = rules.filter(r => !r.startsWith("form:label,"))
232
- const typeRule = extractFormType(typeRules)
233
- let fieldType = inferFormType(typeRule, modelSchema[field] || "");
234
-
235
- let selectPath = ""
236
- const selectRule = rules.find(r => r.startsWith("select,") || r.startsWith("form:select,"))
237
- if (selectRule) {
238
- fieldType = "select"
239
- selectPath = selectRule.split(",")[1]
240
- }
241
-
242
- if (typeRule === "check") fieldType = "boolean"
243
- if (typeRule === "currency") fieldType = "currency"
244
- if (typeRule === "image") fieldType = "image"
245
- if (typeRule === "date") fieldType = "date"
246
- if (typeRule === "time") fieldType = "time"
247
-
248
- let col: number | undefined
249
- const colRule = rules.find(r => /col,(\d+)/.test(r))
250
-
251
- if (colRule) {
252
- const n = Number(colRule.split(',').pop())
253
- if (n >= 1 && n <= 12) col = n
254
- }
255
-
256
- forms.push({
257
- ...(fieldType != "default" && fieldType != "text" ? { type: fieldType } : {}),
258
- ...(col ? { col } : {}),
259
- construction: {
260
- name: field,
261
- label: formLabel,
262
- placeholder: "Masukkan " + formLabel.toLowerCase(),
263
- validations: extractValidationArray(modelSchema[field] || ""),
264
- ...(selectPath ? { serverOptionControl: { path: selectPath } } : {}),
265
- ...(rules.includes("wrap") ? { wrap: true } : {})
266
- }
267
- })
268
- }
269
-
270
- if (hasDetail) details.push({ label: detailLabel, item: field })
271
- }
272
-
273
- const formMap = new Map<string, FormItem>()
274
- forms.forEach(f => formMap.set(f.construction.name, f))
275
-
276
- const nestedForms: FormItem[] = []
277
-
278
- forms.forEach(f => {
279
- const name = f.construction.name
280
- if (name.includes(".")) {
281
- const parts = name.split(".")
282
- const selfName = parts.pop() as string
283
- const parentName = parts.join(".")
284
- const parent = formMap.get(parentName)
285
-
286
- if (parent) {
287
- if (!parent.type) parent.type = "cluster"
288
- if (!parent.construction.fields) parent.construction.fields = []
289
-
290
- f.construction.name = selfName
291
-
292
- parent.construction.fields.push(f)
293
- } else {
294
- nestedForms.push(f)
295
- }
296
- } else {
297
- nestedForms.push(f)
298
- }
299
- })
300
-
301
- return { columns, forms: nestedForms, details }
302
- }
303
-
304
-
305
-
306
- function loadBlueprintFiles(dir: string = "blueprints"): LoadedBlueprintFile[] {
307
- const basePath = path.join(process.cwd(), dir)
308
-
309
- if (!fs.existsSync(basePath)) {
310
- throw new Error("Blueprint folder not found")
311
- }
312
-
313
- return fs.readdirSync(basePath)
314
- .filter(f => f.endsWith(".blueprint.json"))
315
- .map(file => {
316
- const fullPath = path.join(basePath, file)
317
- const content = JSON.parse(fs.readFileSync(fullPath, "utf-8"))
318
-
319
- if (!Array.isArray(content)) {
320
- throw new Error(`${file} must export array of blueprints`)
321
- }
322
-
323
- return {
324
- file: file.replace(".blueprint.json", ""),
325
- blueprints: content as BlueprintStruct[],
326
- }
327
- })
328
- }
329
-
330
- const blueprintMarker = `// ============================================
331
- // ## file THIS FILE IS AUTO-GENERATED BY BLUEPRINT
332
- // ?? Blueprint : {{ blueprint }}
333
- // !! If this comment is removed, blueprint engine WILL NOT override this file.
334
- // ============================================
335
-
336
-
337
- `
338
-
339
-
340
- // ===============================
341
- // ## Main generator
342
- // ===============================
343
-
344
- export async function blueprint(options?: { only?: string[] }): Promise<void> {
345
- const stub = fs.readFileSync(path.join(process.cwd(), "/utils/commands/stubs/table-blueprint.stub"), "utf-8")
346
-
347
- const loaded = loadBlueprintFiles()
348
-
349
- for (const file of loaded) {
350
- for (const bp of file.blueprints) {
351
-
352
- const pagesToGenerate: Record<string, BlueprintPage> = { ...(bp.pages || {}) }
353
-
354
- for (const [key, val] of Object.entries(bp)) {
355
- if (typeof val === "object" && val["schema"]) {
356
- pagesToGenerate[key] = val as BlueprintPage
357
- }
358
- }
359
-
360
- for (const [key, page] of Object.entries(pagesToGenerate)) {
361
-
362
- const route = key;
363
- const name = conversion.strPascal(route.split("/").pop() as string)
364
-
365
- if (options?.only && !options.only.includes(name)) continue
366
-
367
- const outDir = path.join(process.cwd(), "app", route)
368
- fs.mkdirSync(outDir, { recursive: true })
369
-
370
- const filePath = path.join(outDir, "page.tsx");
371
-
372
- if (fs.existsSync(filePath)) {
373
- const content = fs.readFileSync(filePath, "utf-8")
374
-
375
- if (!content.includes("AUTO-GENERATED BY BLUEPRINT")) {
376
- logger.info(`Skip overridden file: ${filePath}`)
377
- continue
378
- }
379
- }
380
-
381
- const schema = bp.schema ?? {}
382
-
383
- const parsed: ParsedSchema = page?.schema ? parsePageSchema(page.schema, schema) : parseModelSchema(schema)
384
-
385
- const { controlBar, action } = parseFeatures(page?.features)
386
-
387
- const fetchPath = resolvePath(page, bp.controllers, bp.model)
388
-
389
- let properties = `
390
- fetchControl={{
391
- path: "${fetchPath}"
392
- }}
393
- columnControl={${renderJS(parsed.columns, 8)}}
394
- formControl={{
395
- fields: ${renderJS(parsed.forms, 10)}
396
- }}
397
- `
398
- if (parsed.details) {
399
- properties += ` detailControl={${renderJS(parsed.details, 8)}}\n`
400
- }
401
-
402
- if (controlBar.length) {
403
- properties += ` controlBar={${JSON.stringify(controlBar)}}\n`
404
- }
405
-
406
- if (action.length) {
407
- properties += ` actionControl={${JSON.stringify(action)}}\n`
408
- }
409
-
410
- const content = stub
411
- .replace(/{{ marker }}/g, blueprintMarker.replace(/{{ blueprint }}/g, file.file + ".blueprint.json"))
412
- .replace(/{{ name }}/g, name)
413
- .replace(/{{ title }}/g, name)
414
- .replace(/{{ properties }}/g, properties)
415
-
416
- fs.writeFileSync(path.join(outDir, "page.tsx"), content)
417
- logger.info(`Generated: ${filePath}`)
418
- }
419
- }
420
- }
421
- }
@@ -1,21 +0,0 @@
1
- import { Command } from "commander";
2
- import { usePdf } from "./use-pdf";
3
- import { blueprint } from "./blueprint";
4
- import { logger } from "./logger";
5
-
6
- const program = new Command();
7
-
8
- program.name("light").description("Next Light CLI").version("1.0.0");
9
-
10
- program.command("use-pdf").description("Copy pdf.worker.min.mjs ke folder public/").action(usePdf );
11
- program.command("blueprint")
12
- .option("-o, --only <names...>", "Run only specific blueprints")
13
- .description("Generate blueprint")
14
- .action(async (opts) => {
15
- await blueprint({ only: opts.only })
16
-
17
- logger.info("Success run all blueprints!")
18
- process.exit(0);
19
- });
20
-
21
- program.parse();
@@ -1,42 +0,0 @@
1
- /* eslint-disable no-console */
2
- type LogType = "start" | "info" | "error" | "warning" | "cavity" | "socket" | "cavityError" | "socketError";
3
-
4
- const colors: Record<LogType | "default", string> = {
5
- default : "\x1b[0m", // default
6
- start : "\x1b[32m", // green
7
- info : "\x1b[36m", // cyan
8
- error : "\x1b[31m", // red
9
- warning : "\x1b[33m", // yellow
10
- cavity : "\x1b[34m", // blue
11
- cavityError : "\x1b[31m", // red
12
- socket : "\x1b[35m", // magenta
13
- socketError : "\x1b[31m", // red
14
- };
15
-
16
- const prefixes: Record<LogType, string> = {
17
- start : "START",
18
- info : "INFO",
19
- error : "ERROR",
20
- warning : "WARNING",
21
- cavity : "CAVITY",
22
- socket : "SOCKET",
23
- cavityError : "CAVITY ERROR",
24
- socketError : "SOCKET ERROR",
25
- };
26
-
27
- function log(type: LogType, ...msg: unknown[]) {
28
- const color = colors[type];
29
- const prefix = prefixes[type];
30
- console.log(`${color}[${prefix}]${colors.default}`, ...msg);
31
- }
32
-
33
- export const logger = {
34
- start : (...msg: unknown[]) => log("start", ...msg),
35
- info : (...msg: unknown[]) => log("info", ...msg),
36
- error : (...msg: unknown[]) => log("error", ...msg),
37
- warning : (...msg: unknown[]) => log("warning", ...msg),
38
- cavity : (...msg: unknown[]) => log("cavity", ...msg),
39
- cavityError : (...msg: unknown[]) => log("cavityError", ...msg),
40
- socket : (...msg: unknown[]) => log("socket", ...msg),
41
- socketError : (...msg: unknown[]) => log("socketError", ...msg),
42
- };
@@ -1,13 +0,0 @@
1
- {{ marker }}
2
- import { TableSupervisionComponent } from "@components";
3
-
4
- export default function {{ name }}Page() {
5
- return (
6
- <>
7
- <TableSupervisionComponent
8
- title="{{ title }}"
9
- {{ properties }}
10
- />
11
- </>
12
- );
13
- }
@@ -1,29 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- import { logger } from "./logger";
5
-
6
- export function usePdf() {
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
9
- const projectRoot = path.join(__dirname, "..", "..");
10
-
11
- const source = path.join(
12
- projectRoot,
13
- "node_modules",
14
- "pdfjs-dist",
15
- "legacy",
16
- "build",
17
- "pdf.worker.min.mjs"
18
- );
19
-
20
- const target = path.join(projectRoot, "public", "pdf.worker.min.mjs");
21
-
22
- if (!fs.existsSync(source)) {
23
- logger.error(`Gagal: pdf.worker.min.mjs tidak ditemukan.`)
24
- process.exit(1);
25
- }
26
-
27
- fs.copyFileSync(source, target);
28
- logger.info("Berhasil memindahkan worker ke public/pdf.worker.min.mjs")
29
- }