@simplix-react/mock 0.0.2 → 0.1.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.
package/README.md CHANGED
@@ -22,7 +22,7 @@ Peer dependencies:
22
22
  ## Quick Example
23
23
 
24
24
  ```ts
25
- import { defineContract } from "@simplix-react/contract";
25
+ import { defineApi, simpleQueryBuilder } from "@simplix-react/contract";
26
26
  import {
27
27
  setupMockWorker,
28
28
  deriveMockHandlers,
@@ -31,7 +31,7 @@ import {
31
31
  import { z } from "zod";
32
32
 
33
33
  // 1. Define your contract
34
- const projectContract = defineContract({
34
+ const projectContract = defineApi({
35
35
  domain: "project",
36
36
  basePath: "/api",
37
37
  entities: {
@@ -41,12 +41,13 @@ const projectContract = defineContract({
41
41
  id: z.string(),
42
42
  title: z.string(),
43
43
  status: z.enum(["todo", "done"]),
44
- createdAt: z.date(),
44
+ createdAt: z.string(),
45
45
  }),
46
46
  createSchema: z.object({ title: z.string() }),
47
47
  updateSchema: z.object({ status: z.enum(["todo", "done"]).optional() }),
48
48
  },
49
49
  },
50
+ queryBuilder: simpleQueryBuilder,
50
51
  });
51
52
 
52
53
  // 2. Derive handlers and bootstrap
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { PGlite } from '@electric-sql/pglite';
2
2
  import * as msw from 'msw';
3
- import { EntityDefinition, OperationDefinition, ApiContractConfig } from '@simplix-react/contract';
4
- import { z } from 'zod';
3
+ import { AnyEntityDef, AnyOperationDef, ApiContractConfig } from '@simplix-react/contract';
5
4
 
6
5
  /**
7
6
  * Initializes a singleton PGlite instance with the given data directory.
@@ -140,8 +139,6 @@ interface MockServerConfig {
140
139
  */
141
140
  declare function setupMockWorker(config: MockServerConfig): Promise<void>;
142
141
 
143
- type AnyEntityDef = EntityDefinition<z.ZodTypeAny, z.ZodTypeAny, z.ZodTypeAny>;
144
- type AnyOperationDef = OperationDefinition<z.ZodTypeAny, z.ZodTypeAny>;
145
142
  /**
146
143
  * Provides per-entity configuration for mock handler generation.
147
144
  *
@@ -337,21 +334,6 @@ type DbRow = Record<string, unknown>;
337
334
  * ```
338
335
  */
339
336
  declare function toCamelCase(str: string): string;
340
- /**
341
- * Converts a camelCase string to snake_case.
342
- *
343
- * @param str - The camelCase input string.
344
- * @returns The snake_case equivalent.
345
- *
346
- * @example
347
- * ```ts
348
- * import { toSnakeCase } from "@simplix-react/mock";
349
- *
350
- * toSnakeCase("createdAt"); // "created_at"
351
- * toSnakeCase("projectId"); // "project_id"
352
- * ```
353
- */
354
- declare function toSnakeCase(str: string): string;
355
337
  /**
356
338
  * Maps a single database row from snake_case columns to a camelCase object.
357
339
  *
@@ -568,4 +550,4 @@ declare function executeSql(db: PGlite, sql: string): Promise<void>;
568
550
  */
569
551
  declare function addColumnIfNotExists(db: PGlite, tableName: string, columnName: string, columnDef: string): Promise<void>;
570
552
 
571
- export { type DbRow, type MockEntityConfig, type MockError, type MockResult, type MockServerConfig, type SetClauseResult, addColumnIfNotExists, buildSetClause, columnExists, deriveMockHandlers, executeSql, getPGliteInstance, initPGlite, mapPgError, mapRow, mapRows, mockFailure, mockSuccess, resetPGliteInstance, setupMockWorker, tableExists, toCamelCase, toSnakeCase };
553
+ export { type DbRow, type MockEntityConfig, type MockError, type MockResult, type MockServerConfig, type SetClauseResult, addColumnIfNotExists, buildSetClause, columnExists, deriveMockHandlers, executeSql, getPGliteInstance, initPGlite, mapPgError, mapRow, mapRows, mockFailure, mockSuccess, resetPGliteInstance, setupMockWorker, tableExists, toCamelCase };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { http, HttpResponse } from 'msw';
2
+ import { camelToSnake } from '@simplix-react/contract';
2
3
 
3
4
  // src/pglite.ts
4
5
  var instance = null;
@@ -47,9 +48,6 @@ async function setupMockWorker(config) {
47
48
  function toCamelCase(str) {
48
49
  return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
49
50
  }
50
- function toSnakeCase(str) {
51
- return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
52
- }
53
51
  function mapRow(row) {
54
52
  const result = {};
55
53
  for (const [key, value] of Object.entries(row)) {
@@ -65,15 +63,13 @@ function mapRow(row) {
65
63
  function mapRows(rows) {
66
64
  return rows.map((row) => mapRow(row));
67
65
  }
68
-
69
- // src/sql/query-building.ts
70
66
  function buildSetClause(input, startIndex = 1) {
71
67
  const parts = [];
72
68
  const values = [];
73
69
  let index = startIndex;
74
70
  for (const [key, value] of Object.entries(input)) {
75
71
  if (value === void 0) continue;
76
- const column = toSnakeCase(key);
72
+ const column = camelToSnake(key);
77
73
  if (typeof value === "object" && value !== null && !(value instanceof Date)) {
78
74
  parts.push(`${column} = $${index}::jsonb`);
79
75
  values.push(JSON.stringify(value));
@@ -145,7 +141,7 @@ function deriveMockHandlers(config, mockConfig) {
145
141
  const { basePath, entities } = config;
146
142
  for (const [name, entity] of Object.entries(entities)) {
147
143
  const entityConfig = mockConfig?.[name];
148
- const tableName = entityConfig?.tableName ?? toSnakeCase(name) + "s";
144
+ const tableName = entityConfig?.tableName ?? camelToSnake(name) + "s";
149
145
  const defaultLimit = entityConfig?.defaultLimit ?? 50;
150
146
  const maxLimit = entityConfig?.maxLimit ?? 100;
151
147
  const defaultSort = entityConfig?.defaultSort ?? "created_at DESC";
@@ -155,7 +151,7 @@ function deriveMockHandlers(config, mockConfig) {
155
151
  handlers.push(
156
152
  http.get(listPath, async ({ request, params: routeParams }) => {
157
153
  const parentId = routeParams[entity.parent.param];
158
- const parentColumn = toSnakeCase(entity.parent.param);
154
+ const parentColumn = camelToSnake(entity.parent.param);
159
155
  const searchParams = parseSearchParams(request.url);
160
156
  return toResponse(
161
157
  await queryListWithParams(
@@ -265,7 +261,7 @@ async function queryListWithParams(tableName, parentColumn, parentId, searchPara
265
261
  paramIndex++;
266
262
  }
267
263
  for (const [key, value] of Object.entries(searchParams.filters)) {
268
- const column = toSnakeCase(key);
264
+ const column = camelToSnake(key);
269
265
  conditions.push(`${column} = $${paramIndex}`);
270
266
  values.push(value);
271
267
  paramIndex++;
@@ -275,7 +271,7 @@ async function queryListWithParams(tableName, parentColumn, parentId, searchPara
275
271
  if (searchParams.sort) {
276
272
  const sortParts = searchParams.sort.split(",").map((s) => {
277
273
  const [field, dir] = s.trim().split(":");
278
- const column = toSnakeCase(field);
274
+ const column = camelToSnake(field);
279
275
  const direction = dir === "desc" ? "DESC" : "ASC";
280
276
  return `${column} ${direction}`;
281
277
  });
@@ -333,7 +329,7 @@ async function queryByIdWithRelations(tableName, id, relations) {
333
329
  const row = mainResult.rows[0];
334
330
  const mapped = mapRow(row);
335
331
  for (const [relationName, relation] of Object.entries(relations)) {
336
- const localColumn = toSnakeCase(relation.localKey);
332
+ const localColumn = camelToSnake(relation.localKey);
337
333
  const fkValue = row[localColumn];
338
334
  if (fkValue) {
339
335
  const foreignKey = relation.foreignKey ?? "id";
@@ -367,7 +363,7 @@ async function insertRow(tableName, dto) {
367
363
  }
368
364
  for (const [key, value] of Object.entries(dto)) {
369
365
  if (value === void 0) continue;
370
- const column = toSnakeCase(key);
366
+ const column = camelToSnake(key);
371
367
  columns.push(column);
372
368
  if (typeof value === "object" && value !== null && !(value instanceof Date)) {
373
369
  placeholders.push(`$${index}::jsonb`);
@@ -472,4 +468,4 @@ async function addColumnIfNotExists(db, tableName, columnName, columnDef) {
472
468
  }
473
469
  }
474
470
 
475
- export { addColumnIfNotExists, buildSetClause, columnExists, deriveMockHandlers, executeSql, getPGliteInstance, initPGlite, mapPgError, mapRow, mapRows, mockFailure, mockSuccess, resetPGliteInstance, setupMockWorker, tableExists, toCamelCase, toSnakeCase };
471
+ export { addColumnIfNotExists, buildSetClause, columnExists, deriveMockHandlers, executeSql, getPGliteInstance, initPGlite, mapPgError, mapRow, mapRows, mockFailure, mockSuccess, resetPGliteInstance, setupMockWorker, tableExists, toCamelCase };
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@simplix-react/mock",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "Auto-generated MSW handlers and PGlite repositories from @simplix-react/contract",
5
5
  "type": "module",
6
+ "sideEffects": false,
6
7
  "exports": {
7
8
  ".": {
8
9
  "types": "./dist/index.d.ts",
@@ -15,19 +16,11 @@
15
16
  "publishConfig": {
16
17
  "access": "public"
17
18
  },
18
- "scripts": {
19
- "build": "tsup",
20
- "dev": "tsup --watch",
21
- "typecheck": "tsc --noEmit",
22
- "lint": "eslint src",
23
- "test": "vitest run --passWithNoTests",
24
- "clean": "rm -rf dist .turbo"
25
- },
26
19
  "peerDependencies": {
27
20
  "@electric-sql/pglite": ">=0.2.0",
28
- "@simplix-react/contract": "workspace:*",
29
21
  "msw": ">=2.0.0",
30
- "zod": ">=4.0.0"
22
+ "zod": ">=4.0.0",
23
+ "@simplix-react/contract": "0.1.0"
31
24
  },
32
25
  "peerDependenciesMeta": {
33
26
  "@electric-sql/pglite": {
@@ -39,14 +32,22 @@
39
32
  },
40
33
  "devDependencies": {
41
34
  "@electric-sql/pglite": "^0.3.14",
42
- "@simplix-react/config-eslint": "workspace:*",
43
- "@simplix-react/config-typescript": "workspace:*",
44
- "@simplix-react/contract": "workspace:*",
45
35
  "eslint": "^9.39.2",
46
36
  "msw": "^2.7.0",
47
37
  "tsup": "^8.5.1",
48
38
  "typescript": "^5.9.3",
49
39
  "vitest": "^3.0.0",
50
- "zod": "^4.0.0"
40
+ "zod": "^4.0.0",
41
+ "@simplix-react/config-eslint": "0.0.1",
42
+ "@simplix-react/config-typescript": "0.0.1",
43
+ "@simplix-react/contract": "0.1.0"
44
+ },
45
+ "scripts": {
46
+ "build": "tsup",
47
+ "dev": "tsup --watch",
48
+ "typecheck": "tsc --noEmit",
49
+ "lint": "eslint src",
50
+ "test": "vitest run --passWithNoTests",
51
+ "clean": "rm -rf dist .turbo"
51
52
  }
52
- }
53
+ }