postgresdk 0.6.4 → 0.6.5

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
@@ -2354,7 +2354,12 @@ import type { Insert${Type}, Update${Type}, Select${Type} } from '${clientPath}/
2354
2354
  * Basic tests for ${tableName} table operations
2355
2355
  *
2356
2356
  * These tests demonstrate basic CRUD operations.
2357
- * Add your own business logic tests in separate files.
2357
+ * The test data is auto-generated and may need adjustment for your specific schema.
2358
+ *
2359
+ * If tests fail due to validation errors:
2360
+ * 1. Check which fields are required by your API
2361
+ * 2. Update the test data below to match your schema requirements
2362
+ * 3. Consider adding your own business logic tests in separate files
2358
2363
  */
2359
2364
  describe('${Type} SDK Operations', () => {
2360
2365
  let sdk: SDK;
@@ -2417,6 +2422,38 @@ export function randomDate(): Date {
2417
2422
  }
2418
2423
  `;
2419
2424
  }
2425
+ function emitVitestConfig() {
2426
+ return `import { defineConfig } from 'vitest/config';
2427
+
2428
+ export default defineConfig({
2429
+ test: {
2430
+ globals: true,
2431
+ environment: 'node',
2432
+ testTimeout: 30000,
2433
+ hookTimeout: 30000,
2434
+ // The reporters are configured via CLI in the test script
2435
+ },
2436
+ });
2437
+ `;
2438
+ }
2439
+ function emitTestGitignore() {
2440
+ return `# Test results
2441
+ test-results/
2442
+ *.log
2443
+
2444
+ # Node modules (if tests have their own dependencies)
2445
+ node_modules/
2446
+
2447
+ # Environment files
2448
+ .env
2449
+ .env.local
2450
+ .env.test
2451
+
2452
+ # Coverage reports
2453
+ coverage/
2454
+ *.lcov
2455
+ `;
2456
+ }
2420
2457
  function emitDockerCompose() {
2421
2458
  return `# Docker Compose for Test Database
2422
2459
  #
@@ -2502,7 +2539,14 @@ echo ""
2502
2539
  # sleep 3
2503
2540
 
2504
2541
  echo "\uD83E\uDDEA Running tests..."
2505
- ${runCommand} "$@"
2542
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
2543
+ TEST_RESULTS_DIR="$SCRIPT_DIR/test-results"
2544
+ mkdir -p "$TEST_RESULTS_DIR"
2545
+
2546
+ # Run tests with appropriate reporter based on framework
2547
+ ${getTestCommand(framework, runCommand)}
2548
+
2549
+ TEST_EXIT_CODE=$?
2506
2550
 
2507
2551
  # Cleanup
2508
2552
  # if [ ! -z "\${SERVER_PID}" ]; then
@@ -2510,12 +2554,34 @@ ${runCommand} "$@"
2510
2554
  # kill $SERVER_PID 2>/dev/null || true
2511
2555
  # fi
2512
2556
 
2513
- echo "✅ Tests completed!"
2557
+ if [ $TEST_EXIT_CODE -eq 0 ]; then
2558
+ echo "✅ Tests completed successfully!"
2559
+ else
2560
+ echo "❌ Tests failed with exit code $TEST_EXIT_CODE"
2561
+ fi
2562
+
2563
+ echo ""
2564
+ echo "\uD83D\uDCCA Test results saved to:"
2565
+ echo " $TEST_RESULTS_DIR/"
2514
2566
  echo ""
2515
2567
  echo "To stop the test database, run:"
2516
2568
  echo " cd $SCRIPT_DIR && docker-compose down"
2569
+
2570
+ exit $TEST_EXIT_CODE
2517
2571
  `;
2518
2572
  }
2573
+ function getTestCommand(framework, baseCommand) {
2574
+ switch (framework) {
2575
+ case "vitest":
2576
+ return `${baseCommand} --reporter=default --reporter=json --outputFile="$TEST_RESULTS_DIR/results-\${TIMESTAMP}.json" "$@"`;
2577
+ case "jest":
2578
+ return `${baseCommand} --json --outputFile="$TEST_RESULTS_DIR/results-\${TIMESTAMP}.json" "$@"`;
2579
+ case "bun":
2580
+ return `${baseCommand} "$@" 2>&1 | tee "$TEST_RESULTS_DIR/results-\${TIMESTAMP}.txt"`;
2581
+ default:
2582
+ return `${baseCommand} "$@"`;
2583
+ }
2584
+ }
2519
2585
  function getFrameworkImports(framework) {
2520
2586
  switch (framework) {
2521
2587
  case "vitest":
@@ -2531,14 +2597,20 @@ function getFrameworkImports(framework) {
2531
2597
  function generateSampleData(table) {
2532
2598
  const fields = [];
2533
2599
  for (const col of table.columns) {
2534
- if (col.hasDefault || col.name === "id" || col.name === "created_at" || col.name === "updated_at") {
2600
+ if (col.name === "id" && col.hasDefault) {
2535
2601
  continue;
2536
2602
  }
2537
- if (col.nullable) {
2603
+ if ((col.name === "created_at" || col.name === "updated_at") && col.hasDefault) {
2538
2604
  continue;
2539
2605
  }
2540
- const value = getSampleValue(col.pgType, col.name);
2541
- fields.push(` ${col.name}: ${value}`);
2606
+ if (col.name === "deleted_at") {
2607
+ continue;
2608
+ }
2609
+ const isImportant = col.name.endsWith("_id") || col.name.endsWith("_by") || col.name.includes("email") || col.name.includes("name") || col.name.includes("phone") || col.name.includes("address") || col.name.includes("description") || col.name.includes("color") || col.name.includes("type") || col.name.includes("status") || col.name.includes("subject");
2610
+ if (!col.nullable || isImportant) {
2611
+ const value = getSampleValue(col.pgType, col.name);
2612
+ fields.push(` ${col.name}: ${value}`);
2613
+ }
2542
2614
  }
2543
2615
  return fields.length > 0 ? `{
2544
2616
  ${fields.join(`,
@@ -2564,15 +2636,51 @@ ${fields.join(`,
2564
2636
  }
2565
2637
  function getSampleValue(type, name, isUpdate = false) {
2566
2638
  const suffix = isUpdate ? ' + " (updated)"' : "";
2639
+ if (name.endsWith("_id") || name.endsWith("_by")) {
2640
+ return `'550e8400-e29b-41d4-a716-446655440000'`;
2641
+ }
2567
2642
  if (name.includes("email")) {
2568
2643
  return `'test${isUpdate ? ".updated" : ""}@example.com'`;
2569
2644
  }
2645
+ if (name === "color") {
2646
+ return `'#${isUpdate ? "FF0000" : "0000FF"}'`;
2647
+ }
2648
+ if (name === "gender") {
2649
+ return `'${isUpdate ? "F" : "M"}'`;
2650
+ }
2651
+ if (name.includes("phone")) {
2652
+ return `'${isUpdate ? "555-0200" : "555-0100"}'`;
2653
+ }
2654
+ if (name.includes("address")) {
2655
+ return `'123 ${isUpdate ? "Updated" : "Test"} Street'`;
2656
+ }
2657
+ if (name === "type" || name === "status") {
2658
+ return `'${isUpdate ? "updated" : "active"}'`;
2659
+ }
2660
+ if (name === "subject") {
2661
+ return `'Test Subject${isUpdate ? " Updated" : ""}'`;
2662
+ }
2570
2663
  if (name.includes("name") || name.includes("title")) {
2571
2664
  return `'Test ${pascal(name)}'${suffix}`;
2572
2665
  }
2573
2666
  if (name.includes("description") || name.includes("bio") || name.includes("content")) {
2574
2667
  return `'Test description'${suffix}`;
2575
2668
  }
2669
+ if (name.includes("preferences") || name.includes("settings")) {
2670
+ return `'Test preferences'${suffix}`;
2671
+ }
2672
+ if (name.includes("restrictions") || name.includes("dietary")) {
2673
+ return `['vegetarian']`;
2674
+ }
2675
+ if (name.includes("location") || name.includes("clinic")) {
2676
+ return `'Test Location'${suffix}`;
2677
+ }
2678
+ if (name.includes("specialty")) {
2679
+ return `'General'`;
2680
+ }
2681
+ if (name.includes("tier")) {
2682
+ return `'Standard'`;
2683
+ }
2576
2684
  switch (type) {
2577
2685
  case "text":
2578
2686
  case "varchar":
@@ -2601,7 +2709,10 @@ function getSampleValue(type, name, isUpdate = false) {
2601
2709
  case "jsonb":
2602
2710
  return `{ key: 'value' }`;
2603
2711
  case "uuid":
2604
- return `'${isUpdate ? "b" : "a"}0e0e0e0-e0e0-e0e0-e0e0-e0e0e0e0e0e0'`;
2712
+ return `'${isUpdate ? "550e8400-e29b-41d4-a716-446655440001" : "550e8400-e29b-41d4-a716-446655440000"}'`;
2713
+ case "text[]":
2714
+ case "varchar[]":
2715
+ return `['item1', 'item2']`;
2605
2716
  default:
2606
2717
  return `'test'`;
2607
2718
  }
@@ -2823,6 +2934,16 @@ async function generate(configPath) {
2823
2934
  path: join(testDir, "run-tests.sh"),
2824
2935
  content: emitTestScript(testFramework)
2825
2936
  });
2937
+ files.push({
2938
+ path: join(testDir, ".gitignore"),
2939
+ content: emitTestGitignore()
2940
+ });
2941
+ if (testFramework === "vitest") {
2942
+ files.push({
2943
+ path: join(testDir, "vitest.config.ts"),
2944
+ content: emitVitestConfig()
2945
+ });
2946
+ }
2826
2947
  for (const table of Object.values(model.tables)) {
2827
2948
  files.push({
2828
2949
  path: join(testDir, `${table.name}.test.ts`),
@@ -7,6 +7,14 @@ export declare function emitTableTest(table: Table, clientPath: string, framewor
7
7
  * Generate a test setup file
8
8
  */
9
9
  export declare function emitTestSetup(clientPath: string, framework?: "vitest" | "jest" | "bun"): string;
10
+ /**
11
+ * Generate vitest config file
12
+ */
13
+ export declare function emitVitestConfig(): string;
14
+ /**
15
+ * Generate .gitignore for test directory
16
+ */
17
+ export declare function emitTestGitignore(): string;
10
18
  /**
11
19
  * Generate docker-compose.yml for test database
12
20
  */
package/dist/index.js CHANGED
@@ -2084,7 +2084,12 @@ import type { Insert${Type}, Update${Type}, Select${Type} } from '${clientPath}/
2084
2084
  * Basic tests for ${tableName} table operations
2085
2085
  *
2086
2086
  * These tests demonstrate basic CRUD operations.
2087
- * Add your own business logic tests in separate files.
2087
+ * The test data is auto-generated and may need adjustment for your specific schema.
2088
+ *
2089
+ * If tests fail due to validation errors:
2090
+ * 1. Check which fields are required by your API
2091
+ * 2. Update the test data below to match your schema requirements
2092
+ * 3. Consider adding your own business logic tests in separate files
2088
2093
  */
2089
2094
  describe('${Type} SDK Operations', () => {
2090
2095
  let sdk: SDK;
@@ -2147,6 +2152,38 @@ export function randomDate(): Date {
2147
2152
  }
2148
2153
  `;
2149
2154
  }
2155
+ function emitVitestConfig() {
2156
+ return `import { defineConfig } from 'vitest/config';
2157
+
2158
+ export default defineConfig({
2159
+ test: {
2160
+ globals: true,
2161
+ environment: 'node',
2162
+ testTimeout: 30000,
2163
+ hookTimeout: 30000,
2164
+ // The reporters are configured via CLI in the test script
2165
+ },
2166
+ });
2167
+ `;
2168
+ }
2169
+ function emitTestGitignore() {
2170
+ return `# Test results
2171
+ test-results/
2172
+ *.log
2173
+
2174
+ # Node modules (if tests have their own dependencies)
2175
+ node_modules/
2176
+
2177
+ # Environment files
2178
+ .env
2179
+ .env.local
2180
+ .env.test
2181
+
2182
+ # Coverage reports
2183
+ coverage/
2184
+ *.lcov
2185
+ `;
2186
+ }
2150
2187
  function emitDockerCompose() {
2151
2188
  return `# Docker Compose for Test Database
2152
2189
  #
@@ -2232,7 +2269,14 @@ echo ""
2232
2269
  # sleep 3
2233
2270
 
2234
2271
  echo "\uD83E\uDDEA Running tests..."
2235
- ${runCommand} "$@"
2272
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
2273
+ TEST_RESULTS_DIR="$SCRIPT_DIR/test-results"
2274
+ mkdir -p "$TEST_RESULTS_DIR"
2275
+
2276
+ # Run tests with appropriate reporter based on framework
2277
+ ${getTestCommand(framework, runCommand)}
2278
+
2279
+ TEST_EXIT_CODE=$?
2236
2280
 
2237
2281
  # Cleanup
2238
2282
  # if [ ! -z "\${SERVER_PID}" ]; then
@@ -2240,12 +2284,34 @@ ${runCommand} "$@"
2240
2284
  # kill $SERVER_PID 2>/dev/null || true
2241
2285
  # fi
2242
2286
 
2243
- echo "✅ Tests completed!"
2287
+ if [ $TEST_EXIT_CODE -eq 0 ]; then
2288
+ echo "✅ Tests completed successfully!"
2289
+ else
2290
+ echo "❌ Tests failed with exit code $TEST_EXIT_CODE"
2291
+ fi
2292
+
2293
+ echo ""
2294
+ echo "\uD83D\uDCCA Test results saved to:"
2295
+ echo " $TEST_RESULTS_DIR/"
2244
2296
  echo ""
2245
2297
  echo "To stop the test database, run:"
2246
2298
  echo " cd $SCRIPT_DIR && docker-compose down"
2299
+
2300
+ exit $TEST_EXIT_CODE
2247
2301
  `;
2248
2302
  }
2303
+ function getTestCommand(framework, baseCommand) {
2304
+ switch (framework) {
2305
+ case "vitest":
2306
+ return `${baseCommand} --reporter=default --reporter=json --outputFile="$TEST_RESULTS_DIR/results-\${TIMESTAMP}.json" "$@"`;
2307
+ case "jest":
2308
+ return `${baseCommand} --json --outputFile="$TEST_RESULTS_DIR/results-\${TIMESTAMP}.json" "$@"`;
2309
+ case "bun":
2310
+ return `${baseCommand} "$@" 2>&1 | tee "$TEST_RESULTS_DIR/results-\${TIMESTAMP}.txt"`;
2311
+ default:
2312
+ return `${baseCommand} "$@"`;
2313
+ }
2314
+ }
2249
2315
  function getFrameworkImports(framework) {
2250
2316
  switch (framework) {
2251
2317
  case "vitest":
@@ -2261,14 +2327,20 @@ function getFrameworkImports(framework) {
2261
2327
  function generateSampleData(table) {
2262
2328
  const fields = [];
2263
2329
  for (const col of table.columns) {
2264
- if (col.hasDefault || col.name === "id" || col.name === "created_at" || col.name === "updated_at") {
2330
+ if (col.name === "id" && col.hasDefault) {
2331
+ continue;
2332
+ }
2333
+ if ((col.name === "created_at" || col.name === "updated_at") && col.hasDefault) {
2265
2334
  continue;
2266
2335
  }
2267
- if (col.nullable) {
2336
+ if (col.name === "deleted_at") {
2268
2337
  continue;
2269
2338
  }
2270
- const value = getSampleValue(col.pgType, col.name);
2271
- fields.push(` ${col.name}: ${value}`);
2339
+ const isImportant = col.name.endsWith("_id") || col.name.endsWith("_by") || col.name.includes("email") || col.name.includes("name") || col.name.includes("phone") || col.name.includes("address") || col.name.includes("description") || col.name.includes("color") || col.name.includes("type") || col.name.includes("status") || col.name.includes("subject");
2340
+ if (!col.nullable || isImportant) {
2341
+ const value = getSampleValue(col.pgType, col.name);
2342
+ fields.push(` ${col.name}: ${value}`);
2343
+ }
2272
2344
  }
2273
2345
  return fields.length > 0 ? `{
2274
2346
  ${fields.join(`,
@@ -2294,15 +2366,51 @@ ${fields.join(`,
2294
2366
  }
2295
2367
  function getSampleValue(type, name, isUpdate = false) {
2296
2368
  const suffix = isUpdate ? ' + " (updated)"' : "";
2369
+ if (name.endsWith("_id") || name.endsWith("_by")) {
2370
+ return `'550e8400-e29b-41d4-a716-446655440000'`;
2371
+ }
2297
2372
  if (name.includes("email")) {
2298
2373
  return `'test${isUpdate ? ".updated" : ""}@example.com'`;
2299
2374
  }
2375
+ if (name === "color") {
2376
+ return `'#${isUpdate ? "FF0000" : "0000FF"}'`;
2377
+ }
2378
+ if (name === "gender") {
2379
+ return `'${isUpdate ? "F" : "M"}'`;
2380
+ }
2381
+ if (name.includes("phone")) {
2382
+ return `'${isUpdate ? "555-0200" : "555-0100"}'`;
2383
+ }
2384
+ if (name.includes("address")) {
2385
+ return `'123 ${isUpdate ? "Updated" : "Test"} Street'`;
2386
+ }
2387
+ if (name === "type" || name === "status") {
2388
+ return `'${isUpdate ? "updated" : "active"}'`;
2389
+ }
2390
+ if (name === "subject") {
2391
+ return `'Test Subject${isUpdate ? " Updated" : ""}'`;
2392
+ }
2300
2393
  if (name.includes("name") || name.includes("title")) {
2301
2394
  return `'Test ${pascal(name)}'${suffix}`;
2302
2395
  }
2303
2396
  if (name.includes("description") || name.includes("bio") || name.includes("content")) {
2304
2397
  return `'Test description'${suffix}`;
2305
2398
  }
2399
+ if (name.includes("preferences") || name.includes("settings")) {
2400
+ return `'Test preferences'${suffix}`;
2401
+ }
2402
+ if (name.includes("restrictions") || name.includes("dietary")) {
2403
+ return `['vegetarian']`;
2404
+ }
2405
+ if (name.includes("location") || name.includes("clinic")) {
2406
+ return `'Test Location'${suffix}`;
2407
+ }
2408
+ if (name.includes("specialty")) {
2409
+ return `'General'`;
2410
+ }
2411
+ if (name.includes("tier")) {
2412
+ return `'Standard'`;
2413
+ }
2306
2414
  switch (type) {
2307
2415
  case "text":
2308
2416
  case "varchar":
@@ -2331,7 +2439,10 @@ function getSampleValue(type, name, isUpdate = false) {
2331
2439
  case "jsonb":
2332
2440
  return `{ key: 'value' }`;
2333
2441
  case "uuid":
2334
- return `'${isUpdate ? "b" : "a"}0e0e0e0-e0e0-e0e0-e0e0-e0e0e0e0e0e0'`;
2442
+ return `'${isUpdate ? "550e8400-e29b-41d4-a716-446655440001" : "550e8400-e29b-41d4-a716-446655440000"}'`;
2443
+ case "text[]":
2444
+ case "varchar[]":
2445
+ return `['item1', 'item2']`;
2335
2446
  default:
2336
2447
  return `'test'`;
2337
2448
  }
@@ -2553,6 +2664,16 @@ async function generate(configPath) {
2553
2664
  path: join(testDir, "run-tests.sh"),
2554
2665
  content: emitTestScript(testFramework)
2555
2666
  });
2667
+ files.push({
2668
+ path: join(testDir, ".gitignore"),
2669
+ content: emitTestGitignore()
2670
+ });
2671
+ if (testFramework === "vitest") {
2672
+ files.push({
2673
+ path: join(testDir, "vitest.config.ts"),
2674
+ content: emitVitestConfig()
2675
+ });
2676
+ }
2556
2677
  for (const table of Object.values(model.tables)) {
2557
2678
  files.push({
2558
2679
  path: join(testDir, `${table.name}.test.ts`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {