@rapidd/build 1.2.3 → 2.0.1

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 (71) hide show
  1. package/README.md +219 -68
  2. package/dist/bin/cli.d.ts +3 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +31 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/index.d.ts +18 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +32 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/src/commands/build.d.ts +17 -0
  11. package/dist/src/commands/build.d.ts.map +1 -0
  12. package/dist/src/commands/build.js +236 -0
  13. package/dist/src/commands/build.js.map +1 -0
  14. package/dist/src/generators/aclGenerator.d.ts +6 -0
  15. package/dist/src/generators/aclGenerator.d.ts.map +1 -0
  16. package/dist/src/generators/aclGenerator.js +384 -0
  17. package/dist/src/generators/aclGenerator.js.map +1 -0
  18. package/dist/src/generators/index.d.ts +4 -0
  19. package/dist/src/generators/index.d.ts.map +1 -0
  20. package/dist/src/generators/index.js +13 -0
  21. package/dist/src/generators/index.js.map +1 -0
  22. package/dist/src/generators/modelGenerator.d.ts +10 -0
  23. package/dist/src/generators/modelGenerator.d.ts.map +1 -0
  24. package/dist/src/generators/modelGenerator.js +143 -0
  25. package/dist/src/generators/modelGenerator.js.map +1 -0
  26. package/dist/src/generators/routeGenerator.d.ts +10 -0
  27. package/dist/src/generators/routeGenerator.d.ts.map +1 -0
  28. package/dist/src/generators/routeGenerator.js +148 -0
  29. package/dist/src/generators/routeGenerator.js.map +1 -0
  30. package/dist/src/parsers/datasourceParser.d.ts +11 -0
  31. package/dist/src/parsers/datasourceParser.d.ts.map +1 -0
  32. package/dist/src/parsers/datasourceParser.js +131 -0
  33. package/dist/src/parsers/datasourceParser.js.map +1 -0
  34. package/dist/src/parsers/deepSQLAnalyzer.d.ts +85 -0
  35. package/dist/src/parsers/deepSQLAnalyzer.d.ts.map +1 -0
  36. package/dist/src/parsers/deepSQLAnalyzer.js +482 -0
  37. package/dist/src/parsers/deepSQLAnalyzer.js.map +1 -0
  38. package/dist/src/parsers/enhancedRLSConverter.d.ts +14 -0
  39. package/dist/src/parsers/enhancedRLSConverter.d.ts.map +1 -0
  40. package/dist/src/parsers/enhancedRLSConverter.js +168 -0
  41. package/dist/src/parsers/enhancedRLSConverter.js.map +1 -0
  42. package/dist/src/parsers/functionAnalyzer.d.ts +55 -0
  43. package/dist/src/parsers/functionAnalyzer.d.ts.map +1 -0
  44. package/dist/src/parsers/functionAnalyzer.js +274 -0
  45. package/dist/src/parsers/functionAnalyzer.js.map +1 -0
  46. package/dist/src/parsers/index.d.ts +13 -0
  47. package/dist/src/parsers/index.d.ts.map +1 -0
  48. package/dist/src/parsers/index.js +20 -0
  49. package/dist/src/parsers/index.js.map +1 -0
  50. package/dist/src/parsers/prismaFilterBuilder.d.ts +79 -0
  51. package/dist/src/parsers/prismaFilterBuilder.d.ts.map +1 -0
  52. package/dist/src/parsers/prismaFilterBuilder.js +322 -0
  53. package/dist/src/parsers/prismaFilterBuilder.js.map +1 -0
  54. package/dist/src/parsers/prismaParser.d.ts +14 -0
  55. package/dist/src/parsers/prismaParser.d.ts.map +1 -0
  56. package/dist/src/parsers/prismaParser.js +263 -0
  57. package/dist/src/parsers/prismaParser.js.map +1 -0
  58. package/package.json +21 -13
  59. package/bin/cli.js +0 -33
  60. package/index.js +0 -11
  61. package/src/commands/build.js +0 -638
  62. package/src/generators/aclGenerator.js +0 -394
  63. package/src/generators/modelGenerator.js +0 -174
  64. package/src/generators/relationshipsGenerator.js +0 -200
  65. package/src/generators/routeGenerator.js +0 -119
  66. package/src/parsers/datasourceParser.js +0 -121
  67. package/src/parsers/deepSQLAnalyzer.js +0 -554
  68. package/src/parsers/enhancedRLSConverter.js +0 -181
  69. package/src/parsers/functionAnalyzer.js +0 -302
  70. package/src/parsers/prismaFilterBuilder.js +0 -422
  71. package/src/parsers/prismaParser.js +0 -287
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildModels = buildModels;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const child_process_1 = require("child_process");
40
+ const prismaParser_1 = require("../parsers/prismaParser");
41
+ const datasourceParser_1 = require("../parsers/datasourceParser");
42
+ const modelGenerator_1 = require("../generators/modelGenerator");
43
+ const routeGenerator_1 = require("../generators/routeGenerator");
44
+ const aclGenerator_1 = require("../generators/aclGenerator");
45
+ /**
46
+ * Update acl.ts for a specific model
47
+ */
48
+ async function updateACLForModel(filteredModels, allModels, aclPath, datasource, userTable, debug = false) {
49
+ // Generate ACL for the filtered model (but pass all models for user table detection)
50
+ const tempPath = aclPath + '.tmp';
51
+ await (0, aclGenerator_1.generateACL)(filteredModels, tempPath, datasource.url, datasource.isPostgreSQL, userTable, {}, debug, allModels);
52
+ // Read the generated ACL for the specific model
53
+ const tempContent = fs.readFileSync(tempPath, 'utf8');
54
+ fs.unlinkSync(tempPath);
55
+ // Extract the model's ACL configuration
56
+ const modelName = Object.keys(filteredModels)[0];
57
+ // Find the start of the model definition
58
+ const modelStart = tempContent.indexOf(`${modelName}:`);
59
+ if (modelStart === -1) {
60
+ throw new Error(`Could not find model ${modelName} in generated RLS`);
61
+ }
62
+ // Find the matching closing brace by counting braces
63
+ let braceCount = 0;
64
+ let inString = false;
65
+ let stringChar = null;
66
+ let i = tempContent.indexOf('{', modelStart);
67
+ for (; i < tempContent.length; i++) {
68
+ const char = tempContent[i];
69
+ const prevChar = i > 0 ? tempContent[i - 1] : '';
70
+ // Handle string literals
71
+ if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
72
+ if (!inString) {
73
+ inString = true;
74
+ stringChar = char;
75
+ }
76
+ else if (char === stringChar) {
77
+ inString = false;
78
+ stringChar = null;
79
+ }
80
+ }
81
+ if (!inString) {
82
+ if (char === '{')
83
+ braceCount++;
84
+ if (char === '}')
85
+ braceCount--;
86
+ if (braceCount === 0) {
87
+ // Found the closing brace
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ if (braceCount !== 0) {
93
+ throw new Error(`Could not extract ACL for model ${modelName} - unmatched braces`);
94
+ }
95
+ const modelAcl = tempContent.substring(modelStart, i + 1);
96
+ // Read existing acl.ts
97
+ if (fs.existsSync(aclPath)) {
98
+ let existingContent = fs.readFileSync(aclPath, 'utf8');
99
+ // Check if model already exists in ACL
100
+ const existingModelPattern = new RegExp(`${modelName}:\\s*\\{[\\s\\S]*?\\n \\}(?=,|\\n)`);
101
+ if (existingModelPattern.test(existingContent)) {
102
+ // Replace existing model ACL
103
+ existingContent = existingContent.replace(existingModelPattern, modelAcl);
104
+ }
105
+ else {
106
+ // Add new model ACL before the closing of acl.model
107
+ existingContent = existingContent.replace(/(\n \})\n(\s*\},)/, `$1,\n ${modelAcl}\n$2`);
108
+ }
109
+ fs.writeFileSync(aclPath, existingContent);
110
+ console.log(`Updated ACL for model: ${modelName}`);
111
+ }
112
+ else {
113
+ // If acl.ts doesn't exist, create it with just this model
114
+ await (0, aclGenerator_1.generateACL)(filteredModels, aclPath, datasource.url, datasource.isPostgreSQL, userTable, {}, debug, allModels);
115
+ }
116
+ }
117
+ /**
118
+ * Build models from Prisma schema
119
+ */
120
+ async function buildModels(options) {
121
+ const schemaPath = path.resolve(process.cwd(), options.schema);
122
+ const outputBase = path.resolve(process.cwd(), options.output);
123
+ // If output is "/", use process.cwd() as the base
124
+ const baseDir = options.output === '/' ? process.cwd() : outputBase;
125
+ // Construct paths - TypeScript output structure
126
+ const srcDir = path.join(baseDir, 'src');
127
+ const modelDir = path.join(srcDir, 'models');
128
+ const configDir = path.join(srcDir, 'config');
129
+ const aclPath = path.join(configDir, 'acl.ts');
130
+ const routesDir = path.join(baseDir, 'routes', 'api', 'v1');
131
+ console.log('Building Rapidd models...');
132
+ console.log(`Schema: ${schemaPath}`);
133
+ console.log(`Output: ${baseDir}`);
134
+ // Check if schema file exists
135
+ if (!fs.existsSync(schemaPath)) {
136
+ throw new Error(`Prisma schema file not found at: ${schemaPath}`);
137
+ }
138
+ // Run npx prisma generate first
139
+ console.log('\nRunning npx prisma generate...');
140
+ try {
141
+ (0, child_process_1.execSync)(`npx prisma generate --schema=${schemaPath}`, {
142
+ stdio: 'inherit',
143
+ cwd: process.cwd()
144
+ });
145
+ console.log('Prisma client generated successfully\n');
146
+ }
147
+ catch (_error) {
148
+ console.warn('Warning: Failed to generate Prisma client');
149
+ console.warn('Continuing with schema parsing fallback...\n');
150
+ }
151
+ // Try to use Prisma DMMF first (using @prisma/internals getDMMF)
152
+ let parsedData = null;
153
+ try {
154
+ parsedData = await (0, prismaParser_1.parsePrismaDMMF)(schemaPath);
155
+ if (parsedData) {
156
+ console.log('Using Prisma DMMF (via @prisma/internals)');
157
+ }
158
+ }
159
+ catch (_error) {
160
+ // Fall back to schema parsing
161
+ }
162
+ // If DMMF parsing failed, parse schema file directly
163
+ if (!parsedData) {
164
+ console.log('Parsing Prisma schema file...');
165
+ parsedData = (0, prismaParser_1.parsePrismaSchema)(schemaPath);
166
+ }
167
+ const { models, enums } = parsedData;
168
+ // Filter models if --model option is provided
169
+ let filteredModels = models;
170
+ if (options.model) {
171
+ const modelName = options.model.toLowerCase();
172
+ const matchedModel = Object.keys(models).find(m => m.toLowerCase() === modelName);
173
+ if (!matchedModel) {
174
+ throw new Error(`Model "${options.model}" not found in schema. Available models: ${Object.keys(models).join(', ')}`);
175
+ }
176
+ filteredModels = { [matchedModel]: models[matchedModel] };
177
+ console.log(`Filtering to model: ${matchedModel}`);
178
+ }
179
+ console.log(`Found ${Object.keys(models).length} models${options.model ? ` (generating ${Object.keys(filteredModels).length})` : ''}`);
180
+ // Determine which components to generate
181
+ const shouldGenerate = {
182
+ model: !options.only || options.only === 'model',
183
+ route: !options.only || options.only === 'route',
184
+ acl: !options.only || options.only === 'acl'
185
+ };
186
+ // Validate --only option
187
+ if (options.only && !['model', 'route', 'acl'].includes(options.only)) {
188
+ throw new Error(`Invalid --only value "${options.only}". Must be one of: model, route, acl`);
189
+ }
190
+ // Generate model files
191
+ if (shouldGenerate.model) {
192
+ (0, modelGenerator_1.generateAllModels)(filteredModels, modelDir);
193
+ }
194
+ // Parse datasource to determine database type
195
+ let datasource = { isPostgreSQL: true, url: null, provider: null, isMySQL: false };
196
+ try {
197
+ datasource = (0, datasourceParser_1.parseDatasource)(schemaPath);
198
+ }
199
+ catch (error) {
200
+ // Only warn if it's not the expected "No url found" error in Prisma 7
201
+ if (!error.message.includes('No url found')) {
202
+ console.warn('Could not parse datasource, assuming PostgreSQL:', error.message);
203
+ }
204
+ }
205
+ // Generate ACL configuration
206
+ if (shouldGenerate.acl) {
207
+ console.log(`\nGenerating ACL configuration...`);
208
+ try {
209
+ // For non-PostgreSQL databases (MySQL, SQLite, etc.), generate permissive ACL
210
+ if (!datasource.isPostgreSQL) {
211
+ console.log(`${datasource.provider || 'Non-PostgreSQL'} database detected - generating permissive ACL...`);
212
+ await (0, aclGenerator_1.generateACL)(models, aclPath, null, false, options.userTable, {}, options.debug);
213
+ }
214
+ else if (options.model) {
215
+ // Update only specific model in acl.ts
216
+ await updateACLForModel(filteredModels, models, aclPath, datasource, options.userTable, options.debug);
217
+ }
218
+ else {
219
+ // Generate ACL for all models
220
+ await (0, aclGenerator_1.generateACL)(models, aclPath, datasource.url, datasource.isPostgreSQL, options.userTable, {}, options.debug);
221
+ }
222
+ }
223
+ catch (error) {
224
+ console.error('Failed to generate ACL:', error.message);
225
+ console.log('Generating permissive ACL fallback...');
226
+ // Pass null for URL and false for isPostgreSQL to skip database connection
227
+ await (0, aclGenerator_1.generateACL)(models, aclPath, null, false, options.userTable, {}, options.debug);
228
+ }
229
+ }
230
+ // Generate routes
231
+ if (shouldGenerate.route) {
232
+ (0, routeGenerator_1.generateAllRoutes)(filteredModels, routesDir);
233
+ }
234
+ return { models, enums };
235
+ }
236
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ModelInfo, RelationshipInfo } from '../parsers/prismaFilterBuilder';
2
+ /**
3
+ * Generate complete acl.ts file (TypeScript)
4
+ */
5
+ export declare function generateACL(models: Record<string, ModelInfo>, outputPath: string, databaseUrl: string | null, isPostgreSQL: boolean, userTableOption?: string, relationships?: Record<string, Record<string, RelationshipInfo>>, debug?: boolean, allModels?: Record<string, ModelInfo>): Promise<void>;
6
+ //# sourceMappingURL=aclGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aclGenerator.d.ts","sourceRoot":"","sources":["../../../src/generators/aclGenerator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AA+UlF;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,YAAY,EAAE,OAAO,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAM,EACpE,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAuFf"}
@@ -0,0 +1,384 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateACL = generateACL;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const pg_1 = require("pg");
40
+ const enhancedRLSConverter_1 = require("../parsers/enhancedRLSConverter");
41
+ const functionAnalyzer_1 = require("../parsers/functionAnalyzer");
42
+ /**
43
+ * Auto-detect user table name (case-insensitive search for user/users)
44
+ */
45
+ function detectUserTable(models, userTableOption) {
46
+ if (userTableOption) {
47
+ return userTableOption;
48
+ }
49
+ const modelNames = Object.keys(models);
50
+ const userTables = modelNames.filter(name => name.toLowerCase() === 'user' || name.toLowerCase() === 'users');
51
+ if (userTables.length === 0) {
52
+ throw new Error('No user table found (user/users). Please specify --user-table option.');
53
+ }
54
+ if (userTables.length > 1) {
55
+ throw new Error(`Multiple user tables found: ${userTables.join(', ')}. Please specify --user-table option.`);
56
+ }
57
+ return userTables[0];
58
+ }
59
+ /**
60
+ * Extract ACL policies from PostgreSQL RLS
61
+ */
62
+ async function extractPostgreSQLPolicies(databaseUrl, models) {
63
+ const client = new pg_1.Client({ connectionString: databaseUrl });
64
+ try {
65
+ await client.connect();
66
+ const policies = {};
67
+ // Create mapping from database table name to model name
68
+ const tableToModelMap = {};
69
+ for (const [modelName, modelData] of Object.entries(models)) {
70
+ const dbName = modelData.dbName || modelName.toLowerCase();
71
+ tableToModelMap[dbName] = modelName;
72
+ policies[modelName] = [];
73
+ }
74
+ // Query all policies from PostgreSQL RLS (pg_policies)
75
+ const result = await client.query(`
76
+ SELECT
77
+ tablename,
78
+ policyname,
79
+ permissive,
80
+ roles,
81
+ cmd,
82
+ qual,
83
+ with_check
84
+ FROM pg_policies
85
+ WHERE schemaname = 'public'
86
+ ORDER BY tablename, policyname
87
+ `);
88
+ // Group policies by model (using table to model mapping)
89
+ for (const row of result.rows) {
90
+ const tableName = row.tablename;
91
+ const modelName = tableToModelMap[tableName];
92
+ if (modelName && policies[modelName] !== undefined) {
93
+ policies[modelName].push({
94
+ name: row.policyname,
95
+ permissive: row.permissive === 'PERMISSIVE',
96
+ roles: row.roles,
97
+ command: row.cmd,
98
+ using: row.qual,
99
+ withCheck: row.with_check
100
+ });
101
+ }
102
+ }
103
+ await client.end();
104
+ return policies;
105
+ }
106
+ catch (error) {
107
+ try {
108
+ await client.end();
109
+ }
110
+ catch (_e) {
111
+ // ignore
112
+ }
113
+ throw error;
114
+ }
115
+ }
116
+ /**
117
+ * Generate ACL functions for a single model from PostgreSQL policies
118
+ */
119
+ function generateModelACL(modelName, policies, converter) {
120
+ const hasPolicies = policies && policies.length > 0;
121
+ if (!hasPolicies) {
122
+ // No policies - generate permissive access
123
+ return ` ${modelName}: {
124
+ canCreate(_user: RapiddUser): boolean {
125
+ return true;
126
+ },
127
+ getAccessFilter(_user: RapiddUser): Record<string, unknown> | boolean {
128
+ return {};
129
+ },
130
+ getUpdateFilter(_user: RapiddUser): Record<string, unknown> | boolean | false {
131
+ return {};
132
+ },
133
+ getDeleteFilter(_user: RapiddUser): Record<string, unknown> | boolean | false {
134
+ return {};
135
+ },
136
+ getOmitFields(_user: RapiddUser): string[] {
137
+ return [];
138
+ },
139
+ }`;
140
+ }
141
+ // Find policies by command type
142
+ const selectPolicies = policies.filter(p => p.command === 'SELECT' || p.command === 'ALL');
143
+ const insertPolicies = policies.filter(p => p.command === 'INSERT' || p.command === 'ALL');
144
+ const updatePolicies = policies.filter(p => p.command === 'UPDATE' || p.command === 'ALL');
145
+ const deletePolicies = policies.filter(p => p.command === 'DELETE' || p.command === 'ALL');
146
+ // Generate each function
147
+ const canCreateCode = generateFunction(insertPolicies, 'withCheck', converter, modelName);
148
+ const accessFilterCode = generateFilter(selectPolicies, 'using', converter, modelName);
149
+ let updateFilterCode = generateFilter(updatePolicies, 'using', converter, modelName);
150
+ let deleteFilterCode = generateFilter(deletePolicies, 'using', converter, modelName);
151
+ // If update/delete filters are empty/false but access filter is not, copy access filter
152
+ if ((updateFilterCode === 'return false;' || updateFilterCode === 'return {};') &&
153
+ accessFilterCode !== 'return false;' && accessFilterCode !== 'return {};') {
154
+ updateFilterCode = accessFilterCode;
155
+ }
156
+ if ((deleteFilterCode === 'return false;' || deleteFilterCode === 'return {};') &&
157
+ accessFilterCode !== 'return false;' && accessFilterCode !== 'return {};') {
158
+ deleteFilterCode = accessFilterCode;
159
+ }
160
+ return ` ${modelName}: {
161
+ canCreate(user: RapiddUser): boolean {
162
+ ${canCreateCode}
163
+ },
164
+ getAccessFilter(user: RapiddUser): Record<string, unknown> | boolean {
165
+ ${accessFilterCode}
166
+ },
167
+ getUpdateFilter(user: RapiddUser): Record<string, unknown> | boolean | false {
168
+ ${updateFilterCode}
169
+ },
170
+ getDeleteFilter(user: RapiddUser): Record<string, unknown> | boolean | false {
171
+ ${deleteFilterCode}
172
+ },
173
+ getOmitFields(_user: RapiddUser): string[] {
174
+ return [];
175
+ },
176
+ }`;
177
+ }
178
+ /**
179
+ * Generate JavaScript function from policies
180
+ */
181
+ function generateFunction(policies, expressionField, converter, modelName) {
182
+ if (policies.length === 0) {
183
+ return 'return true;';
184
+ }
185
+ const conditions = [];
186
+ for (const policy of policies) {
187
+ const expr = expressionField === 'withCheck'
188
+ ? (policy.withCheck || policy.using)
189
+ : policy[expressionField];
190
+ if (expr) {
191
+ try {
192
+ const jsExpr = converter.convertToJavaScript(expr, 'data', 'user', modelName);
193
+ console.log(` Policy '${policy.name}': ${expr.substring(0, 50)}... -> ${jsExpr.substring(0, 80)}`);
194
+ conditions.push(jsExpr);
195
+ }
196
+ catch (e) {
197
+ console.warn(` Failed to convert policy '${policy.name}' for ${modelName}: ${e.message}`);
198
+ console.warn(` SQL: ${expr}`);
199
+ conditions.push(`true /* TODO: Manual conversion needed for policy '${policy.name}' */`);
200
+ }
201
+ }
202
+ }
203
+ if (conditions.length === 0) {
204
+ return 'return true;';
205
+ }
206
+ // If any condition is 'true', the entire expression is true
207
+ if (conditions.some(c => c === 'true' || c.startsWith('true /*'))) {
208
+ return 'return true;';
209
+ }
210
+ // Policies are OR'd together (any policy allows)
211
+ return `return ${conditions.join(' || ')};`;
212
+ }
213
+ /**
214
+ * Generate Prisma filter function
215
+ */
216
+ function generateFilter(policies, expressionField, converter, modelName) {
217
+ if (policies.length === 0) {
218
+ return 'return false;';
219
+ }
220
+ const filtersWithRoles = [];
221
+ for (const policy of policies) {
222
+ const expr = policy[expressionField];
223
+ if (expr) {
224
+ try {
225
+ const prismaFilter = converter.convertToPrismaFilter(expr, 'user', modelName);
226
+ const analysis = converter.analyzer ? converter.analyzer.analyzeSQLForFilters(expr) : null;
227
+ // Track role conditions and data filters separately
228
+ const roleConditions = analysis?.conditions?.filter(c => c.type === 'role_any' || c.type === 'role_equal') || [];
229
+ filtersWithRoles.push({
230
+ filter: prismaFilter,
231
+ roleConditions,
232
+ hasDataFilter: prismaFilter !== '{}'
233
+ });
234
+ }
235
+ catch (e) {
236
+ console.warn(` Failed to convert filter policy '${policy.name}' for ${modelName}: ${e.message}`);
237
+ console.warn(` SQL: ${expr}`);
238
+ // On error, skip filter (fail-safe - no access)
239
+ }
240
+ }
241
+ }
242
+ if (filtersWithRoles.length === 0) {
243
+ return 'return false;';
244
+ }
245
+ // Build conditional filter logic
246
+ return buildConditionalFilter(filtersWithRoles);
247
+ }
248
+ /**
249
+ * Build conditional filter with role checks
250
+ */
251
+ function buildConditionalFilter(filtersWithRoles) {
252
+ const roleOnlyFilters = [];
253
+ const dataFilters = [];
254
+ for (const item of filtersWithRoles) {
255
+ if (item.roleConditions.length > 0 && !item.hasDataFilter) {
256
+ // Pure role check - return {} if role matches
257
+ roleOnlyFilters.push(...item.roleConditions);
258
+ }
259
+ else if (item.roleConditions.length > 0 && item.hasDataFilter) {
260
+ // Has both role and data filter - already handled with if statement
261
+ if (item.filter.includes('if (')) {
262
+ return item.filter;
263
+ }
264
+ dataFilters.push(item.filter);
265
+ }
266
+ else if (item.hasDataFilter) {
267
+ // Data filter only
268
+ dataFilters.push(item.filter);
269
+ }
270
+ }
271
+ // Generate conditional code
272
+ const conditions = [];
273
+ // Collect all roles that grant full access
274
+ const rolesWithFullAccess = new Set();
275
+ for (const roleCond of roleOnlyFilters) {
276
+ if (roleCond.type === 'role_any' && roleCond.roles) {
277
+ roleCond.roles.forEach(r => rolesWithFullAccess.add(r));
278
+ }
279
+ else if (roleCond.type === 'role_equal' && roleCond.role) {
280
+ rolesWithFullAccess.add(roleCond.role);
281
+ }
282
+ }
283
+ // Add single consolidated role check if needed
284
+ if (rolesWithFullAccess.size > 0) {
285
+ const roleArray = Array.from(rolesWithFullAccess);
286
+ if (roleArray.length === 1) {
287
+ conditions.push(`if (user?.role === '${roleArray[0]}') return {};`);
288
+ }
289
+ else {
290
+ conditions.push(`if ([${roleArray.map(r => `'${r}'`).join(', ')}].includes(user?.role)) return {};`);
291
+ }
292
+ }
293
+ // Deduplicate data filters
294
+ const uniqueDataFilters = [...new Set(dataFilters)];
295
+ // Add final return with data filters
296
+ if (uniqueDataFilters.length === 0) {
297
+ conditions.push('return false;');
298
+ }
299
+ else if (uniqueDataFilters.length === 1) {
300
+ conditions.push(`return ${uniqueDataFilters[0]};`);
301
+ }
302
+ else {
303
+ conditions.push(`return { OR: [${uniqueDataFilters.join(', ')}] };`);
304
+ }
305
+ return conditions.join(' ');
306
+ }
307
+ /**
308
+ * Generate complete acl.ts file (TypeScript)
309
+ */
310
+ async function generateACL(models, outputPath, databaseUrl, isPostgreSQL, userTableOption, relationships = {}, debug = false, allModels) {
311
+ // Use allModels for user table detection if provided (when filtering by model)
312
+ const modelsForUserDetection = allModels || models;
313
+ const _userTable = detectUserTable(modelsForUserDetection, userTableOption);
314
+ const modelNames = Object.keys(models);
315
+ let policies = {};
316
+ // Create enhanced converter with analyzed functions, models, and relationships
317
+ let converter = (0, enhancedRLSConverter_1.createEnhancedConverter)({}, {}, models, relationships);
318
+ if (isPostgreSQL && databaseUrl) {
319
+ console.log('PostgreSQL detected - analyzing database...');
320
+ // Step 1: Analyze functions
321
+ try {
322
+ const functionAnalysis = await (0, functionAnalyzer_1.analyzeFunctions)(databaseUrl);
323
+ console.log(`Analyzed ${Object.keys(functionAnalysis.functionMappings).length} PostgreSQL functions`);
324
+ // Create enhanced converter with analyzed mappings, models, and relationships
325
+ converter = (0, enhancedRLSConverter_1.createEnhancedConverter)(functionAnalysis.functionMappings, functionAnalysis.sessionVariables, models, relationships);
326
+ // Save function analysis for debugging (only if --debug flag is set)
327
+ if (debug) {
328
+ const configPath = path.join(path.dirname(outputPath), 'acl-mappings.json');
329
+ const mappingConfig = (0, functionAnalyzer_1.generateMappingConfig)(functionAnalysis);
330
+ fs.writeFileSync(configPath, JSON.stringify(mappingConfig, null, 2));
331
+ console.log(`Function mappings saved to ${configPath}`);
332
+ }
333
+ }
334
+ catch (error) {
335
+ console.warn(`Could not analyze functions: ${error.message}`);
336
+ }
337
+ // Step 2: Extract policies
338
+ try {
339
+ policies = await extractPostgreSQLPolicies(databaseUrl, models);
340
+ const totalPolicies = Object.values(policies).reduce((sum, p) => sum + p.length, 0);
341
+ console.log(`Extracted ${totalPolicies} policies from PostgreSQL RLS`);
342
+ }
343
+ catch (error) {
344
+ console.warn(`Failed to extract PostgreSQL policies: ${error.message}`);
345
+ console.log('Generating permissive ACL for all models...');
346
+ for (const modelName of modelNames) {
347
+ policies[modelName] = [];
348
+ }
349
+ }
350
+ }
351
+ else {
352
+ if (!isPostgreSQL) {
353
+ console.log('Non-PostgreSQL database detected - generating permissive ACL');
354
+ }
355
+ console.log('Generating permissive ACL for all models...');
356
+ for (const modelName of modelNames) {
357
+ policies[modelName] = [];
358
+ }
359
+ }
360
+ // Generate ACL TypeScript code
361
+ let aclCode = `import type { AclConfig, RapiddUser } from '../types';
362
+
363
+ const acl: AclConfig = {
364
+ model: {
365
+ `;
366
+ const modelACLCode = modelNames.map(modelName => {
367
+ return generateModelACL(modelName, policies[modelName], converter);
368
+ });
369
+ aclCode += modelACLCode.join(',\n');
370
+ aclCode += `
371
+ },
372
+ };
373
+
374
+ export default acl;
375
+ `;
376
+ // Ensure output directory exists
377
+ const outputDir = path.dirname(outputPath);
378
+ if (!fs.existsSync(outputDir)) {
379
+ fs.mkdirSync(outputDir, { recursive: true });
380
+ }
381
+ fs.writeFileSync(outputPath, aclCode);
382
+ console.log('Generated acl.ts with dynamic function mappings');
383
+ }
384
+ //# sourceMappingURL=aclGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aclGenerator.js","sourceRoot":"","sources":["../../../src/generators/aclGenerator.ts"],"names":[],"mappings":"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"}