schematic-pg 0.1.4 → 0.1.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/README.md CHANGED
@@ -203,6 +203,14 @@ cd my-app
203
203
 
204
204
  Edit `app.schema`, then generate code and start the API:
205
205
 
206
+ ```bash
207
+ make dev
208
+ # → starts PostgreSQL, generates code, bootstraps the DB, and runs the dev server
209
+ # → http://localhost:3000
210
+ ```
211
+
212
+ Or run each step individually:
213
+
206
214
  ```bash
207
215
  # Start PostgreSQL (PostGIS-enabled, matches .env defaults)
208
216
  docker compose up -d
@@ -225,6 +233,7 @@ The `init` command creates everything you need to get running:
225
233
  | `app.schema` | Starter schema (one `User` model) — edit this |
226
234
  | `.env` | `DATABASE_URL`, JWT settings |
227
235
  | `docker-compose.yml` | Local PostGIS PostgreSQL on `:5432` |
236
+ | `Makefile` | `make dev` — docker compose + generate + db:bootstrap + dev |
228
237
  | `tsconfig.json` | TypeScript config for `generated/` and `src/routes/` |
229
238
  | `package.json` | `schematic-pg` + runtime deps (`hono`, `pg`, `zod`, …) |
230
239
  | `src/routes/health.ts` | Example custom route mounted at `/health` |
@@ -286,6 +295,7 @@ schematic-pg dev [schema] # generate:client + generate:api, then start generat
286
295
  Equivalent npm scripts in a project created by `init`:
287
296
 
288
297
  ```bash
298
+ make dev # docker compose up -d + generate + db:bootstrap + dev
289
299
  npm run dev # schematic-pg dev
290
300
  npm run generate # schematic-pg generate
291
301
  ```
@@ -11,4 +11,5 @@ export declare function getFilterFieldKind(field: Field, schema: Schema): Filter
11
11
  export declare function getFilterOperators(kind: FilterFieldKind): FilterOperator[];
12
12
  export declare function buildFilterFieldMeta(field: Field, schema: Schema): FilterFieldMeta;
13
13
  export declare function queryParamKey(fieldName: string, operator: FilterOperator): string;
14
+ export declare function toQueryBooleanZodType(): string;
14
15
  export declare function toFilterZodType(type: TypeExpr, field: Field, schema: Schema, operator: FilterOperator, coerce?: boolean): string;
@@ -54,6 +54,12 @@ export function queryParamKey(fieldName, operator) {
54
54
  }
55
55
  return `${fieldName}_${operator}`;
56
56
  }
57
+ export function toQueryBooleanZodType() {
58
+ return `z.preprocess(
59
+ (value) => (typeof value === 'string' ? value.toLowerCase() : value),
60
+ z.union([z.boolean(), z.enum(['true', 'false'])]).transform((value) => value === true || value === 'true'),
61
+ )`;
62
+ }
57
63
  export function toFilterZodType(type, field, schema, operator, coerce = false) {
58
64
  const prefix = coerce ? 'z.coerce.' : 'z.';
59
65
  const enumType = schema.enums.find((enumDef) => enumDef.name === type.name);
@@ -77,7 +83,7 @@ export function toFilterZodType(type, field, schema, operator, coerce = false) {
77
83
  case 'SMALLINT':
78
84
  return `${prefix}number().int()`;
79
85
  case 'BOOLEAN':
80
- return `${prefix}boolean()`;
86
+ return toQueryBooleanZodType();
81
87
  case 'TIMESTAMP':
82
88
  return 'z.coerce.date()';
83
89
  case 'DECIMAL':
@@ -86,8 +86,7 @@ export class ZodSchemaGenerator {
86
86
  const lines = [];
87
87
  for (const operator of meta.operators) {
88
88
  const key = queryParamKey(field.name, operator);
89
- const useCoerce = operator !== 'equals' || field.type.name !== 'BOOLEAN';
90
- const zodType = toFilterZodType(field.type, field, this.schema, operator, useCoerce);
89
+ const zodType = toFilterZodType(field.type, field, this.schema, operator, true);
91
90
  lines.push(`${key}: ${zodType}.optional(),`);
92
91
  }
93
92
  return lines;
package/dist/cli/init.js CHANGED
@@ -3,12 +3,13 @@ import { PACKAGE_NAME } from '../constants.js';
3
3
  import { existsSync } from 'node:fs';
4
4
  import { mkdir, readdir, writeFile } from 'node:fs/promises';
5
5
  import path from 'node:path';
6
- import { APP_SCHEMA_TEMPLATE, createPackageJsonTemplate, DOCKER_COMPOSE_TEMPLATE, ENV_TEMPLATE, GITIGNORE_TEMPLATE, HEALTH_ROUTE_TEMPLATE, TSCONFIG_TEMPLATE, } from './templates.js';
6
+ import { APP_SCHEMA_TEMPLATE, createPackageJsonTemplate, DOCKER_COMPOSE_TEMPLATE, ENV_TEMPLATE, GITIGNORE_TEMPLATE, HEALTH_ROUTE_TEMPLATE, MAKEFILE_TEMPLATE, TSCONFIG_TEMPLATE, } from './templates.js';
7
7
  const INIT_FILES = [
8
8
  { relativePath: 'app.schema', content: APP_SCHEMA_TEMPLATE },
9
9
  { relativePath: '.env', content: ENV_TEMPLATE },
10
10
  { relativePath: '.gitignore', content: GITIGNORE_TEMPLATE },
11
11
  { relativePath: 'docker-compose.yml', content: DOCKER_COMPOSE_TEMPLATE },
12
+ { relativePath: 'Makefile', content: MAKEFILE_TEMPLATE },
12
13
  { relativePath: 'tsconfig.json', content: TSCONFIG_TEMPLATE },
13
14
  { relativePath: 'src/routes/health.ts', content: HEALTH_ROUTE_TEMPLATE },
14
15
  ];
@@ -101,6 +102,9 @@ export async function runInit(args) {
101
102
  if (skipInstall) {
102
103
  console.log(' npm install');
103
104
  }
105
+ console.log(' make dev');
106
+ console.log('');
107
+ console.log(' # or run individually:');
104
108
  console.log(' docker compose up -d');
105
109
  console.log(` npx ${PACKAGE_NAME} generate`);
106
110
  console.log(` npx ${PACKAGE_NAME} db:bootstrap`);
@@ -1,7 +1,8 @@
1
- export declare const APP_SCHEMA_TEMPLATE = "models {\n model User {\n id: UUID @id @default(gen_random_uuid())\n email: VARCHAR(255) @unique\n name: VARCHAR(150)\n createdAt: TIMESTAMP @default(now())\n }\n}\n";
1
+ export declare const APP_SCHEMA_TEMPLATE = "extensions {\n\n}\n\nenums {\n\n}\n\nmodels {\n model User {\n id: UUID @id @default(gen_random_uuid())\n email: VARCHAR(255) @unique\n name: VARCHAR(150)\n createdAt: TIMESTAMP @default(now())\n }\n}\n";
2
2
  export declare const ENV_TEMPLATE = "DATABASE_URL=postgresql://postgrest:postgrest@localhost:5432/postgrest\nJWT_SECRET=\nJWT_ROLE_CLAIM=role\nJWT_USER_ID_CLAIM=sub\n";
3
3
  export declare const GITIGNORE_TEMPLATE = "node_modules/\ndist/\n.env\ndocker_data/\n.DS_Store\n*.log\nnpm-debug.log*\n";
4
4
  export declare const DOCKER_COMPOSE_TEMPLATE = "services:\n postgres:\n image: postgis/postgis:16-3.4\n container_name: schematic-pg-postgres\n restart: unless-stopped\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_USER: postgrest\n POSTGRES_PASSWORD: postgrest\n POSTGRES_DB: postgrest\n volumes:\n - ./docker_data/postgres:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgrest -d postgrest\"]\n interval: 5s\n timeout: 5s\n retries: 5\n";
5
5
  export declare const TSCONFIG_TEMPLATE = "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"outDir\": \"dist\",\n \"rootDir\": \".\"\n },\n \"include\": [\"generated/**/*\", \"src/**/*\"]\n}\n";
6
+ export declare const MAKEFILE_TEMPLATE = ".PHONY: dev\n\ndev:\n\tdocker compose up -d\n\tnpx schematic-pg generate\n\tnpx schematic-pg db:bootstrap\n\tnpx schematic-pg dev\n";
6
7
  export declare const HEALTH_ROUTE_TEMPLATE = "import { Hono } from 'hono';\nimport type { AppEnv } from 'schematic-pg/api/types';\n\nconst router = new Hono<AppEnv>();\nrouter.get('/', (c) => c.json({ ok: true }));\nexport default router;\n";
7
8
  export declare function createPackageJsonTemplate(projectName: string): string;
@@ -1,5 +1,13 @@
1
1
  import { PACKAGE_NAME, PACKAGE_VERSION } from '../constants.js';
2
- export const APP_SCHEMA_TEMPLATE = `models {
2
+ export const APP_SCHEMA_TEMPLATE = `extensions {
3
+
4
+ }
5
+
6
+ enums {
7
+
8
+ }
9
+
10
+ models {
3
11
  model User {
4
12
  id: UUID @id @default(gen_random_uuid())
5
13
  email: VARCHAR(255) @unique
@@ -54,6 +62,14 @@ export const TSCONFIG_TEMPLATE = `{
54
62
  "include": ["generated/**/*", "src/**/*"]
55
63
  }
56
64
  `;
65
+ export const MAKEFILE_TEMPLATE = `.PHONY: dev
66
+
67
+ dev:
68
+ \tdocker compose up -d
69
+ \tnpx ${PACKAGE_NAME} generate
70
+ \tnpx ${PACKAGE_NAME} db:bootstrap
71
+ \tnpx ${PACKAGE_NAME} dev
72
+ `;
57
73
  export const HEALTH_ROUTE_TEMPLATE = `import { Hono } from 'hono';
58
74
  import type { AppEnv } from '${PACKAGE_NAME}/api/types';
59
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schematic-pg",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Single-file backend framework for PostgreSQL and Node.js",
5
5
  "type": "module",
6
6
  "license": "MIT",