@xubylele/schema-forge 1.11.0 → 1.12.1
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 +35 -0
- package/dist/api.d.ts +0 -49
- package/dist/api.js +400 -15
- package/dist/cli.js +452 -19
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ A modern CLI tool for database schema management with a clean DSL and automatic
|
|
|
14
14
|
- **Postgres/Supabase** - Currently supports PostgreSQL and Supabase
|
|
15
15
|
- **Constraint Diffing** - Detects UNIQUE and PRIMARY KEY changes with deterministic constraint names
|
|
16
16
|
- **Live PostgreSQL Introspection** - Extract normalized schema directly from `information_schema`
|
|
17
|
+
- **Policy (RLS) support** - Define Row Level Security policies in the DSL: `for select|insert|update|delete|all`, optional `to role1 role2` (e.g. `anon`, `authenticated`). Invalid policies produce clear CLI errors during validation. See [RLS policy patterns](https://github.com/xubylele/schema-forge-core/blob/main/docs/rls-policy-patterns.md) for user-owned rows, public read/authenticated write, and multi-tenant examples.
|
|
17
18
|
|
|
18
19
|
## Installation
|
|
19
20
|
|
|
@@ -324,6 +325,7 @@ Live `--json` output returns a structured `DriftReport`:
|
|
|
324
325
|
|
|
325
326
|
Validation checks include:
|
|
326
327
|
|
|
328
|
+
- **Policy validation** – Each policy must reference an existing table, use a valid command (`select` / `insert` / `update` / `delete` / `all`), and have at least one of `using` or `with check`. Invalid policies cause validation to fail with a clear error (exit code 1).
|
|
327
329
|
- Dropped tables (`DROP_TABLE`, error)
|
|
328
330
|
- Dropped columns (`DROP_COLUMN`, error)
|
|
329
331
|
- Column type changes (`ALTER_COLUMN_TYPE`, warning/error based on compatibility heuristics)
|
|
@@ -566,6 +568,39 @@ table table_name {
|
|
|
566
568
|
- `default <value>` - Default value (e.g., `default now()`, `default false`, `default 0`)
|
|
567
569
|
- `fk <table>.<column>` - Foreign key reference (e.g., `fk users.id`)
|
|
568
570
|
|
|
571
|
+
### Policies (RLS)
|
|
572
|
+
|
|
573
|
+
Row Level Security policies are declared at the top level (the table must be defined first). Each policy must have a `for` command and at least one of `using` or `with check`.
|
|
574
|
+
|
|
575
|
+
```sql
|
|
576
|
+
table users {
|
|
577
|
+
id uuid pk
|
|
578
|
+
email text unique
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
policy "Users can read themselves" on users
|
|
582
|
+
for select
|
|
583
|
+
using auth.uid() = id
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
- **First line:** `policy "<name>" on <table>`
|
|
587
|
+
- **Continuation:** `for <command>` (required): `select`, `insert`, `update`, `delete`, or `all` (applies to all commands). Optional `to role1 role2` (e.g. `to anon authenticated`). Optional `using <expr>` and `with check <expr>`.
|
|
588
|
+
|
|
589
|
+
Example with `for all` and `to`:
|
|
590
|
+
|
|
591
|
+
```sql
|
|
592
|
+
policy "Own rows" on profiles
|
|
593
|
+
for all
|
|
594
|
+
using auth.uid() = id
|
|
595
|
+
with check auth.uid() = id
|
|
596
|
+
|
|
597
|
+
policy "Public read" on items
|
|
598
|
+
for select to anon authenticated
|
|
599
|
+
using true
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
Invalid policies (missing table, invalid command, or no expressions) fail `schema-forge validate` with a clear error message. For common patterns (user-owned rows, public read / authenticated write, multi-tenant), see [RLS policy patterns](https://github.com/xubylele/schema-forge-core/blob/main/docs/rls-policy-patterns.md) in the core package.
|
|
603
|
+
|
|
569
604
|
### Examples
|
|
570
605
|
|
|
571
606
|
#### Simple table
|
package/dist/api.d.ts
CHANGED
|
@@ -11,14 +11,12 @@ interface DoctorOptions {
|
|
|
11
11
|
schema?: string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/** Migration file name format: hyphen (timestamp-name.sql) or underscore (timestamp_name.sql, Supabase CLI style). */
|
|
15
14
|
type MigrationFileNameFormat = 'hyphen' | 'underscore';
|
|
16
15
|
|
|
17
16
|
interface GenerateOptions {
|
|
18
17
|
name?: string;
|
|
19
18
|
safe?: boolean;
|
|
20
19
|
force?: boolean;
|
|
21
|
-
/** Override migration file name format: hyphen (timestamp-name.sql) or underscore (timestamp_name.sql). */
|
|
22
20
|
migrationFormat?: MigrationFileNameFormat;
|
|
23
21
|
}
|
|
24
22
|
|
|
@@ -44,69 +42,22 @@ interface ValidateOptions {
|
|
|
44
42
|
force?: boolean;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
/**
|
|
48
|
-
* Exit codes used throughout the CLI for deterministic behavior
|
|
49
|
-
*
|
|
50
|
-
* @see SF-106 Standardize Exit Codes
|
|
51
|
-
*/
|
|
52
45
|
declare const EXIT_CODES: {
|
|
53
|
-
/** Successful operation */
|
|
54
46
|
readonly SUCCESS: 0;
|
|
55
|
-
/** Validation error (invalid DSL syntax, config errors, missing files, etc.) */
|
|
56
47
|
readonly VALIDATION_ERROR: 1;
|
|
57
|
-
/** Drift detected - Reserved for future use when comparing actual DB state vs schema */
|
|
58
48
|
readonly DRIFT_DETECTED: 2;
|
|
59
|
-
/** Destructive operation detected in CI environment without --force */
|
|
60
49
|
readonly CI_DESTRUCTIVE: 3;
|
|
61
50
|
};
|
|
62
51
|
|
|
63
|
-
/**
|
|
64
|
-
* Programmatic API for Schema Forge.
|
|
65
|
-
* Use this entrypoint when integrating from Node (e.g. scripts, GitHub Actions)
|
|
66
|
-
* instead of invoking the CLI via shell.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* const { generate, EXIT_CODES } = require('@xubylele/schema-forge/api');
|
|
70
|
-
* const result = await generate({ name: 'MyMigration' });
|
|
71
|
-
* if (result.exitCode !== EXIT_CODES.SUCCESS) process.exit(result.exitCode);
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Result of a programmatic command run. Exit codes match the CLI contract.
|
|
76
|
-
* @see docs/exit-codes.json
|
|
77
|
-
*/
|
|
78
52
|
interface RunResult {
|
|
79
53
|
exitCode: number;
|
|
80
54
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Initialize a new schema project in the current directory.
|
|
83
|
-
* @param options.provider - Database provider: 'postgres' (default) or 'supabase'. Supabase uses supabase/migrations for output.
|
|
84
|
-
*/
|
|
85
55
|
declare function init(options?: InitOptions): Promise<RunResult>;
|
|
86
|
-
/**
|
|
87
|
-
* Generate SQL migration from schema files.
|
|
88
|
-
*/
|
|
89
56
|
declare function generate(options?: GenerateOptions): Promise<RunResult>;
|
|
90
|
-
/**
|
|
91
|
-
* Compare two schema versions and generate migration SQL (optionally against live DB).
|
|
92
|
-
*/
|
|
93
57
|
declare function diff(options?: DiffOptions): Promise<RunResult>;
|
|
94
|
-
/**
|
|
95
|
-
* Check live database drift against state.
|
|
96
|
-
*/
|
|
97
58
|
declare function doctor(options?: DoctorOptions): Promise<RunResult>;
|
|
98
|
-
/**
|
|
99
|
-
* Validate schema and optionally check for destructive changes or live drift.
|
|
100
|
-
*/
|
|
101
59
|
declare function validate(options?: ValidateOptions): Promise<RunResult>;
|
|
102
|
-
/**
|
|
103
|
-
* Extract normalized live schema from PostgreSQL.
|
|
104
|
-
*/
|
|
105
60
|
declare function introspect(options?: IntrospectOptions): Promise<RunResult>;
|
|
106
|
-
/**
|
|
107
|
-
* Import schema from SQL migrations.
|
|
108
|
-
* @param inputPath - Path to .sql file or migrations directory
|
|
109
|
-
*/
|
|
110
61
|
declare function importSchema(inputPath: string, options?: ImportOptions): Promise<RunResult>;
|
|
111
62
|
|
|
112
63
|
export { type DiffOptions, type DoctorOptions, EXIT_CODES, type GenerateOptions, type ImportOptions, type InitOptions, type IntrospectOptions, type RunResult, type ValidateOptions, diff, doctor, generate, importSchema, init, introspect, validate };
|