omni-rest 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -720,10 +720,7 @@ function resolveOutputDir(frontendDir, framework, outFlag) {
720
720
  if (structure.usesSrc) {
721
721
  return path3__namespace.resolve(frontendDir, "src");
722
722
  }
723
- if (framework === "nextjs" && structure.usesAppRouter) {
724
- return path3__namespace.resolve(frontendDir, "app");
725
- }
726
- return path3__namespace.resolve(frontendDir, "src");
723
+ return frontendDir;
727
724
  }
728
725
  var BASE_PACKAGES = [
729
726
  "@tanstack/react-query",
@@ -1126,15 +1123,19 @@ function generateTableFile(config, modelConfig) {
1126
1123
  lines.push(`'use client'`);
1127
1124
  lines.push(``);
1128
1125
  }
1129
- lines.push(`import { DataTable } from "../data-table";`);
1130
- lines.push(`import { ${columnsVar} } from "./${Model}Columns";`);
1131
1126
  const hookImports = [useListHook, useDeleteHook];
1132
1127
  if (bulkDelete) {
1133
1128
  hookImports.push(useBulkDeleteHook);
1134
1129
  }
1135
- lines.push(`import { ${hookImports.join(", ")} } from "../hooks/use${Model}";`);
1130
+ lines.push(`import { useState } from "react";`);
1131
+ lines.push(`import DataTable from "../data-table";`);
1132
+ lines.push(`import { ${columnsVar} } from "./${Model}Columns";`);
1133
+ lines.push(`import { ${hookImports.join(", ")} } from "../../hooks/use${Model}";`);
1134
+ lines.push(`import { ${Model}Form } from "./${Model}Form";`);
1135
+ lines.push(`import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "../ui/dialog";`);
1136
1136
  lines.push(``);
1137
1137
  lines.push(`export function ${Model}Table() {`);
1138
+ lines.push(` const [isCreateOpen, setIsCreateOpen] = useState(false);`);
1138
1139
  lines.push(` const { data } = ${useListHook}();`);
1139
1140
  lines.push(` const ${varName}Delete = ${useDeleteHook}();`);
1140
1141
  if (bulkDelete) {
@@ -1142,22 +1143,40 @@ function generateTableFile(config, modelConfig) {
1142
1143
  }
1143
1144
  lines.push(``);
1144
1145
  lines.push(` return (`);
1146
+ lines.push(` <>`);
1145
1147
  const dtProps = [
1146
- ` columns={${columnsVar}}`,
1147
- ` data={data?.data ?? []}`,
1148
- ` onRowDelete={(row) => ${varName}Delete.mutate(row.id)}`
1148
+ ` title="${models}"`,
1149
+ ` description="Manage ${models.toLowerCase()} in your system"`,
1150
+ ` columns={${columnsVar}}`,
1151
+ ` data={data?.data ?? []}`,
1152
+ ` toggleAction={() => setIsCreateOpen(true)}`,
1153
+ ` actionText="Create ${Model}"`,
1154
+ ` onRowDelete={(row: any) => ${varName}Delete.mutate(row.id)}`
1149
1155
  ];
1150
1156
  if (bulkDelete) {
1151
- dtProps.push(` onMultiDelete={(rows) => ${varName}BulkDelete.mutate(rows.map((r) => r.id))}`);
1157
+ dtProps.push(` onMultiDelete={(rows: any[]) => ${varName}BulkDelete.mutate(rows.map((r) => r.id))}`);
1152
1158
  }
1153
1159
  if (canExport) {
1154
- dtProps.push(` canExport={true}`);
1160
+ dtProps.push(` canExport={true}`);
1155
1161
  }
1156
- lines.push(` <DataTable`);
1162
+ lines.push(` <DataTable`);
1157
1163
  for (const prop of dtProps) {
1158
1164
  lines.push(prop);
1159
1165
  }
1160
- lines.push(` />`);
1166
+ lines.push(` />`);
1167
+ lines.push(``);
1168
+ lines.push(` <Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>`);
1169
+ lines.push(` <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">`);
1170
+ lines.push(` <DialogHeader>`);
1171
+ lines.push(` <DialogTitle>Create New ${Model}</DialogTitle>`);
1172
+ lines.push(` <DialogDescription>`);
1173
+ lines.push(` Fill in the information below to create a new ${varName}.`);
1174
+ lines.push(` </DialogDescription>`);
1175
+ lines.push(` </DialogHeader>`);
1176
+ lines.push(` <${Model}Form onSuccess={() => setIsCreateOpen(false)} />`);
1177
+ lines.push(` </DialogContent>`);
1178
+ lines.push(` </Dialog>`);
1179
+ lines.push(` </>`);
1161
1180
  lines.push(` );`);
1162
1181
  lines.push(`}`);
1163
1182
  lines.push(``);
@@ -1186,17 +1205,17 @@ function generateFormFile(config, modelConfig) {
1186
1205
  }
1187
1206
  }
1188
1207
  lines.push(`import { FormGenerator } from "../form-generator";`);
1189
- lines.push(`import { ${name}Schema } from "src/schemas.generated";`);
1208
+ lines.push(`import { ${name}CreateSchema } from "../../schemas.generated";`);
1190
1209
  lines.push(
1191
- `import { useCreate${name}, useUpdate${name} } from "../hooks/use${name}";`
1210
+ `import { useCreate${name}, useUpdate${name} } from "../../hooks/use${name}";`
1192
1211
  );
1193
1212
  for (const { relatedModel } of relationalFieldMeta) {
1194
1213
  lines.push(
1195
- `import { use${relatedModel}s } from "../hooks/use${relatedModel}";`
1214
+ `import { use${relatedModel}s } from "../../hooks/use${relatedModel}";`
1196
1215
  );
1197
1216
  }
1198
1217
  lines.push(``);
1199
- lines.push(`export function ${name}Form({ id }: { id?: string }) {`);
1218
+ lines.push(`export function ${name}Form({ id, onSuccess }: { id?: string; onSuccess?: () => void }) {`);
1200
1219
  lines.push(` const create${name} = useCreate${name}();`);
1201
1220
  lines.push(` const update${name} = useUpdate${name}();`);
1202
1221
  for (const { fieldName, relatedModel } of relationalFieldMeta) {
@@ -1246,24 +1265,36 @@ function generateFormFile(config, modelConfig) {
1246
1265
  });
1247
1266
  lines.push(` ];`);
1248
1267
  lines.push(``);
1268
+ lines.push(` const handleSubmit = (data: any) => {`);
1269
+ lines.push(` const mutation = id ? update${name}.mutate({ id, data }) : create${name}.mutate(data);`);
1270
+ lines.push(` if (onSuccess) {`);
1271
+ lines.push(` // Call onSuccess after mutation completes`);
1272
+ lines.push(` Promise.resolve(mutation).then(() => onSuccess()).catch(() => {});`);
1273
+ lines.push(` }`);
1274
+ lines.push(` };`);
1275
+ lines.push(``);
1249
1276
  lines.push(` return (`);
1250
1277
  lines.push(` <FormGenerator`);
1251
1278
  lines.push(` fields={fields}`);
1252
- lines.push(` schema={${name}Schema}`);
1253
- lines.push(
1254
- ` onSubmit={(data) => id ? update${name}.mutate({ id, data }) : create${name}.mutate(data)}`
1255
- );
1279
+ lines.push(` schema={${name}CreateSchema}`);
1280
+ lines.push(` onSubmit={handleSubmit}`);
1256
1281
  lines.push(` steps={steps}`);
1257
1282
  lines.push(` />`);
1258
1283
  lines.push(` );`);
1259
1284
  } else {
1285
+ lines.push(` const handleSubmit = (data: any) => {`);
1286
+ lines.push(` const mutation = id ? update${name}.mutate({ id, data }) : create${name}.mutate(data);`);
1287
+ lines.push(` if (onSuccess) {`);
1288
+ lines.push(` // Call onSuccess after mutation completes`);
1289
+ lines.push(` Promise.resolve(mutation).then(() => onSuccess()).catch(() => {});`);
1290
+ lines.push(` }`);
1291
+ lines.push(` };`);
1292
+ lines.push(``);
1260
1293
  lines.push(` return (`);
1261
1294
  lines.push(` <FormGenerator`);
1262
1295
  lines.push(` fields={fields}`);
1263
- lines.push(` schema={${name}Schema}`);
1264
- lines.push(
1265
- ` onSubmit={(data) => id ? update${name}.mutate({ id, data }) : create${name}.mutate(data)}`
1266
- );
1296
+ lines.push(` schema={${name}CreateSchema}`);
1297
+ lines.push(` onSubmit={handleSubmit}`);
1267
1298
  lines.push(` />`);
1268
1299
  lines.push(` );`);
1269
1300
  }
@@ -1339,6 +1370,35 @@ function generateMenuData(config) {
1339
1370
  lines.push(``);
1340
1371
  return lines.join("\n");
1341
1372
  }
1373
+
1374
+ // src/frontend/codegen/providers.ts
1375
+ function generateProvidersFile(config) {
1376
+ const { staleTime, gcTime } = config;
1377
+ const lines = [];
1378
+ lines.push(`'use client'`);
1379
+ lines.push(``);
1380
+ lines.push(`import { QueryClient, QueryClientProvider } from '@tanstack/react-query'`);
1381
+ lines.push(`import { useState } from 'react'`);
1382
+ lines.push(``);
1383
+ lines.push(`export function Providers({ children }: { children: React.ReactNode }) {`);
1384
+ lines.push(` const [queryClient] = useState(() => new QueryClient({`);
1385
+ lines.push(` defaultOptions: {`);
1386
+ lines.push(` queries: {`);
1387
+ lines.push(` staleTime: ${staleTime},`);
1388
+ lines.push(` gcTime: ${gcTime},`);
1389
+ lines.push(` },`);
1390
+ lines.push(` },`);
1391
+ lines.push(` }))`);
1392
+ lines.push(``);
1393
+ lines.push(` return (`);
1394
+ lines.push(` <QueryClientProvider client={queryClient}>`);
1395
+ lines.push(` {children}`);
1396
+ lines.push(` </QueryClientProvider>`);
1397
+ lines.push(` )`);
1398
+ lines.push(`}`);
1399
+ lines.push(``);
1400
+ return lines.join("\n");
1401
+ }
1342
1402
  var GREEN = "\x1B[32m";
1343
1403
  var YELLOW = "\x1B[33m";
1344
1404
  var BLUE = "\x1B[34m";
@@ -1449,6 +1509,11 @@ async function generateAll(config) {
1449
1509
  }
1450
1510
  const baseResults = await copyBaseComponents(outputDir, packageRoot);
1451
1511
  results.push(...baseResults);
1512
+ if (framework === "nextjs" && structure.usesAppRouter) {
1513
+ const providersContent = generateProvidersFile(config);
1514
+ const providersPath = path3__namespace.join(outputDir, "components", "providers.tsx");
1515
+ results.push(await writeFile(providersPath, providersContent));
1516
+ }
1452
1517
  if (generateMenu) {
1453
1518
  const menuContent = generateMenuData(config);
1454
1519
  const menuPath = path3__namespace.join(outputDir, "lib", "menu-data.ts");