crudora 0.1.0 → 0.2.0

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 (58) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +554 -328
  3. package/dist/cli.js +72 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/core/crudora.d.ts +34 -9
  6. package/dist/core/crudora.d.ts.map +1 -1
  7. package/dist/core/crudora.js +254 -105
  8. package/dist/core/crudora.js.map +1 -1
  9. package/dist/core/crudoraServer.d.ts +64 -10
  10. package/dist/core/crudoraServer.d.ts.map +1 -1
  11. package/dist/core/crudoraServer.js +138 -19
  12. package/dist/core/crudoraServer.js.map +1 -1
  13. package/dist/core/drizzleTableBuilder.d.ts +6 -0
  14. package/dist/core/drizzleTableBuilder.d.ts.map +1 -0
  15. package/dist/core/drizzleTableBuilder.js +175 -0
  16. package/dist/core/drizzleTableBuilder.js.map +1 -0
  17. package/dist/core/model.d.ts +28 -9
  18. package/dist/core/model.d.ts.map +1 -1
  19. package/dist/core/model.js +33 -70
  20. package/dist/core/model.js.map +1 -1
  21. package/dist/core/repository.d.ts +98 -14
  22. package/dist/core/repository.d.ts.map +1 -1
  23. package/dist/core/repository.js +561 -103
  24. package/dist/core/repository.js.map +1 -1
  25. package/dist/core/schemaGenerator.d.ts +3 -3
  26. package/dist/core/schemaGenerator.d.ts.map +1 -1
  27. package/dist/core/schemaGenerator.js +237 -32
  28. package/dist/core/schemaGenerator.js.map +1 -1
  29. package/dist/decorators/model.d.ts +56 -1
  30. package/dist/decorators/model.d.ts.map +1 -1
  31. package/dist/decorators/model.js +92 -0
  32. package/dist/decorators/model.js.map +1 -1
  33. package/dist/index.d.ts +7 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +12 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/scripts/copy-assets.js +47 -47
  38. package/dist/scripts/postinstall.js +172 -136
  39. package/dist/templates/.env.example +13 -9
  40. package/dist/templates/drizzle.config.ts +10 -0
  41. package/dist/templates/schema.ts +23 -0
  42. package/dist/types/logger.type.d.ts +7 -0
  43. package/dist/types/logger.type.d.ts.map +1 -0
  44. package/dist/types/logger.type.js +3 -0
  45. package/dist/types/logger.type.js.map +1 -0
  46. package/dist/types/model.type.d.ts +30 -5
  47. package/dist/types/model.type.d.ts.map +1 -1
  48. package/dist/utils/validation.d.ts.map +1 -1
  49. package/dist/utils/validation.js +91 -19
  50. package/dist/utils/validation.js.map +1 -1
  51. package/package.json +108 -94
  52. package/scripts/copy-assets.js +47 -47
  53. package/scripts/postinstall.js +172 -136
  54. package/templates/.env.example +13 -9
  55. package/templates/drizzle.config.ts +10 -0
  56. package/templates/schema.ts +23 -0
  57. package/dist/templates/schema.prisma +0 -22
  58. package/templates/schema.prisma +0 -22
@@ -2,33 +2,105 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ValidationGenerator = void 0;
4
4
  const zod_1 = require("zod");
5
+ const model_1 = require("../decorators/model");
6
+ function zodTypeFor(opts, forStrict) {
7
+ const { type, required = false, nullable = false, length } = opts;
8
+ let base;
9
+ switch (type) {
10
+ case 'integer':
11
+ base = zod_1.z.number().int();
12
+ break;
13
+ case 'number':
14
+ base = zod_1.z.number();
15
+ break;
16
+ case 'boolean':
17
+ base = zod_1.z.boolean();
18
+ break;
19
+ case 'date':
20
+ base = zod_1.z.coerce.date();
21
+ break;
22
+ case 'decimal':
23
+ base = zod_1.z.string().regex(/^-?\d+(\.\d+)?$/, 'Must be a valid decimal number');
24
+ break;
25
+ case 'json':
26
+ base = zod_1.z.union([zod_1.z.record(zod_1.z.string(), zod_1.z.any()), zod_1.z.array(zod_1.z.any())]);
27
+ break;
28
+ case 'uuid':
29
+ base = zod_1.z.uuid();
30
+ break;
31
+ case 'enum':
32
+ base = opts.enumValues?.length
33
+ ? zod_1.z.enum(opts.enumValues)
34
+ : zod_1.z.string();
35
+ break;
36
+ case 'bigint':
37
+ base = zod_1.z.number().int();
38
+ break;
39
+ case 'serial':
40
+ base = zod_1.z.number().int().positive();
41
+ break;
42
+ case 'array':
43
+ base = zod_1.z.array(zod_1.z.string());
44
+ break;
45
+ case 'string':
46
+ base = length ? zod_1.z.string().max(length) : zod_1.z.string();
47
+ break;
48
+ case 'text':
49
+ default:
50
+ base = zod_1.z.string();
51
+ }
52
+ if (nullable)
53
+ base = base.nullable();
54
+ // In strict mode, only required fields stay required; others become optional.
55
+ // In partial mode, everything is optional.
56
+ if (forStrict) {
57
+ return required ? base : base.optional();
58
+ }
59
+ return base.optional();
60
+ }
61
+ const SYSTEM_FIELDS = new Set(['createdAt', 'updatedAt', 'deletedAt']);
62
+ function resolveFields(modelClass) {
63
+ const fieldMeta = (0, model_1.getFieldMetadata)(modelClass);
64
+ const hasMeta = Object.keys(fieldMeta).length > 0;
65
+ const fillable = modelClass.fillable;
66
+ if (hasMeta) {
67
+ // Exclude primary-key and system-managed fields — users must never write these directly
68
+ let entries = Object.entries(fieldMeta).filter(([name, opts]) => !opts.primary && !SYSTEM_FIELDS.has(name));
69
+ // When fillable is defined, restrict validation to only those fields.
70
+ // A field not in fillable (e.g. password set via beforeCreate hook) must not
71
+ // be required from the request body even if it has required: true in @Field().
72
+ if (fillable?.length) {
73
+ entries = entries.filter(([name]) => fillable.includes(name));
74
+ }
75
+ return entries.map(([name, opts]) => ({ name, opts }));
76
+ }
77
+ // Fallback: fillable defined but no @Field() decorators (e.g. registerTable() without decorators).
78
+ // Column types are unknown — treat all as optional strings and let the DB enforce constraints.
79
+ return (fillable ?? []).map((name) => ({
80
+ name,
81
+ opts: { type: 'string', required: false },
82
+ }));
83
+ }
5
84
  class ValidationGenerator {
6
85
  static generateZodSchema(modelClass) {
7
- // Simplified: gunakan static properties langsung dari model class
8
- const fillable = modelClass.fillable || [];
9
- const schemaFields = {};
10
- // Jika tidak ada fillable fields, return empty partial schema
11
- if (fillable.length === 0) {
86
+ const fields = resolveFields(modelClass);
87
+ if (fields.length === 0)
12
88
  return zod_1.z.object({}).partial();
89
+ const shape = {};
90
+ for (const { name, opts } of fields) {
91
+ shape[name] = zodTypeFor(opts, false);
13
92
  }
14
- // Generate basic string validation untuk semua fillable fields
15
- fillable.forEach(fieldName => {
16
- schemaFields[fieldName] = zod_1.z.string().optional();
17
- });
18
- return zod_1.z.object(schemaFields).partial();
93
+ return zod_1.z.object(shape);
19
94
  }
20
95
  static generateStrictZodSchema(modelClass) {
21
- const fillable = modelClass.fillable || [];
22
- const schemaFields = {};
23
- // Jika tidak ada fillable fields, return empty schema
24
- if (fillable.length === 0) {
96
+ const fields = resolveFields(modelClass);
97
+ if (fields.length === 0)
25
98
  return zod_1.z.object({});
99
+ const shape = {};
100
+ for (const { name, opts } of fields) {
101
+ shape[name] = zodTypeFor(opts, true);
26
102
  }
27
- // Generate basic string validation untuk semua fillable fields
28
- fillable.forEach(fieldName => {
29
- schemaFields[fieldName] = zod_1.z.string();
30
- });
31
- return zod_1.z.object(schemaFields);
103
+ return zod_1.z.object(shape);
32
104
  }
33
105
  }
34
106
  exports.ValidationGenerator = ValidationGenerator;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAGxB,MAAa,mBAAmB;IAC9B,MAAM,CAAC,iBAAiB,CAAkB,UAA+B;QACvE,kEAAkE;QAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC3C,MAAM,YAAY,GAAiC,EAAE,CAAC;QAEtD,8DAA8D;QAC9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,EAAS,CAAC;QACvC,CAAC;QAED,+DAA+D;QAC/D,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC3B,YAAY,CAAC,SAAS,CAAC,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,OAAO,OAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAS,CAAC;IACjD,CAAC;IAED,MAAM,CAAC,uBAAuB,CAAkB,UAA+B;QAC7E,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC3C,MAAM,YAAY,GAAiC,EAAE,CAAC;QAEtD,sDAAsD;QACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,OAAC,CAAC,MAAM,CAAC,EAAE,CAAQ,CAAC;QAC7B,CAAC;QAED,+DAA+D;QAC/D,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC3B,YAAY,CAAC,SAAS,CAAC,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,OAAO,OAAC,CAAC,MAAM,CAAC,YAAY,CAAQ,CAAC;IACvC,CAAC;CACF;AAnCD,kDAmCC"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,94 +1,108 @@
1
- {
2
- "name": "crudora",
3
- "version": "0.1.0",
4
- "type": "module",
5
- "main": "dist/index.cjs",
6
- "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "require": "./dist/index.cjs",
12
- "types": "./dist/index.d.ts"
13
- },
14
- "./package.json": "./package.json"
15
- },
16
- "files": [
17
- "dist",
18
- "README.md",
19
- "LICENSE",
20
- "templates",
21
- "scripts"
22
- ],
23
- "scripts": {
24
- "build": "tsc && node scripts/copy-assets.js",
25
- "copy-assets": "node scripts/copy-assets.js",
26
- "build:watch": "tsc --watch",
27
- "clean": "rimraf dist",
28
- "prebuild": "npm run clean",
29
- "prepublishOnly": "npm run build",
30
- "dev": "ts-node src/index.ts",
31
- "test": "jest",
32
- "test:watch": "jest --watch",
33
- "test:coverage": "jest --coverage",
34
- "lint": "eslint src/**/*.ts",
35
- "format": "prettier --write src/**/*.ts",
36
- "postinstall": "node scripts/postinstall.js || echo 'Postinstall script failed, but continuing...'"
37
- },
38
- "keywords": [
39
- "crud",
40
- "api",
41
- "typescript",
42
- "prisma",
43
- "express",
44
- "framework",
45
- "backend",
46
- "rest-api",
47
- "orm",
48
- "validation",
49
- "zod",
50
- "decorators",
51
- "auto-generation"
52
- ],
53
- "repository": {
54
- "type": "git",
55
- "url": "git+https://github.com/suryamsj/crudora.git"
56
- },
57
- "bugs": {
58
- "url": "https://github.com/suryamsj/crudora/issues"
59
- },
60
- "homepage": "https://github.com/suryamsj/crudora#readme",
61
- "author": {
62
- "name": "Muhammad Surya J",
63
- "url": "https://suryamsj.my.id"
64
- },
65
- "license": "MIT",
66
- "description": "TypeScript framework for automated CRUD API generation with Prisma and Express",
67
- "dependencies": {
68
- "@types/express": "^5.0.3",
69
- "commander": "^14.0.0",
70
- "express": "^5.1.0",
71
- "jest-mock-extended": "^4.0.0",
72
- "reflect-metadata": "^0.2.2",
73
- "zod": "^4.0.5"
74
- },
75
- "devDependencies": {
76
- "@types/jest": "^30.0.0",
77
- "@types/node": "^24.0.15",
78
- "@types/supertest": "^6.0.3",
79
- "@typescript-eslint/eslint-plugin": "^8.38.0",
80
- "@typescript-eslint/parser": "^8.38.0",
81
- "eslint": "^9.31.0",
82
- "jest": "^30.0.4",
83
- "prettier": "^3.6.2",
84
- "rimraf": "^6.0.1",
85
- "supertest": "^7.1.3",
86
- "ts-jest": "^29.4.0",
87
- "ts-node": "^10.9.2",
88
- "typescript": "^5.8.3"
89
- },
90
- "peerDependencies": {
91
- "@prisma/client": "^6.12.0",
92
- "prisma": "^6.12.0"
93
- }
94
- }
1
+ {
2
+ "name": "crudora",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "crudora": "./dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs",
15
+ "types": "./dist/index.d.ts"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE",
23
+ "templates",
24
+ "scripts"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc && tsc -p tsconfig.cli.json && node scripts/copy-assets.js",
28
+ "copy-assets": "node scripts/copy-assets.js",
29
+ "build:watch": "tsc --watch",
30
+ "clean": "rimraf dist",
31
+ "prebuild": "npm run clean",
32
+ "prepublishOnly": "npm run build",
33
+ "dev": "ts-node src/index.ts",
34
+ "test": "jest",
35
+ "test:watch": "jest --watch",
36
+ "test:coverage": "jest --coverage",
37
+ "lint": "eslint src/**/*.ts",
38
+ "format": "prettier --write src/**/*.ts",
39
+ "postinstall": "node scripts/postinstall.js || echo 'Postinstall script failed, but continuing...'"
40
+ },
41
+ "keywords": [
42
+ "crud",
43
+ "api",
44
+ "typescript",
45
+ "drizzle",
46
+ "express",
47
+ "framework",
48
+ "backend",
49
+ "rest-api",
50
+ "orm",
51
+ "validation",
52
+ "zod",
53
+ "decorators",
54
+ "auto-generation",
55
+ "multiple-schema"
56
+ ],
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/suryamsj/crudora.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/suryamsj/crudora/issues"
63
+ },
64
+ "homepage": "https://github.com/suryamsj/crudora#readme",
65
+ "author": {
66
+ "name": "Muhammad Surya J",
67
+ "url": "https://suryamsj.my.id"
68
+ },
69
+ "license": "MIT",
70
+ "description": "TypeScript framework for automated CRUD API generation with Drizzle ORM and Express",
71
+ "dependencies": {
72
+ "@types/express": "^5.0.3",
73
+ "commander": "^14.0.0",
74
+ "express": "^5.1.0",
75
+ "reflect-metadata": "^0.2.2",
76
+ "zod": "^4.0.5"
77
+ },
78
+ "devDependencies": {
79
+ "@types/jest": "^30.0.0",
80
+ "@types/node": "^24.0.15",
81
+ "@types/supertest": "^6.0.3",
82
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
83
+ "@typescript-eslint/parser": "^8.38.0",
84
+ "drizzle-kit": "^0.31.10",
85
+ "eslint": "^9.31.0",
86
+ "jest": "^30.0.4",
87
+ "prettier": "^3.6.2",
88
+ "rimraf": "^6.0.1",
89
+ "supertest": "^7.1.3",
90
+ "ts-jest": "^29.4.0",
91
+ "ts-node": "^10.9.2",
92
+ "typescript": "^5.8.3"
93
+ },
94
+ "peerDependencies": {
95
+ "drizzle-orm": "^0.40.0"
96
+ },
97
+ "peerDependenciesMeta": {
98
+ "pg": {
99
+ "optional": true
100
+ },
101
+ "postgres": {
102
+ "optional": true
103
+ },
104
+ "mysql2": {
105
+ "optional": true
106
+ }
107
+ }
108
+ }
@@ -1,47 +1,47 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { fileURLToPath } from 'url';
4
-
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = path.dirname(__filename);
7
-
8
- function copyDir(src, dest) {
9
- if (!fs.existsSync(dest)) {
10
- fs.mkdirSync(dest, { recursive: true });
11
- }
12
-
13
- const entries = fs.readdirSync(src, { withFileTypes: true });
14
-
15
- for (const entry of entries) {
16
- const srcPath = path.join(src, entry.name);
17
- const destPath = path.join(dest, entry.name);
18
-
19
- if (entry.isDirectory()) {
20
- copyDir(srcPath, destPath);
21
- } else {
22
- fs.copyFileSync(srcPath, destPath);
23
- }
24
- }
25
- }
26
-
27
- // Copy templates
28
- copyDir('templates', 'dist/templates');
29
- copyDir('scripts', 'dist/scripts');
30
-
31
- // Make sure bin directory exists
32
- if (!fs.existsSync('dist/bin')) {
33
- fs.mkdirSync('dist/bin', { recursive: true });
34
- }
35
-
36
- // Ensure bin file is executable
37
- if (fs.existsSync('bin/crudora.js')) {
38
- fs.copyFileSync('bin/crudora.js', 'dist/bin/crudora.js');
39
- try {
40
- // Make executable on Unix systems
41
- fs.chmodSync('dist/bin/crudora.js', '755');
42
- } catch (error) {
43
- // Ignore errors on Windows
44
- }
45
- }
46
-
47
- console.log('✅ Assets copied to dist/');
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ function copyDir(src, dest) {
9
+ if (!fs.existsSync(dest)) {
10
+ fs.mkdirSync(dest, { recursive: true });
11
+ }
12
+
13
+ const entries = fs.readdirSync(src, { withFileTypes: true });
14
+
15
+ for (const entry of entries) {
16
+ const srcPath = path.join(src, entry.name);
17
+ const destPath = path.join(dest, entry.name);
18
+
19
+ if (entry.isDirectory()) {
20
+ copyDir(srcPath, destPath);
21
+ } else {
22
+ fs.copyFileSync(srcPath, destPath);
23
+ }
24
+ }
25
+ }
26
+
27
+ // Copy templates
28
+ copyDir('templates', 'dist/templates');
29
+ copyDir('scripts', 'dist/scripts');
30
+
31
+ // Make sure bin directory exists
32
+ if (!fs.existsSync('dist/bin')) {
33
+ fs.mkdirSync('dist/bin', { recursive: true });
34
+ }
35
+
36
+ // Ensure bin file is executable
37
+ if (fs.existsSync('bin/crudora.js')) {
38
+ fs.copyFileSync('bin/crudora.js', 'dist/bin/crudora.js');
39
+ try {
40
+ // Make executable on Unix systems
41
+ fs.chmodSync('dist/bin/crudora.js', '755');
42
+ } catch (error) {
43
+ // Ignore errors on Windows
44
+ }
45
+ }
46
+
47
+ console.log('✅ Assets copied to dist/');