suparisma 1.0.0 â 1.0.2
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 +4 -2
- package/dist/generators/coreGenerator.js +204 -42
- package/dist/generators/supabaseClientGenerator.js +0 -3
- package/dist/generators/typeGenerator.js +42 -16
- package/dist/index.js +111 -116
- package/dist/parser.js +10 -8
- package/package.json +1 -1
- package/prisma/schema.prisma +4 -2
- package/generated/hooks/useSuparismaAuditLog.ts +0 -80
- package/generated/hooks/useSuparismaThing.ts +0 -82
- package/generated/index.ts +0 -55
- package/generated/types/AuditLogTypes.ts +0 -391
- package/generated/types/ThingTypes.ts +0 -394
- package/generated/utils/core.ts +0 -1490
- package/generated/utils/supabase-client.ts +0 -10
package/dist/index.js
CHANGED
|
@@ -90,32 +90,41 @@ function analyzePrismaSchema(schemaPath) {
|
|
|
90
90
|
try {
|
|
91
91
|
const schemaContent = fs_1.default.readFileSync(schemaPath, 'utf8');
|
|
92
92
|
const modelInfos = [];
|
|
93
|
-
// Regular expression to match model definitions with comments
|
|
94
93
|
const modelRegex = /(?:\/\/\s*@disableRealtime\s*)?\s*model\s+(\w+)\s*{([\s\S]*?)}/g;
|
|
95
94
|
let modelMatch;
|
|
96
95
|
while ((modelMatch = modelRegex.exec(schemaContent)) !== null) {
|
|
97
96
|
const modelName = modelMatch[1];
|
|
98
|
-
const
|
|
97
|
+
const modelBodyWithComments = modelMatch[0]; // Includes the model keyword and its comments
|
|
98
|
+
const modelBody = modelMatch[2]; // Just the content within {}
|
|
99
99
|
if (!modelName || !modelBody) {
|
|
100
100
|
console.error('Model name or body not found');
|
|
101
101
|
continue;
|
|
102
102
|
}
|
|
103
|
-
const tableName =
|
|
104
|
-
?
|
|
103
|
+
const tableName = modelBodyWithComments.includes('@map')
|
|
104
|
+
? modelBodyWithComments.match(/@map\s*\(\s*["'](.+?)["']\s*\)/)?.at(1) || modelName
|
|
105
105
|
: modelName;
|
|
106
|
-
|
|
107
|
-
// Default is to enable realtime unless explicitly disabled
|
|
108
|
-
const enableRealtime = !modelMatch[0].includes('// @disableRealtime');
|
|
109
|
-
// Find fields with @enableSearch comment
|
|
106
|
+
const enableRealtime = !modelBodyWithComments.includes('// @disableRealtime');
|
|
110
107
|
const searchFields = [];
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
// Split model body into lines to check preceding line for @enableSearch
|
|
109
|
+
const bodyLines = modelBody.trim().split('\n');
|
|
110
|
+
for (let i = 0; i < bodyLines.length; i++) {
|
|
111
|
+
const currentLine = bodyLines[i].trim();
|
|
112
|
+
const previousLine = i > 0 ? bodyLines[i - 1].trim() : "";
|
|
113
|
+
// Check if the PREVIOUS line contains the @enableSearch comment
|
|
114
|
+
if (previousLine.includes('// @enableSearch')) {
|
|
115
|
+
// Try to parse the CURRENT line as a field definition
|
|
116
|
+
// Basic regex: fieldName fieldType (optional attributes/comments)
|
|
117
|
+
const fieldMatch = currentLine.match(/^(\w+)\s+(\w+)/);
|
|
118
|
+
if (fieldMatch) {
|
|
119
|
+
const fieldName = fieldMatch[1];
|
|
120
|
+
const fieldType = fieldMatch[2];
|
|
121
|
+
if (fieldName && fieldType) {
|
|
122
|
+
searchFields.push({
|
|
123
|
+
name: fieldName,
|
|
124
|
+
type: fieldType,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
119
128
|
}
|
|
120
129
|
}
|
|
121
130
|
modelInfos.push({
|
|
@@ -150,123 +159,109 @@ async function configurePrismaTablesForSuparisma(schemaPath) {
|
|
|
150
159
|
}
|
|
151
160
|
// Analyze Prisma schema for models, realtime and search annotations
|
|
152
161
|
const modelInfos = analyzePrismaSchema(schemaPath);
|
|
153
|
-
// Dynamically import pg package
|
|
154
162
|
const pg = await Promise.resolve().then(() => __importStar(require('pg')));
|
|
155
163
|
const { Pool } = pg.default || pg;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// Get all tables from database directly
|
|
160
|
-
const { rows: allTables } = await pool.query(`
|
|
161
|
-
SELECT table_name
|
|
162
|
-
FROM information_schema.tables
|
|
163
|
-
WHERE table_schema = 'public'
|
|
164
|
-
`);
|
|
165
|
-
console.log(`đ Found ${allTables.length} tables in the 'public' schema`);
|
|
166
|
-
allTables.forEach((t) => console.log(` - ${t.table_name}`));
|
|
167
|
-
// DIRECT APPROACH: Hardcode SQL for each known Prisma model type
|
|
164
|
+
const pool = new Pool({ connectionString: process.env.DIRECT_URL });
|
|
165
|
+
console.log('đ Connected to PostgreSQL database for configuration.');
|
|
166
|
+
const { rows: allTables } = await pool.query(`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'`);
|
|
168
167
|
for (const model of modelInfos) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
const matchingTable = allTables.find((t) => t.table_name.toLowerCase() === model.tableName.toLowerCase());
|
|
169
|
+
if (!matchingTable) {
|
|
170
|
+
console.warn(`đ Skipping model ${model.name}: Corresponding table ${model.tableName} not found in database.`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const actualTableName = matchingTable.table_name;
|
|
174
|
+
console.log(`Processing model ${model.name} (table: "${actualTableName}")`);
|
|
175
|
+
// Realtime setup (existing logic)
|
|
176
|
+
if (model.enableRealtime) {
|
|
177
|
+
const alterPublicationQuery = `ALTER PUBLICATION supabase_realtime ADD TABLE "${actualTableName}";`;
|
|
178
|
+
try {
|
|
179
|
+
await pool.query(alterPublicationQuery);
|
|
180
|
+
console.log(` â
Added "${actualTableName}" to supabase_realtime publication for real-time updates.`);
|
|
175
181
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
console.log(`âšī¸ Model ${model.name}: enableRealtime is ${model.enableRealtime}`);
|
|
180
|
-
if (model.enableRealtime) {
|
|
181
|
-
// Explicitly use double quotes for mixed case identifiers
|
|
182
|
-
// try {
|
|
183
|
-
// await pool.query(`ALTER TABLE "${actualTableName}" REPLICA IDENTITY FULL;`);
|
|
184
|
-
// console.log(`â
Set REPLICA IDENTITY FULL on "${actualTableName}"`);
|
|
185
|
-
// } catch (err: any ) {
|
|
186
|
-
// console.error(`â Failed to set REPLICA IDENTITY on "${actualTableName}": ${err.message}`);
|
|
187
|
-
// }
|
|
188
|
-
// Directly add the table to Supabase Realtime publication
|
|
189
|
-
const alterPublicationQuery = `ALTER PUBLICATION supabase_realtime ADD TABLE "${actualTableName}";`;
|
|
190
|
-
console.log(`âšī¸ Executing SQL: ${alterPublicationQuery}`);
|
|
191
|
-
try {
|
|
192
|
-
await pool.query(alterPublicationQuery);
|
|
193
|
-
console.log(`â
Added "${actualTableName}" to supabase_realtime publication`);
|
|
182
|
+
catch (err) {
|
|
183
|
+
if (err.message.includes('already member')) {
|
|
184
|
+
console.log(` âšī¸ Table "${actualTableName}" was already in supabase_realtime publication.`);
|
|
194
185
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (err.message.includes('already member')) {
|
|
198
|
-
console.log(`âšī¸ Table "${actualTableName}" was already in supabase_realtime publication`);
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
console.error(`â Failed to add "${actualTableName}" to supabase_realtime. Full error:`, err);
|
|
202
|
-
}
|
|
186
|
+
else {
|
|
187
|
+
console.error(` â Failed to add "${actualTableName}" to supabase_realtime: ${err.message}`);
|
|
203
188
|
}
|
|
204
189
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log(` âšī¸ Realtime disabled for model ${model.name}.`);
|
|
193
|
+
}
|
|
194
|
+
// Search setup
|
|
195
|
+
if (model.searchFields.length > 0) {
|
|
196
|
+
console.log(` đ Setting up full-text search for model ${model.name}:`);
|
|
197
|
+
const { rows: columns } = await pool.query(`SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1`, [actualTableName]);
|
|
198
|
+
for (const searchField of model.searchFields) {
|
|
199
|
+
const matchingColumn = columns.find((c) => c.column_name.toLowerCase() === searchField.name.toLowerCase());
|
|
200
|
+
if (!matchingColumn) {
|
|
201
|
+
console.warn(` đ Skipping search for field ${searchField.name}: Column not found in table "${actualTableName}".`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const actualColumnName = matchingColumn.column_name;
|
|
205
|
+
const functionName = `search_${actualTableName.toLowerCase()}_by_${actualColumnName.toLowerCase()}_prefix`;
|
|
206
|
+
const indexName = `idx_gin_search_${actualTableName.toLowerCase()}_${actualColumnName.toLowerCase()}`;
|
|
207
|
+
console.log(` âĄī¸ Configuring field "${actualColumnName}":`);
|
|
208
|
+
try {
|
|
209
|
+
// Create search function
|
|
210
|
+
const createFunctionQuery = `
|
|
211
|
+
CREATE OR REPLACE FUNCTION "public"."${functionName}"(search_prefix text)
|
|
212
|
+
RETURNS SETOF "public"."${actualTableName}" AS $$
|
|
213
|
+
BEGIN
|
|
214
|
+
RETURN QUERY
|
|
215
|
+
SELECT * FROM "public"."${actualTableName}"
|
|
216
|
+
WHERE to_tsvector('english', "${actualColumnName}") @@ to_tsquery('english', search_prefix || ':*');
|
|
217
|
+
END;
|
|
218
|
+
$$ LANGUAGE plpgsql STABLE;`; // Added STABLE for potential performance benefits
|
|
219
|
+
await pool.query(createFunctionQuery);
|
|
220
|
+
console.log(` â
Created/Replaced RPC function: "${functionName}"(search_prefix text)`);
|
|
221
|
+
// Create GIN index
|
|
222
|
+
const createIndexQuery = `
|
|
223
|
+
DO $$
|
|
224
|
+
BEGIN
|
|
225
|
+
IF NOT EXISTS (
|
|
226
|
+
SELECT 1 FROM pg_indexes
|
|
227
|
+
WHERE schemaname = 'public'
|
|
228
|
+
AND tablename = '${actualTableName}'
|
|
229
|
+
AND indexname = '${indexName}'
|
|
230
|
+
) THEN
|
|
231
|
+
CREATE INDEX "${indexName}" ON "public"."${actualTableName}" USING GIN (to_tsvector('english', "${actualColumnName}"));
|
|
232
|
+
RAISE NOTICE ' â
Created GIN index: "${indexName}" on "${actualTableName}"("${actualColumnName}")';
|
|
233
|
+
ELSE
|
|
234
|
+
RAISE NOTICE ' âšī¸ GIN index "${indexName}" on "${actualTableName}"("${actualColumnName}") already exists.';
|
|
235
|
+
END IF;
|
|
236
|
+
END;
|
|
237
|
+
$$;`;
|
|
238
|
+
const indexResult = await pool.query(createIndexQuery);
|
|
239
|
+
// Output notices from the DO $$ block (PostgreSQL specific)
|
|
240
|
+
if (indexResult.rows.length > 0 && indexResult.rows[0].notice) {
|
|
241
|
+
console.log(indexResult.rows[0].notice.replace(/^NOTICE: /, ''));
|
|
253
242
|
}
|
|
254
|
-
|
|
255
|
-
|
|
243
|
+
else if (!indexResult.rows.find((r) => r.notice?.includes('Created GIN index'))) {
|
|
244
|
+
// If DO $$ block doesn't emit specific notice for creation and it didn't say exists.
|
|
245
|
+
// This is a fallback log, actual creation/existence is handled by the DO block.
|
|
246
|
+
// The important part is that the index will be there.
|
|
256
247
|
}
|
|
257
248
|
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
console.error(` â Failed to set up search for "${actualTableName}"."${actualColumnName}": ${err.message}`);
|
|
251
|
+
}
|
|
258
252
|
}
|
|
259
253
|
}
|
|
260
|
-
|
|
261
|
-
console.
|
|
254
|
+
else {
|
|
255
|
+
console.log(` âšī¸ No fields marked with // @enableSearch for model ${model.name}.`);
|
|
262
256
|
}
|
|
257
|
+
console.log('---------------------------------------------------');
|
|
263
258
|
}
|
|
264
259
|
await pool.end();
|
|
265
|
-
console.log('đ Database configuration complete');
|
|
260
|
+
console.log('đ Database configuration complete.');
|
|
266
261
|
}
|
|
267
262
|
catch (err) {
|
|
268
|
-
console.error('â Error
|
|
269
|
-
console.log('â ī¸
|
|
263
|
+
console.error('â Error during database configuration:', err);
|
|
264
|
+
console.log('â ī¸ Hook generation will continue, but database features like search or realtime might not be fully configured.');
|
|
270
265
|
}
|
|
271
266
|
}
|
|
272
267
|
/**
|
package/dist/parser.js
CHANGED
|
@@ -44,15 +44,16 @@ function parsePrismaSchema(schemaPath) {
|
|
|
44
44
|
if (line.startsWith('//')) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
// Parse field definition
|
|
48
|
-
const fieldMatch = line.match(/\s*(\w+)\s+(\w+)(\?)?\s*(?:@[^)]+)?/);
|
|
47
|
+
// Parse field definition - Updated to handle array types
|
|
48
|
+
const fieldMatch = line.match(/\s*(\w+)\s+(\w+)(\[\])?\??(\?)?\s*(?:@[^)]+)?/);
|
|
49
49
|
if (fieldMatch) {
|
|
50
50
|
const fieldName = fieldMatch[1];
|
|
51
|
-
const
|
|
52
|
-
const
|
|
51
|
+
const baseFieldType = fieldMatch[2]; // e.g., "String" from "String[]"
|
|
52
|
+
const isArray = !!fieldMatch[3]; // [] makes it an array
|
|
53
|
+
const isOptional = !!fieldMatch[4]; // ? makes it optional
|
|
53
54
|
// Store for potential standalone @enableSearch comment
|
|
54
55
|
lastFieldName = fieldName || '';
|
|
55
|
-
lastFieldType =
|
|
56
|
+
lastFieldType = baseFieldType || '';
|
|
56
57
|
// Detect special fields
|
|
57
58
|
const isId = line.includes('@id');
|
|
58
59
|
const isCreatedAt = fieldName === 'created_at' || fieldName === 'createdAt';
|
|
@@ -73,13 +74,13 @@ function parsePrismaSchema(schemaPath) {
|
|
|
73
74
|
if (line.includes('// @enableSearch')) {
|
|
74
75
|
searchFields.push({
|
|
75
76
|
name: fieldName || '',
|
|
76
|
-
type:
|
|
77
|
+
type: baseFieldType || '',
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
|
-
if (fieldName &&
|
|
80
|
+
if (fieldName && baseFieldType) {
|
|
80
81
|
fields.push({
|
|
81
82
|
name: fieldName,
|
|
82
|
-
type:
|
|
83
|
+
type: baseFieldType, // Store the base type (String, not String[])
|
|
83
84
|
isRequired: false,
|
|
84
85
|
isOptional,
|
|
85
86
|
isId,
|
|
@@ -89,6 +90,7 @@ function parsePrismaSchema(schemaPath) {
|
|
|
89
90
|
hasDefaultValue,
|
|
90
91
|
defaultValue, // Add the extracted default value
|
|
91
92
|
isRelation,
|
|
93
|
+
isList: isArray, // Add the isList property
|
|
92
94
|
});
|
|
93
95
|
}
|
|
94
96
|
}
|
package/package.json
CHANGED
package/prisma/schema.prisma
CHANGED
|
@@ -19,10 +19,12 @@ enum SomeEnum {
|
|
|
19
19
|
THREE
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
model Thing {
|
|
24
24
|
id String @id @default(uuid())
|
|
25
|
-
|
|
25
|
+
// @enableSearch
|
|
26
|
+
name String?
|
|
27
|
+
stringArray String[]
|
|
26
28
|
someEnum SomeEnum @default(ONE)
|
|
27
29
|
someNumber Int?
|
|
28
30
|
createdAt DateTime @default(now())
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
// THIS FILE IS AUTO-GENERATED - DO NOT EDIT DIRECTLY
|
|
2
|
-
// Edit the generator script instead: scripts/generate-realtime-hooks.ts
|
|
3
|
-
|
|
4
|
-
// Corrected import for core hook factory
|
|
5
|
-
import { createSuparismaHook } from '../utils/core';
|
|
6
|
-
import type {
|
|
7
|
-
AuditLogWithRelations,
|
|
8
|
-
AuditLogCreateInput,
|
|
9
|
-
AuditLogUpdateInput,
|
|
10
|
-
AuditLogWhereInput,
|
|
11
|
-
AuditLogWhereUniqueInput,
|
|
12
|
-
AuditLogOrderByInput,
|
|
13
|
-
AuditLogHookApi,
|
|
14
|
-
UseAuditLogOptions
|
|
15
|
-
} from '../types/AuditLogTypes';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A Prisma-like hook for interacting with AuditLog records with real-time capabilities.
|
|
19
|
-
*
|
|
20
|
-
* This hook provides CRUD operations, real-time updates, and search functionality.
|
|
21
|
-
*
|
|
22
|
-
* @param options - Optional configuration options for the hook
|
|
23
|
-
* @returns An object with data state and methods for interacting with AuditLog records
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* // Basic usage - get all AuditLog records with realtime updates
|
|
27
|
-
* const auditlog = useSuparismaAuditLog();
|
|
28
|
-
* const { data, loading, error } = auditlog;
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* // With filtering and ordering
|
|
32
|
-
* const auditlog = useSuparismaAuditLog({
|
|
33
|
-
* where: { active: true },
|
|
34
|
-
* orderBy: { createdAt: 'desc' }, // Note: Using actual Prisma field name
|
|
35
|
-
* limit: 10
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* // Create a new record
|
|
40
|
-
* const result = await auditlog.create({
|
|
41
|
-
* name: "Example Name",
|
|
42
|
-
* // other fields...
|
|
43
|
-
* });
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* // Update a record
|
|
47
|
-
* const result = await auditlog.update({
|
|
48
|
-
* where: { id: "123" },
|
|
49
|
-
* data: { name: "Updated Name" }
|
|
50
|
-
* });
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Delete a record
|
|
54
|
-
* const result = await auditlog.delete({ id: "123" });
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // Find records with specific criteria
|
|
58
|
-
* const result = await auditlog.findMany({
|
|
59
|
-
* where: { // filters },
|
|
60
|
-
* orderBy: { // ordering },
|
|
61
|
-
* take: 20 // limit
|
|
62
|
-
* });
|
|
63
|
-
*/
|
|
64
|
-
export const useSuparismaAuditLog = createSuparismaHook<
|
|
65
|
-
AuditLogWithRelations,
|
|
66
|
-
AuditLogWithRelations,
|
|
67
|
-
AuditLogCreateInput,
|
|
68
|
-
AuditLogUpdateInput,
|
|
69
|
-
AuditLogWhereInput,
|
|
70
|
-
AuditLogWhereUniqueInput,
|
|
71
|
-
AuditLogOrderByInput
|
|
72
|
-
>({
|
|
73
|
-
tableName: 'AuditLog',
|
|
74
|
-
hasCreatedAt: true,
|
|
75
|
-
hasUpdatedAt: false,
|
|
76
|
-
// Default values from schema
|
|
77
|
-
defaultValues: {"id":"uuid(","createdAt":"now("},
|
|
78
|
-
// Field name for createdAt from Prisma schema
|
|
79
|
-
createdAtField: "createdAt"
|
|
80
|
-
}) as unknown as (options?: UseAuditLogOptions) => AuditLogHookApi;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
// THIS FILE IS AUTO-GENERATED - DO NOT EDIT DIRECTLY
|
|
2
|
-
// Edit the generator script instead: scripts/generate-realtime-hooks.ts
|
|
3
|
-
|
|
4
|
-
// Corrected import for core hook factory
|
|
5
|
-
import { createSuparismaHook } from '../utils/core';
|
|
6
|
-
import type {
|
|
7
|
-
ThingWithRelations,
|
|
8
|
-
ThingCreateInput,
|
|
9
|
-
ThingUpdateInput,
|
|
10
|
-
ThingWhereInput,
|
|
11
|
-
ThingWhereUniqueInput,
|
|
12
|
-
ThingOrderByInput,
|
|
13
|
-
ThingHookApi,
|
|
14
|
-
UseThingOptions
|
|
15
|
-
} from '../types/ThingTypes';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A Prisma-like hook for interacting with Thing records with real-time capabilities.
|
|
19
|
-
*
|
|
20
|
-
* This hook provides CRUD operations, real-time updates, and search functionality.
|
|
21
|
-
*
|
|
22
|
-
* @param options - Optional configuration options for the hook
|
|
23
|
-
* @returns An object with data state and methods for interacting with Thing records
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* // Basic usage - get all Thing records with realtime updates
|
|
27
|
-
* const thing = useSuparismaThing();
|
|
28
|
-
* const { data, loading, error } = thing;
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* // With filtering and ordering
|
|
32
|
-
* const thing = useSuparismaThing({
|
|
33
|
-
* where: { active: true },
|
|
34
|
-
* orderBy: { createdAt: 'desc' }, // Note: Using actual Prisma field name
|
|
35
|
-
* limit: 10
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* // Create a new record
|
|
40
|
-
* const result = await thing.create({
|
|
41
|
-
* name: "Example Name",
|
|
42
|
-
* // other fields...
|
|
43
|
-
* });
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* // Update a record
|
|
47
|
-
* const result = await thing.update({
|
|
48
|
-
* where: { id: "123" },
|
|
49
|
-
* data: { name: "Updated Name" }
|
|
50
|
-
* });
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Delete a record
|
|
54
|
-
* const result = await thing.delete({ id: "123" });
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // Find records with specific criteria
|
|
58
|
-
* const result = await thing.findMany({
|
|
59
|
-
* where: { // filters },
|
|
60
|
-
* orderBy: { // ordering },
|
|
61
|
-
* take: 20 // limit
|
|
62
|
-
* });
|
|
63
|
-
*/
|
|
64
|
-
export const useSuparismaThing = createSuparismaHook<
|
|
65
|
-
ThingWithRelations,
|
|
66
|
-
ThingWithRelations,
|
|
67
|
-
ThingCreateInput,
|
|
68
|
-
ThingUpdateInput,
|
|
69
|
-
ThingWhereInput,
|
|
70
|
-
ThingWhereUniqueInput,
|
|
71
|
-
ThingOrderByInput
|
|
72
|
-
>({
|
|
73
|
-
tableName: 'Thing',
|
|
74
|
-
hasCreatedAt: true,
|
|
75
|
-
hasUpdatedAt: true,
|
|
76
|
-
// Default values from schema
|
|
77
|
-
defaultValues: {"id":"uuid(","someEnum":"ONE","createdAt":"now("},
|
|
78
|
-
// Field name for createdAt from Prisma schema
|
|
79
|
-
createdAtField: "createdAt",
|
|
80
|
-
// Field name for updatedAt from Prisma schema
|
|
81
|
-
updatedAtField: "updatedAt"
|
|
82
|
-
}) as unknown as (options?: UseThingOptions) => ThingHookApi;
|
package/generated/index.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// THIS FILE IS AUTO-GENERATED - DO NOT EDIT DIRECTLY
|
|
2
|
-
// Edit the generator script instead: scripts/generate-realtime-hooks.ts
|
|
3
|
-
|
|
4
|
-
import { useSuparismaThing } from './hooks/useSuparismaThing';
|
|
5
|
-
import { useSuparismaAuditLog } from './hooks/useSuparismaAuditLog';
|
|
6
|
-
import type { UseThingOptions, ThingHookApi } from './types/ThingTypes';
|
|
7
|
-
import type { UseAuditLogOptions, AuditLogHookApi } from './types/AuditLogTypes';
|
|
8
|
-
export type { SuparismaOptions, SearchQuery, SearchState, FilterOperators } from './utils/core';
|
|
9
|
-
export type { ThingWithRelations, ThingCreateInput, ThingUpdateInput, ThingWhereInput, ThingWhereUniqueInput, ThingOrderByInput, ThingHookApi, UseThingOptions } from './types/ThingTypes';
|
|
10
|
-
export type { AuditLogWithRelations, AuditLogCreateInput, AuditLogUpdateInput, AuditLogWhereInput, AuditLogWhereUniqueInput, AuditLogOrderByInput, AuditLogHookApi, UseAuditLogOptions } from './types/AuditLogTypes';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Interface for all Suparisma hooks with dot notation access.
|
|
14
|
-
* This provides IntelliSense for all available models.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* // Access hooks for different models
|
|
18
|
-
* const users = useSuparisma.user();
|
|
19
|
-
* const posts = useSuparisma.post();
|
|
20
|
-
*/
|
|
21
|
-
export interface SuparismaHooks {
|
|
22
|
-
thing: (options?: UseThingOptions) => ThingHookApi;
|
|
23
|
-
auditLog: (options?: UseAuditLogOptions) => AuditLogHookApi;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Main Suparisma hook object with dot notation access to all model hooks.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* // Get hooks for different models
|
|
31
|
-
* import useSuparisma from './your-output-dir'; // e.g., from './suparisma/generated'
|
|
32
|
-
*
|
|
33
|
-
* // Access user model with all hook methods
|
|
34
|
-
* const users = useSuparisma.user();
|
|
35
|
-
* const { data, loading, error } = users;
|
|
36
|
-
*
|
|
37
|
-
* // Create a new record
|
|
38
|
-
* await users.create({ name: "John" });
|
|
39
|
-
*
|
|
40
|
-
* // Delete a record
|
|
41
|
-
* await users.delete({ id: "123" });
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* // Use with filtering and options
|
|
45
|
-
* const admins = useSuparisma.user({
|
|
46
|
-
* where: { role: 'admin' },
|
|
47
|
-
* orderBy: { created_at: 'desc' }
|
|
48
|
-
* });
|
|
49
|
-
*/
|
|
50
|
-
const useSuparisma: SuparismaHooks = {
|
|
51
|
-
thing: useSuparismaThing,
|
|
52
|
-
auditLog: useSuparismaAuditLog,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export default useSuparisma;
|