@famgia/omnify-sql 0.0.2

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 ADDED
@@ -0,0 +1,201 @@
1
+ # @famgia/omnify-sql
2
+
3
+ Raw SQL Migration Generator for Omnify schemas. Generates versioned SQL migration files (`0001_create_users.sql`, `0002_create_posts.sql`, etc.) from Omnify schema definitions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @famgia/omnify-sql
9
+ # or
10
+ pnpm add @famgia/omnify-sql
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - **Multi-dialect support**: MySQL, PostgreSQL, SQLite
16
+ - **Versioned migrations**: Auto-numbered migration files
17
+ - **Foreign keys**: Automatic FK generation with referential actions
18
+ - **Pivot tables**: ManyToMany and MorphToMany support
19
+ - **Index types**: btree, hash, fulltext, spatial, gin, gist
20
+ - **Spatial types**: Point and Coordinates
21
+ - **Compatibility validation**: Errors for incompatible type/dialect combinations
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import { generateMigrations } from '@famgia/omnify-sql';
27
+
28
+ const schemas = {
29
+ User: {
30
+ name: 'User',
31
+ kind: 'object',
32
+ properties: {
33
+ email: { type: 'Email', unique: true },
34
+ name: { type: 'String' },
35
+ },
36
+ options: { timestamps: true },
37
+ },
38
+ };
39
+
40
+ const migrations = generateMigrations(schemas, { dialect: 'mysql' });
41
+
42
+ for (const migration of migrations) {
43
+ console.log(migration.fileName);
44
+ // 0001_create_users.sql
45
+ console.log(migration.content);
46
+ // CREATE TABLE `users` ...
47
+ }
48
+ ```
49
+
50
+ ## Supported Dialects
51
+
52
+ | Feature | MySQL | PostgreSQL | SQLite |
53
+ |---------|:-----:|:----------:|:------:|
54
+ | Basic types | ✅ | ✅ | ✅ |
55
+ | Foreign keys | ✅ | ✅ | ✅ |
56
+ | Timestamps | ✅ | ✅ | ✅ |
57
+ | Soft delete | ✅ | ✅ | ✅ |
58
+ | JSON | `JSON` | `JSONB` | `TEXT` |
59
+ | UUID | `CHAR(36)` | `UUID` | `TEXT` |
60
+ | Boolean | `TINYINT(1)` | `BOOLEAN` | `INTEGER` |
61
+
62
+ ## Data Types
63
+
64
+ ### Standard Types
65
+
66
+ | Omnify Type | MySQL | PostgreSQL | SQLite |
67
+ |-------------|-------|------------|--------|
68
+ | `String` | `VARCHAR(255)` | `VARCHAR(255)` | `TEXT` |
69
+ | `Int` | `INT` | `INTEGER` | `INTEGER` |
70
+ | `BigInt` | `BIGINT` | `BIGINT` | `INTEGER` |
71
+ | `Float` | `DOUBLE` | `DOUBLE PRECISION` | `REAL` |
72
+ | `Decimal` | `DECIMAL(p,s)` | `DECIMAL(p,s)` | `REAL` |
73
+ | `Boolean` | `TINYINT(1)` | `BOOLEAN` | `INTEGER` |
74
+ | `Text` | `TEXT` | `TEXT` | `TEXT` |
75
+ | `LongText` | `LONGTEXT` | `TEXT` | `TEXT` |
76
+ | `Date` | `DATE` | `DATE` | `TEXT` |
77
+ | `Time` | `TIME` | `TIME` | `TEXT` |
78
+ | `Timestamp` | `TIMESTAMP` | `TIMESTAMP` | `TEXT` |
79
+ | `Json` | `JSON` | `JSONB` | `TEXT` |
80
+ | `Email` | `VARCHAR(255)` | `VARCHAR(255)` | `TEXT` |
81
+ | `Password` | `VARCHAR(255)` | `VARCHAR(255)` | `TEXT` |
82
+
83
+ ### Spatial/Geographic Types
84
+
85
+ | Type | MySQL | PostgreSQL | SQLite | Cross-DB |
86
+ |------|-------|------------|--------|:--------:|
87
+ | `Point` | `POINT` | `geometry(Point, 4326)` | ❌ Error | No |
88
+ | `Coordinates` | `DECIMAL(10,8)` + `DECIMAL(11,8)` | `DECIMAL(10,8)` + `DECIMAL(11,8)` | `REAL` + `REAL` | ✅ Yes |
89
+
90
+ **Note**: `Coordinates` type generates two columns: `{name}_latitude` and `{name}_longitude`.
91
+
92
+ ```yaml
93
+ # Schema
94
+ properties:
95
+ location:
96
+ type: Coordinates
97
+ nullable: true
98
+
99
+ # Generated SQL (MySQL)
100
+ `location_latitude` DECIMAL(10, 8) NULL,
101
+ `location_longitude` DECIMAL(11, 8) NULL
102
+ ```
103
+
104
+ ## Index Types
105
+
106
+ | Index Type | MySQL | PostgreSQL | SQLite | Use Case |
107
+ |------------|:-----:|:----------:|:------:|----------|
108
+ | `btree` | ✅ | ✅ | ✅ | Default, general purpose |
109
+ | `hash` | ✅ | ✅ | ✅ (fallback) | Equality lookups |
110
+ | `fulltext` | ✅ | ✅ (GIN) | ❌ Error | Text search |
111
+ | `spatial` | ✅ | ✅ (GIST) | ❌ Error | Geographic data |
112
+ | `gin` | ❌ Error | ✅ | ❌ Error | JSONB, arrays |
113
+ | `gist` | ❌ Error | ✅ | ❌ Error | Spatial, range types |
114
+
115
+ ### Example
116
+
117
+ ```yaml
118
+ options:
119
+ indexes:
120
+ - columns: [title, content]
121
+ type: fulltext
122
+ name: articles_fulltext
123
+ - columns: [email]
124
+ unique: true
125
+ ```
126
+
127
+ Generated SQL:
128
+ ```sql
129
+ -- MySQL
130
+ CREATE FULLTEXT INDEX `articles_fulltext` ON `articles` (`title`, `content`);
131
+
132
+ -- PostgreSQL
133
+ CREATE INDEX "articles_fulltext" ON "articles"
134
+ USING GIN (to_tsvector('english', "title") || to_tsvector('english', "content"));
135
+ ```
136
+
137
+ ## Compatibility Validation
138
+
139
+ The generator automatically validates type and index compatibility with the target dialect. Incompatible combinations throw descriptive errors:
140
+
141
+ ```
142
+ SQL Generator: Incompatible types detected for dialect "sqlite":
143
+
144
+ 1. Schema "Store", property "location": Type "Point" is not supported in sqlite.
145
+ SQLite does not support native spatial types. Use Coordinates type for
146
+ cross-database compatibility.
147
+
148
+ 2. Schema "Article", index "articles_ft": Index type "fulltext" is not supported
149
+ in sqlite. SQLite does not support native fulltext indexes.
150
+
151
+ To fix: Either change the type/index or use a compatible dialect.
152
+ ```
153
+
154
+ ## API Reference
155
+
156
+ ### `generateMigrations(schemas, options)`
157
+
158
+ Generates all migrations for a schema collection.
159
+
160
+ ```typescript
161
+ const migrations = generateMigrations(schemas, {
162
+ dialect: 'mysql', // 'mysql' | 'postgresql' | 'sqlite'
163
+ ifNotExists: true, // Add IF NOT EXISTS
164
+ generateDown: true, // Include DROP TABLE comments
165
+ startVersion: 1, // Starting version number
166
+ versionPadding: 4, // Padding for version (0001, 00001, etc.)
167
+ });
168
+ ```
169
+
170
+ ### `generateMigrationFromSchema(schema, allSchemas, options)`
171
+
172
+ Generates a single migration for one schema.
173
+
174
+ ### `generateDropMigration(tableName, options)`
175
+
176
+ Generates a DROP TABLE migration.
177
+
178
+ ### `getMigrationPath(migration, basePath)`
179
+
180
+ Returns the file path for a migration.
181
+
182
+ ## Plugin Usage
183
+
184
+ Use as an Omnify plugin:
185
+
186
+ ```typescript
187
+ import sqlPlugin from '@famgia/omnify-sql/plugin';
188
+
189
+ const config = {
190
+ plugins: [
191
+ sqlPlugin({
192
+ dialect: 'postgresql',
193
+ outputDir: 'database/migrations',
194
+ }),
195
+ ],
196
+ };
197
+ ```
198
+
199
+ ## License
200
+
201
+ MIT