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
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Model = exports.ValidationGenerator = exports.SchemaGenerator = exports.Repository = exports.CrudoraServer = exports.Crudora = void 0;
3
+ exports.getRelationMetadata = exports.getFieldMetadata = exports.BelongsToMany = exports.BelongsTo = exports.HasOne = exports.HasMany = exports.Field = exports.Model = exports.ValidationGenerator = exports.DrizzleTableBuilder = exports.SchemaGenerator = exports.NotFoundError = exports.Repository = exports.CrudoraServer = exports.Crudora = void 0;
4
4
  require("reflect-metadata");
5
5
  var crudora_1 = require("./core/crudora");
6
6
  Object.defineProperty(exports, "Crudora", { enumerable: true, get: function () { return crudora_1.Crudora; } });
@@ -8,10 +8,21 @@ var crudoraServer_1 = require("./core/crudoraServer");
8
8
  Object.defineProperty(exports, "CrudoraServer", { enumerable: true, get: function () { return crudoraServer_1.CrudoraServer; } });
9
9
  var repository_1 = require("./core/repository");
10
10
  Object.defineProperty(exports, "Repository", { enumerable: true, get: function () { return repository_1.Repository; } });
11
+ Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return repository_1.NotFoundError; } });
11
12
  var schemaGenerator_1 = require("./core/schemaGenerator");
12
13
  Object.defineProperty(exports, "SchemaGenerator", { enumerable: true, get: function () { return schemaGenerator_1.SchemaGenerator; } });
14
+ var drizzleTableBuilder_1 = require("./core/drizzleTableBuilder");
15
+ Object.defineProperty(exports, "DrizzleTableBuilder", { enumerable: true, get: function () { return drizzleTableBuilder_1.DrizzleTableBuilder; } });
13
16
  var validation_1 = require("./utils/validation");
14
17
  Object.defineProperty(exports, "ValidationGenerator", { enumerable: true, get: function () { return validation_1.ValidationGenerator; } });
15
18
  var model_1 = require("./core/model");
16
19
  Object.defineProperty(exports, "Model", { enumerable: true, get: function () { return model_1.Model; } });
20
+ var model_2 = require("./decorators/model");
21
+ Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return model_2.Field; } });
22
+ Object.defineProperty(exports, "HasMany", { enumerable: true, get: function () { return model_2.HasMany; } });
23
+ Object.defineProperty(exports, "HasOne", { enumerable: true, get: function () { return model_2.HasOne; } });
24
+ Object.defineProperty(exports, "BelongsTo", { enumerable: true, get: function () { return model_2.BelongsTo; } });
25
+ Object.defineProperty(exports, "BelongsToMany", { enumerable: true, get: function () { return model_2.BelongsToMany; } });
26
+ Object.defineProperty(exports, "getFieldMetadata", { enumerable: true, get: function () { return model_2.getFieldMetadata; } });
27
+ Object.defineProperty(exports, "getRelationMetadata", { enumerable: true, get: function () { return model_2.getRelationMetadata; } });
17
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAC1B,0CAAyC;AAAhC,kGAAA,OAAO,OAAA;AAChB,sDAAqD;AAA5C,8GAAA,aAAa,OAAA;AACtB,gDAA+C;AAAtC,wGAAA,UAAU,OAAA;AACnB,0DAAyD;AAAhD,kHAAA,eAAe,OAAA;AACxB,iDAAyD;AAAhD,iHAAA,mBAAmB,OAAA;AAC5B,sCAAqC;AAA5B,8FAAA,KAAK,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAC1B,0CAAyC;AAAhC,kGAAA,OAAO,OAAA;AAChB,sDAAqD;AAA5C,8GAAA,aAAa,OAAA;AAEtB,gDAA8D;AAArD,wGAAA,UAAU,OAAA;AAAE,2GAAA,aAAa,OAAA;AAElC,0DAAyD;AAAhD,kHAAA,eAAe,OAAA;AACxB,kEAAiE;AAAxD,0HAAA,mBAAmB,OAAA;AAC5B,iDAAyD;AAAhD,iHAAA,mBAAmB,OAAA;AAC5B,sCAAqC;AAA5B,8FAAA,KAAK,OAAA;AAEd,4CAQ4B;AAP1B,8FAAA,KAAK,OAAA;AACL,gGAAA,OAAO,OAAA;AACP,+FAAA,MAAM,OAAA;AACN,kGAAA,SAAS,OAAA;AACT,sGAAA,aAAa,OAAA;AACb,yGAAA,gBAAgB,OAAA;AAChB,4GAAA,mBAAmB,OAAA"}
@@ -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/');
@@ -1,136 +1,172 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
- // Paths
5
- const templatePath = path.join(__dirname, '..', 'templates', 'schema.prisma');
6
- const targetPrismaPath = path.join(process.cwd(), 'prisma', 'schema.prisma');
7
- const targetEnvPath = path.join(process.cwd(), '.env');
8
- const targetServerPath = path.join(process.cwd(), 'src', 'server.ts');
9
- const targetPackagePath = path.join(process.cwd(), 'package.json');
10
-
11
- console.log('🚀 Setting up Crudora project...');
12
-
13
- // 1. Create prisma directory and schema
14
- if (!fs.existsSync(path.dirname(targetPrismaPath))) {
15
- console.log('📋 Creating Prisma schema...');
16
- fs.mkdirSync(path.dirname(targetPrismaPath), { recursive: true });
17
- fs.copyFileSync(templatePath, targetPrismaPath);
18
- console.log('✅ Prisma schema created at prisma/schema.prisma');
19
- } else {
20
- console.log('📋 Prisma directory already exists, skipping schema creation');
21
- }
22
-
23
- // 2. Create .env file
24
- if (!fs.existsSync(targetEnvPath)) {
25
- console.log('🔧 Creating .env file...');
26
- const envContent = `# Database
27
- DATABASE_URL="file:./dev.db"
28
-
29
- # Server
30
- PORT=3000
31
- NODE_ENV=development
32
-
33
- # API
34
- API_BASE_PATH="/api"
35
- `;
36
- fs.writeFileSync(targetEnvPath, envContent);
37
- console.log(' .env file created');
38
- } else {
39
- console.log('🔧 .env file already exists, skipping creation');
40
- }
41
-
42
- // 3. Create basic server setup
43
- if (!fs.existsSync(targetServerPath)) {
44
- console.log('🖥️ Creating server setup...');
45
- const serverContent = `const { CrudoraServer } = require('crudora');
46
- const { PrismaClient } = require('@prisma/client');
47
- require('dotenv').config();
48
-
49
- const prisma = new PrismaClient();
50
-
51
- // Example User model (uncomment and modify as needed)
52
- /*
53
- class User {
54
- static tableName = 'users';
55
- static primaryKey = 'id';
56
- static timestamps = true;
57
- static fillable = ['name', 'email'];
58
- static hidden = ['password'];
59
- }
60
- */
61
-
62
- const server = new CrudoraServer({
63
- port: process.env.PORT || 3000,
64
- prisma: prisma,
65
- cors: true,
66
- basePath: process.env.API_BASE_PATH || '/api'
67
- });
68
-
69
- // Register your models here
70
- // server.registerModel(User);
71
-
72
- // Add custom routes if needed
73
- server.get('/health', (req, res) => {
74
- res.json({ status: 'ok', timestamp: new Date() });
75
- });
76
-
77
- // Generate routes and start server
78
- server
79
- .generateRoutes()
80
- .listen(() => {
81
- console.log('🚀 Crudora server is running!');
82
- console.log(\`📚 API documentation: http://localhost:\${process.env.PORT || 3000}\${process.env.API_BASE_PATH || '/api'}\`);
83
- });
84
- `;
85
- fs.writeFileSync(targetServerPath, serverContent);
86
- console.log('✅ Server setup created at server.ts');
87
- } else {
88
- console.log('🖥️ server.ts already exists, skipping creation');
89
- }
90
-
91
- // 4. Update package.json scripts (if package.json exists)
92
- if (fs.existsSync(targetPackagePath)) {
93
- try {
94
- const packageJson = JSON.parse(fs.readFileSync(targetPackagePath, 'utf8'));
95
-
96
- if (!packageJson.scripts) {
97
- packageJson.scripts = {};
98
- }
99
-
100
- // Add useful scripts if they don't exist
101
- const scriptsToAdd = {
102
- 'build': 'tsc',
103
- 'dev': 'ts-node src/server.ts',
104
- 'start': 'ts-node src/server.ts',
105
- 'start:prod': 'node dist/index.js',
106
- 'db:generate': 'prisma generate',
107
- 'db:push': 'prisma db push',
108
- 'db:migrate': 'prisma migrate dev',
109
- 'db:studio': 'prisma studio'
110
- };
111
-
112
- let scriptsAdded = false;
113
- for (const [scriptName, scriptCommand] of Object.entries(scriptsToAdd)) {
114
- if (!packageJson.scripts[scriptName]) {
115
- packageJson.scripts[scriptName] = scriptCommand;
116
- scriptsAdded = true;
117
- }
118
- }
119
-
120
- if (scriptsAdded) {
121
- fs.writeFileSync(targetPackagePath, JSON.stringify(packageJson, null, 2));
122
- console.log('✅ Package.json scripts updated');
123
- }
124
- } catch (error) {
125
- console.log('⚠️ Could not update package.json scripts:', error.message);
126
- }
127
- }
128
-
129
- console.log('\n🎉 Crudora setup complete!');
130
- console.log('\n📝 Next steps:');
131
- console.log('1. Install dependencies: npm install @prisma/client prisma dotenv');
132
- console.log('2. Generate Prisma client: npm run db:generate');
133
- console.log('3. Push database schema: npm run db:push');
134
- console.log('4. Define your models in server.js');
135
- console.log('5. Start development server: npm run dev');
136
- console.log('\n📖 Documentation: https://github.com/suryamsj/crudora#readme');
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
+ // ─── Skip guards ──────────────────────────────────────────────────────────────
9
+ // Opt-out: set CRUDORA_SKIP_POSTINSTALL=1 in CI pipelines or Docker builds.
10
+ if (process.env.CRUDORA_SKIP_POSTINSTALL) {
11
+ process.exit(0);
12
+ }
13
+
14
+ // Many CI systems set CI=true — don't scaffold files into a CI workspace.
15
+ if (process.env.CI) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Running inside node_modules means someone else is installing crudora as a dep.
20
+ // Scaffold into their project root (process.cwd()), not the package directory.
21
+ // Guard: if there's no package.json in cwd, we're probably not in a real project.
22
+ const cwdPkgPath = path.join(process.cwd(), 'package.json');
23
+ if (!fs.existsSync(cwdPkgPath)) {
24
+ process.exit(0);
25
+ }
26
+
27
+ // ─── Peer dependency check ────────────────────────────────────────────────────
28
+ try {
29
+ const cwdPkg = JSON.parse(fs.readFileSync(cwdPkgPath, 'utf-8'));
30
+ const hasDrizzle =
31
+ cwdPkg.dependencies?.['drizzle-orm'] ||
32
+ cwdPkg.devDependencies?.['drizzle-orm'];
33
+ if (!hasDrizzle) {
34
+ console.warn(
35
+ '\n⚠️ Crudora: drizzle-orm is not listed in your dependencies.\n' +
36
+ ' Run: npm install drizzle-orm\n' +
37
+ ' Also install the driver for your database:\n' +
38
+ ' PostgreSQL: npm install pg\n' +
39
+ ' MySQL: npm install mysql2\n',
40
+ );
41
+ }
42
+ } catch {
43
+ // Non-fatal — package.json may not be JSON-parseable
44
+ }
45
+
46
+ const templateDir = path.join(__dirname, '..', 'templates');
47
+ const targetEnvPath = path.join(process.cwd(), '.env');
48
+ const targetServerPath = path.join(process.cwd(), 'src', 'server.ts');
49
+ const targetDrizzleConfig = path.join(process.cwd(), 'drizzle.config.ts');
50
+ const targetSchemaDir = path.join(process.cwd(), 'src', 'db');
51
+ const targetSchemaPath = path.join(targetSchemaDir, 'schema.ts');
52
+
53
+ console.log('🚀 Setting up Crudora project...');
54
+
55
+ // 1. Create .env file
56
+ if (!fs.existsSync(targetEnvPath)) {
57
+ console.log('🔧 Creating .env file...');
58
+ const envContent = `# Database — choose one based on your dialect
59
+ # PostgreSQL
60
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
61
+
62
+ # MySQL (uncomment if using MySQL)
63
+ # DATABASE_URL="mysql://user:password@localhost:3306/mydb"
64
+
65
+ # Server
66
+ PORT=3000
67
+ NODE_ENV=development
68
+
69
+ # API
70
+ API_BASE_PATH="/api"
71
+ `;
72
+ fs.writeFileSync(targetEnvPath, envContent);
73
+ console.log(' .env file created');
74
+ } else {
75
+ console.log('🔧 .env file already exists, skipping creation');
76
+ }
77
+
78
+ // 2. Create drizzle.config.ts
79
+ if (!fs.existsSync(targetDrizzleConfig)) {
80
+ console.log('📋 Creating drizzle.config.ts...');
81
+ fs.copyFileSync(path.join(templateDir, 'drizzle.config.ts'), targetDrizzleConfig);
82
+ console.log('✅ drizzle.config.ts created');
83
+ } else {
84
+ console.log('📋 drizzle.config.ts already exists, skipping');
85
+ }
86
+
87
+ // 3. Create src/db/schema.ts
88
+ if (!fs.existsSync(targetSchemaPath)) {
89
+ console.log('📋 Creating src/db/schema.ts...');
90
+ if (!fs.existsSync(targetSchemaDir)) {
91
+ fs.mkdirSync(targetSchemaDir, { recursive: true });
92
+ }
93
+ fs.copyFileSync(path.join(templateDir, 'schema.ts'), targetSchemaPath);
94
+ console.log('✅ src/db/schema.ts created');
95
+ } else {
96
+ console.log('📋 src/db/schema.ts already exists, skipping');
97
+ }
98
+
99
+ // 4. Create basic server setup
100
+ if (!fs.existsSync(targetServerPath)) {
101
+ console.log('🖥️ Creating server setup...');
102
+ const serverContent = `import { CrudoraServer, Model, Field } from 'crudora';
103
+ import { drizzle } from 'drizzle-orm/node-postgres';
104
+ import { Pool } from 'pg';
105
+ import 'dotenv/config';
106
+
107
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL });
108
+ const db = drizzle(pool);
109
+
110
+ // Example User model (uncomment and modify as needed)
111
+ /*
112
+ class User extends Model {
113
+ static schema = 'auth'; // optional: database schema
114
+ static tableName = 'users';
115
+ static hidden = ['password'];
116
+
117
+ @Field({ type: 'uuid', primary: true })
118
+ id!: string;
119
+
120
+ @Field({ type: 'string', required: true, unique: true })
121
+ email!: string;
122
+
123
+ @Field({ type: 'string', required: true })
124
+ password!: string;
125
+ }
126
+ */
127
+
128
+ const server = new CrudoraServer({
129
+ port: Number(process.env.PORT) || 3000,
130
+ db,
131
+ dialect: 'postgresql',
132
+ cors: true,
133
+ basePath: process.env.API_BASE_PATH || '/api',
134
+ });
135
+
136
+ // Register your models here
137
+ // server.registerModel(User);
138
+
139
+ server.get('/health', (_req, res) => {
140
+ res.json({ success: true, data: { status: 'ok', timestamp: new Date() } });
141
+ });
142
+
143
+ server
144
+ .generateRoutes()
145
+ .listen(() => {
146
+ console.log('🚀 Crudora server is running!');
147
+ });
148
+ `;
149
+ if (!fs.existsSync(path.dirname(targetServerPath))) {
150
+ fs.mkdirSync(path.dirname(targetServerPath), { recursive: true });
151
+ }
152
+ fs.writeFileSync(targetServerPath, serverContent);
153
+ console.log('✅ Server setup created at src/server.ts');
154
+ } else {
155
+ console.log('🖥️ src/server.ts already exists, skipping creation');
156
+ }
157
+
158
+ console.log('\n🎉 Crudora setup complete!');
159
+ console.log('\n📝 Next steps:');
160
+ console.log('1. Install dependencies: npm install drizzle-orm pg');
161
+ console.log('2. Update DATABASE_URL in .env');
162
+ console.log('3. Define your models in src/server.ts');
163
+ console.log('4. Add these scripts to your package.json:');
164
+ console.log(' "dev": "ts-node src/server.ts"');
165
+ console.log(' "build": "tsc"');
166
+ console.log(' "db:generate": "drizzle-kit generate"');
167
+ console.log(' "db:push": "drizzle-kit push"');
168
+ console.log(' "db:migrate": "drizzle-kit migrate"');
169
+ console.log(' "db:studio": "drizzle-kit studio"');
170
+ console.log('5. Push schema to DB: npx drizzle-kit push');
171
+ console.log('6. Start server: npx ts-node src/server.ts');
172
+ console.log('\n📖 Documentation: https://github.com/suryamsj/crudora#readme');
@@ -1,9 +1,13 @@
1
- # Database
2
- DATABASE_URL="file:./dev.db"
3
-
4
- # Server
5
- PORT=3000
6
- NODE_ENV=development
7
-
8
- # API
9
- API_BASE_PATH="/api"
1
+ # Database — choose one based on your dialect
2
+ # PostgreSQL
3
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
4
+
5
+ # MySQL (uncomment if using MySQL)
6
+ # DATABASE_URL="mysql://user:password@localhost:3306/mydb"
7
+
8
+ # Server
9
+ PORT=3000
10
+ NODE_ENV=development
11
+
12
+ # API
13
+ API_BASE_PATH="/api"
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'drizzle-kit';
2
+
3
+ export default defineConfig({
4
+ schema: './src/db/schema.ts',
5
+ out: './drizzle',
6
+ dialect: 'postgresql', // or 'mysql'
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL!,
9
+ },
10
+ });
@@ -0,0 +1,23 @@
1
+ // Auto-generated by Crudora — do not edit manually
2
+ // Run: npx crudora generate-schema > src/db/schema.ts
3
+ //
4
+ // Example schema with multiple PostgreSQL schemas:
5
+ //
6
+ // import { pgTable, pgSchema, uuid, varchar, timestamp } from 'drizzle-orm/pg-core';
7
+ //
8
+ // const authSchema = pgSchema('auth');
9
+ //
10
+ // export const usersTable = authSchema.table('users', {
11
+ // id: uuid('id').primaryKey(),
12
+ // email: varchar('email', { length: 255 }).notNull().unique(),
13
+ // password: varchar('password', { length: 255 }).notNull(),
14
+ // createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow().notNull(),
15
+ // updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow().notNull(),
16
+ // });
17
+ //
18
+ // export const postsTable = pgTable('posts', {
19
+ // id: uuid('id').primaryKey(),
20
+ // title: varchar('title', { length: 255 }).notNull(),
21
+ // createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow().notNull(),
22
+ // updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow().notNull(),
23
+ // });
@@ -0,0 +1,7 @@
1
+ export interface CrudoraLogger {
2
+ error(message: string, context?: Record<string, any>): void;
3
+ warn(message: string, context?: Record<string, any>): void;
4
+ info(message: string, context?: Record<string, any>): void;
5
+ debug(message: string, context?: Record<string, any>): void;
6
+ }
7
+ //# sourceMappingURL=logger.type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.type.d.ts","sourceRoot":"","sources":["../../src/types/logger.type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC3D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC3D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CAC7D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=logger.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.type.js","sourceRoot":"","sources":["../../src/types/logger.type.ts"],"names":[],"mappings":""}
@@ -1,13 +1,38 @@
1
- export interface ModelOptions {
2
- tableName?: string;
3
- timestamps?: boolean;
4
- }
1
+ export type FieldType = 'string' | 'text' | 'integer' | 'number' | 'boolean' | 'date' | 'uuid' | 'decimal' | 'json' | 'enum' | 'bigint' | 'serial' | 'array';
5
2
  export interface FieldOptions {
6
- type: 'string' | 'number' | 'boolean' | 'date' | 'uuid';
3
+ type: FieldType;
7
4
  required?: boolean;
8
5
  unique?: boolean;
9
6
  default?: any;
10
7
  length?: number;
11
8
  primary?: boolean;
9
+ nullable?: boolean;
10
+ precision?: number;
11
+ scale?: number;
12
+ /** Required when type is 'enum'. Lists the allowed values. */
13
+ enumValues?: string[];
14
+ }
15
+ export interface ModelOptions {
16
+ tableName?: string;
17
+ timestamps?: boolean;
18
+ }
19
+ export type Dialect = 'postgresql' | 'mysql';
20
+ export type RelationType = 'hasOne' | 'hasMany' | 'belongsTo' | 'belongsToMany';
21
+ export interface RelationDefinition {
22
+ type: RelationType;
23
+ /** Lazy model getter — avoids circular-import issues */
24
+ model: () => any;
25
+ /** The foreign-key column name */
26
+ foreignKey: string;
27
+ /**
28
+ * hasOne / hasMany: column on the owning (local) side. Defaults to the model's primary key.
29
+ * belongsTo : column on the related side (the "owner"). Defaults to the related model's primary key.
30
+ * belongsToMany: override for this model's local key (defaults to primary key).
31
+ */
32
+ relatedKey?: string;
33
+ /** Lazy getter returning the pivot/junction model constructor. */
34
+ pivotModel?: () => any;
35
+ /** Column on the pivot table that points to the **related** model. */
36
+ pivotRelatedKey?: string;
12
37
  }
13
38
  //# sourceMappingURL=model.type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.type.d.ts","sourceRoot":"","sources":["../../src/types/model.type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
1
+ {"version":3,"file":"model.type.d.ts","sourceRoot":"","sources":["../../src/types/model.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,MAAM,GACN,SAAS,GACT,QAAQ,GACR,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,eAAe,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,wDAAwD;IACxD,KAAK,EAAE,MAAM,GAAG,CAAC;IACjB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC;IACvB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAExD,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAkBjG,MAAM,CAAC,uBAAuB,CAAC,CAAC,SAAS,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;CAgBjG"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA4FxD,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAWjG,MAAM,CAAC,uBAAuB,CAAC,CAAC,SAAS,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;CAUjG"}