@an5/orm 1.0.9 → 1.1.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 +10 -3
- package/dist/config.d.ts +9 -1
- package/dist/config.js +13 -18
- package/dist/generator/src/api.d.ts +35 -0
- package/dist/generator/src/api.js +58 -0
- package/dist/generator/src/config.d.ts +162 -0
- package/dist/generator/src/config.js +354 -0
- package/dist/generator/src/dialect.d.ts +88 -0
- package/dist/generator/src/dialect.js +318 -0
- package/dist/generator/src/dotnet-generator.d.ts +8 -0
- package/dist/generator/src/dotnet-generator.js +282 -101
- package/dist/generator/src/field-types.d.ts +96 -0
- package/dist/generator/src/field-types.js +433 -0
- package/dist/generator/src/golang-generator.d.ts +36 -0
- package/dist/generator/src/golang-generator.js +1230 -0
- package/dist/generator/src/index.js +69 -36
- package/dist/generator/src/metadata-generator.js +2 -1
- package/dist/generator/src/parser.d.ts +28 -2
- package/dist/generator/src/parser.js +92 -90
- package/dist/generator/src/push-apply.d.ts +37 -0
- package/dist/generator/src/push-apply.js +109 -0
- package/dist/generator/src/push-schema.d.ts +93 -0
- package/dist/generator/src/push-schema.js +189 -0
- package/dist/generator/src/python-generator.d.ts +19 -1
- package/dist/generator/src/python-generator.js +147 -64
- package/dist/generator/src/rust-generator.d.ts +38 -0
- package/dist/generator/src/rust-generator.js +971 -0
- package/dist/generator/src/suggest.d.ts +17 -0
- package/dist/generator/src/suggest.js +45 -0
- package/dist/generator/src/type-kinds.d.ts +27 -0
- package/dist/generator/src/type-kinds.js +72 -0
- package/dist/generator/src/types.d.ts +33 -0
- package/dist/generator/src/types.js +39 -0
- package/dist/migration-core.d.ts +16 -1
- package/dist/migration-core.js +60 -21
- package/dist/orm.d.ts +147 -0
- package/dist/orm.js +1654 -0
- package/dist/provider-support.d.ts +27 -0
- package/dist/provider-support.js +50 -0
- package/dist/sql-utils.js +8 -3
- package/generator/src/api.ts +45 -0
- package/generator/src/config.ts +496 -0
- package/generator/src/dialect.ts +415 -0
- package/generator/src/dotnet-generator.ts +277 -88
- package/generator/src/field-types.ts +473 -0
- package/generator/src/golang-generator.ts +94 -68
- package/generator/src/index.ts +71 -36
- package/generator/src/metadata-generator.ts +2 -2
- package/generator/src/parser.ts +122 -90
- package/generator/src/push-apply.ts +148 -0
- package/generator/src/push-schema.ts +250 -0
- package/generator/src/python-generator.ts +118 -62
- package/generator/src/rust-generator.ts +974 -0
- package/generator/src/suggest.ts +41 -0
- package/generator/src/type-kinds.ts +78 -0
- package/generator/src/types.ts +48 -0
- package/package.json +26 -6
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sqlLiteral = sqlLiteral;
|
|
4
|
+
exports.dialectFor = dialectFor;
|
|
5
|
+
exports.defaultClause = defaultClause;
|
|
6
|
+
/** `schema.table` reduced to the bare object name, e.g. `dbo.widgets`. */
|
|
7
|
+
function objectName(raw) {
|
|
8
|
+
return raw.replace(/[\[\]"`]/g, '').split('.').filter(Boolean).join('.');
|
|
9
|
+
}
|
|
10
|
+
/** A possibly schema-qualified name split into parts, unquoting each. */
|
|
11
|
+
function splitQualified(raw) {
|
|
12
|
+
const parts = raw.replace(/[\[\]"`]/g, '').split('.').filter(Boolean);
|
|
13
|
+
if (parts.length >= 2) {
|
|
14
|
+
return { schema: parts[parts.length - 2], name: parts[parts.length - 1] };
|
|
15
|
+
}
|
|
16
|
+
return { schema: undefined, name: parts[0] ?? raw };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A single-quoted SQL string literal.
|
|
20
|
+
*
|
|
21
|
+
* Every provider doubles an embedded quote, so one helper covers them all. These
|
|
22
|
+
* values come from the schema files, so they are the project's own — but an
|
|
23
|
+
* apostrophe in a column name would otherwise close the literal and produce SQL
|
|
24
|
+
* that means something else entirely.
|
|
25
|
+
*/
|
|
26
|
+
function sqlLiteral(value) {
|
|
27
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
28
|
+
}
|
|
29
|
+
/** Bracketed identifiers: SQL Server, and SQLite which accepts the same form. */
|
|
30
|
+
function bracketQuote(name) {
|
|
31
|
+
return `[${name.replace(/^\[(.*)\]$/, '$1').replace(/\]/g, ']]')}]`;
|
|
32
|
+
}
|
|
33
|
+
/** Double-quoted identifiers: the SQL standard, so PostgreSQL. */
|
|
34
|
+
function doubleQuote(name) {
|
|
35
|
+
return `"${name.replace(/^"(.*)"$/, '$1').replace(/"/g, '""')}"`;
|
|
36
|
+
}
|
|
37
|
+
/** Backtick identifiers: MySQL. */
|
|
38
|
+
function backtickQuote(name) {
|
|
39
|
+
return `\`${name.replace(/^`(.*)`$/, '$1').replace(/`/g, '``')}\``;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The schema an unqualified table lands in.
|
|
43
|
+
*
|
|
44
|
+
* `''` means "whatever the connection resolves", which is also what the DDL emits
|
|
45
|
+
* for an unqualified name — the two must agree or `db:push` cannot find the table it
|
|
46
|
+
* just created. PostgreSQL therefore queries `current_schema()` rather than
|
|
47
|
+
* hard-coding `public`: with the usual `search_path = "$user", public`, a table
|
|
48
|
+
* created unqualified lands in the role's own schema, and looking only in `public`
|
|
49
|
+
* made every push re-issue `CREATE TABLE` and fail with "relation already exists".
|
|
50
|
+
*/
|
|
51
|
+
function defaultSchema(provider, schema) {
|
|
52
|
+
if (schema !== undefined)
|
|
53
|
+
return schema;
|
|
54
|
+
return provider === 'postgres' ? 'current_schema()' : '';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Where a table's existence is recorded.
|
|
58
|
+
*
|
|
59
|
+
* SQL Server needs `OBJECT_ID` because the query is by object, not by name; the
|
|
60
|
+
* others keep their metadata in a catalog view keyed by schema plus name.
|
|
61
|
+
*/
|
|
62
|
+
function buildTableExists(provider) {
|
|
63
|
+
return (raw) => {
|
|
64
|
+
const { schema, name } = splitQualified(raw);
|
|
65
|
+
switch (provider) {
|
|
66
|
+
case 'mssql':
|
|
67
|
+
return `SELECT name FROM sys.tables WHERE object_id = OBJECT_ID(${sqlLiteral(objectName(raw))})`;
|
|
68
|
+
case 'postgres':
|
|
69
|
+
return `SELECT tablename FROM pg_tables WHERE schemaname = ${schema ? sqlLiteral(schema) : defaultSchema(provider, undefined)} AND tablename = ${sqlLiteral(name)}`;
|
|
70
|
+
case 'mysql':
|
|
71
|
+
// An unqualified table belongs to the database the connection selected.
|
|
72
|
+
return (`SELECT table_name FROM information_schema.tables WHERE table_schema = ${schema ? sqlLiteral(schema) : 'DATABASE()'} ` +
|
|
73
|
+
`AND table_name = ${sqlLiteral(name)}`);
|
|
74
|
+
case 'sqlite':
|
|
75
|
+
return `SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${sqlLiteral(name)}`;
|
|
76
|
+
default:
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function buildColumnExists(provider) {
|
|
82
|
+
return (raw, column) => {
|
|
83
|
+
const { schema, name } = splitQualified(raw);
|
|
84
|
+
const columnLiteral = sqlLiteral(column);
|
|
85
|
+
switch (provider) {
|
|
86
|
+
case 'mssql':
|
|
87
|
+
return `SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(${sqlLiteral(objectName(raw))}) AND name = ${columnLiteral}`;
|
|
88
|
+
case 'postgres':
|
|
89
|
+
return (`SELECT column_name FROM information_schema.columns WHERE table_schema = ${schema ? sqlLiteral(schema) : defaultSchema(provider, undefined)} ` +
|
|
90
|
+
`AND table_name = ${sqlLiteral(name)} AND column_name = ${columnLiteral}`);
|
|
91
|
+
case 'mysql':
|
|
92
|
+
return (`SELECT column_name FROM information_schema.columns WHERE table_schema = ${schema ? sqlLiteral(schema) : 'DATABASE()'} ` +
|
|
93
|
+
`AND table_name = ${sqlLiteral(name)} AND column_name = ${columnLiteral}`);
|
|
94
|
+
case 'sqlite':
|
|
95
|
+
// A table-valued pragma, so this stays one round trip. Needs SQLite 3.16
|
|
96
|
+
// (2017) for `pragma_table_info` to be usable as a table function.
|
|
97
|
+
return `SELECT name FROM pragma_table_info(${sqlLiteral(name)}) WHERE name = ${columnLiteral}`;
|
|
98
|
+
default:
|
|
99
|
+
return '';
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function buildIndexExists(provider) {
|
|
104
|
+
return (raw, name) => {
|
|
105
|
+
const { schema, name: table } = splitQualified(raw);
|
|
106
|
+
const tableLiteral = sqlLiteral(table);
|
|
107
|
+
const indexLiteral = sqlLiteral(name);
|
|
108
|
+
const schemaClause = schema ? sqlLiteral(schema) : 'DATABASE()';
|
|
109
|
+
switch (provider) {
|
|
110
|
+
case 'mssql':
|
|
111
|
+
return `SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID(${sqlLiteral(objectName(raw))}) AND name = ${indexLiteral}`;
|
|
112
|
+
case 'postgres':
|
|
113
|
+
return (`SELECT indexname FROM pg_indexes WHERE schemaname = ${schema ? sqlLiteral(schema) : defaultSchema(provider, undefined)} ` +
|
|
114
|
+
`AND tablename = ${tableLiteral} AND indexname = ${indexLiteral}`);
|
|
115
|
+
case 'mysql':
|
|
116
|
+
return (`SELECT index_name FROM information_schema.statistics WHERE table_schema = ${schemaClause} ` +
|
|
117
|
+
`AND table_name = ${tableLiteral} AND index_name = ${indexLiteral} LIMIT 1`);
|
|
118
|
+
case 'sqlite':
|
|
119
|
+
return `SELECT name FROM sqlite_master WHERE type = 'index' AND tbl_name = ${tableLiteral} AND name = ${indexLiteral}`;
|
|
120
|
+
default:
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function buildUniqueConstraintExists(provider) {
|
|
126
|
+
return (raw, name) => {
|
|
127
|
+
const { schema, name: table } = splitQualified(raw);
|
|
128
|
+
const tableLiteral = sqlLiteral(table);
|
|
129
|
+
const constraintLiteral = sqlLiteral(name);
|
|
130
|
+
switch (provider) {
|
|
131
|
+
case 'mssql':
|
|
132
|
+
return `SELECT name FROM sys.objects WHERE type = 'UQ' AND parent_object_id = OBJECT_ID(${sqlLiteral(objectName(raw))}) AND name = ${constraintLiteral}`;
|
|
133
|
+
case 'postgres':
|
|
134
|
+
return (`SELECT con.conname FROM pg_constraint con ` +
|
|
135
|
+
`JOIN pg_class t ON t.oid = con.conrelid AND t.relname = ${tableLiteral} ` +
|
|
136
|
+
`JOIN pg_namespace n ON n.oid = t.relnamespace ` +
|
|
137
|
+
`WHERE con.contype = 'u' AND con.conname = ${constraintLiteral} ` +
|
|
138
|
+
`AND n.nspname = ${schema ? sqlLiteral(schema) : defaultSchema(provider, undefined)}`);
|
|
139
|
+
case 'mysql':
|
|
140
|
+
return (`SELECT constraint_name FROM information_schema.table_constraints ` +
|
|
141
|
+
`WHERE table_schema = ${schema ? sqlLiteral(schema) : 'DATABASE()'} AND table_name = ${tableLiteral} ` +
|
|
142
|
+
`AND constraint_name = ${constraintLiteral} AND constraint_type = 'UNIQUE'`);
|
|
143
|
+
case 'sqlite':
|
|
144
|
+
// No named constraints to look for; the unique index carries the name, so
|
|
145
|
+
// the index catalog answers for it.
|
|
146
|
+
return buildIndexExists(provider)(raw, name);
|
|
147
|
+
default:
|
|
148
|
+
return '';
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The keyword that makes a column auto-incrementing, or an empty string when the
|
|
154
|
+
* expression did not ask for one.
|
|
155
|
+
*
|
|
156
|
+
* SQLite is checked rather than passed through: it accepts AUTOINCREMENT only on
|
|
157
|
+
* an `INTEGER PRIMARY KEY`, so a schema asking for `@default(autoincrement())` on
|
|
158
|
+
* anything else has to hear about it here rather than from the engine.
|
|
159
|
+
*/
|
|
160
|
+
function identityKeyword(column, provider) {
|
|
161
|
+
if (column.defaultExpr?.trim() !== 'autoincrement()')
|
|
162
|
+
return '';
|
|
163
|
+
switch (provider) {
|
|
164
|
+
case 'mssql':
|
|
165
|
+
return 'IDENTITY(1,1)';
|
|
166
|
+
case 'postgres':
|
|
167
|
+
return 'GENERATED BY DEFAULT AS IDENTITY';
|
|
168
|
+
case 'mysql':
|
|
169
|
+
return 'AUTO_INCREMENT';
|
|
170
|
+
case 'sqlite': {
|
|
171
|
+
// The whole declared type, not the base name: `INTEGER(8)` is not an
|
|
172
|
+
// INTEGER PRIMARY KEY as far as SQLite is concerned, and letting it through
|
|
173
|
+
// would replace this message with the engine's.
|
|
174
|
+
const declared = column.sqlType.trim().toUpperCase();
|
|
175
|
+
if (!column.isId) {
|
|
176
|
+
throw new Error(`SQLite: @default(autoincrement()) on "${column.name}" needs @id — ` +
|
|
177
|
+
'SQLite only auto-increments an INTEGER PRIMARY KEY.');
|
|
178
|
+
}
|
|
179
|
+
if (declared !== 'INTEGER') {
|
|
180
|
+
throw new Error(`SQLite: @default(autoincrement()) on "${column.name}" needs the type INTEGER, ` +
|
|
181
|
+
`not ${column.sqlType} — SQLite only auto-increments an INTEGER PRIMARY KEY.`);
|
|
182
|
+
}
|
|
183
|
+
return 'AUTOINCREMENT';
|
|
184
|
+
}
|
|
185
|
+
default:
|
|
186
|
+
return '';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function createDialect(provider, quote) {
|
|
190
|
+
const supportsUniqueInlineOnAddColumn = provider !== 'sqlite';
|
|
191
|
+
const quoteTable = (raw) => {
|
|
192
|
+
const { schema, name } = splitQualified(raw);
|
|
193
|
+
return schema ? `${quote(schema)}.${quote(name)}` : quote(name);
|
|
194
|
+
};
|
|
195
|
+
const list = (fields) => fields.join(', ');
|
|
196
|
+
// Named rather than a method so `addColumn` keeps working if the dialect is
|
|
197
|
+
// destructured by a caller.
|
|
198
|
+
const columnDefinition = (column) => {
|
|
199
|
+
const identity = identityKeyword(column, provider);
|
|
200
|
+
// Where the identity keyword goes is not a detail: SQL Server takes it as part
|
|
201
|
+
// of the column type (`INT IDENTITY(1,1)`), while SQLite only accepts it after
|
|
202
|
+
// `PRIMARY KEY` and only spells the documented form `INTEGER PRIMARY KEY
|
|
203
|
+
// AUTOINCREMENT`.
|
|
204
|
+
const type = identity && provider !== 'sqlite'
|
|
205
|
+
? `${quote(column.name)} ${column.sqlType} ${identity}`
|
|
206
|
+
: `${quote(column.name)} ${column.sqlType}`;
|
|
207
|
+
const nullable = column.isOptional ? '' : ' NOT NULL';
|
|
208
|
+
const unique = column.isUnique && !column.isId ? ' UNIQUE' : '';
|
|
209
|
+
const defaultSql = defaultClause(column.defaultExpr, provider);
|
|
210
|
+
const defaultPart = defaultSql ? ` ${defaultSql}` : '';
|
|
211
|
+
if (column.isId) {
|
|
212
|
+
const key = `${type} PRIMARY KEY`;
|
|
213
|
+
return `${key}${identity && provider === 'sqlite' ? ` ${identity}` : ''}${defaultPart}`;
|
|
214
|
+
}
|
|
215
|
+
return `${type}${nullable}${defaultPart}${unique}`;
|
|
216
|
+
};
|
|
217
|
+
return {
|
|
218
|
+
provider,
|
|
219
|
+
supportsDdl: true,
|
|
220
|
+
quote,
|
|
221
|
+
quoteTable,
|
|
222
|
+
supportsNamedUniqueConstraint: provider !== 'sqlite',
|
|
223
|
+
supportsUniqueInlineOnAddColumn,
|
|
224
|
+
tableExists: buildTableExists(provider),
|
|
225
|
+
columnExists: buildColumnExists(provider),
|
|
226
|
+
uniqueConstraintExists: buildUniqueConstraintExists(provider),
|
|
227
|
+
indexExists: buildIndexExists(provider),
|
|
228
|
+
columnDefinition,
|
|
229
|
+
createTable: (table, columnDefs) => `CREATE TABLE ${table} (\n ${columnDefs.join(',\n ')}\n)`,
|
|
230
|
+
createIndex: (name, table, fields) => `CREATE INDEX ${name} ON ${table} (${list(fields)})`,
|
|
231
|
+
createUniqueIndex: (name, table, fields) => `CREATE UNIQUE INDEX ${name} ON ${table} (${list(fields)})`,
|
|
232
|
+
addColumn: (table, column) => {
|
|
233
|
+
// SQLite refuses "Cannot add a UNIQUE column", so the unique is left out here
|
|
234
|
+
// and added as a separate index by the caller — silently dropping it instead
|
|
235
|
+
// would push a column that is not unique after all.
|
|
236
|
+
const withoutUnique = supportsUniqueInlineOnAddColumn
|
|
237
|
+
? column
|
|
238
|
+
: { ...column, isUnique: false };
|
|
239
|
+
return `ALTER TABLE ${table} ADD ${columnDefinition(withoutUnique)}`;
|
|
240
|
+
},
|
|
241
|
+
addUniqueConstraint: (name, table, fields) => `ALTER TABLE ${table} ADD CONSTRAINT ${name} UNIQUE (${list(fields)})`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Google Sheets has no tables and therefore no DDL: a sheet is a range of cells the
|
|
246
|
+
* adapter reads and writes. Every builder is inert and `supportsDdl` is false, so
|
|
247
|
+
* the caller explains that instead of sending SQL to a database that cannot run it.
|
|
248
|
+
*/
|
|
249
|
+
const SHEETS_DIALECT = {
|
|
250
|
+
provider: 'googlesheets',
|
|
251
|
+
supportsDdl: false,
|
|
252
|
+
quote: (name) => name,
|
|
253
|
+
quoteTable: (raw) => objectName(raw),
|
|
254
|
+
supportsNamedUniqueConstraint: false,
|
|
255
|
+
supportsUniqueInlineOnAddColumn: false,
|
|
256
|
+
tableExists: () => '',
|
|
257
|
+
columnExists: () => '',
|
|
258
|
+
uniqueConstraintExists: () => '',
|
|
259
|
+
indexExists: () => '',
|
|
260
|
+
columnDefinition: () => '',
|
|
261
|
+
createTable: () => '',
|
|
262
|
+
createIndex: () => '',
|
|
263
|
+
createUniqueIndex: () => '',
|
|
264
|
+
addColumn: () => '',
|
|
265
|
+
addUniqueConstraint: () => '',
|
|
266
|
+
};
|
|
267
|
+
/** The dialect that writes DDL for a provider. */
|
|
268
|
+
function dialectFor(provider) {
|
|
269
|
+
switch (provider) {
|
|
270
|
+
case 'postgres':
|
|
271
|
+
return createDialect(provider, doubleQuote);
|
|
272
|
+
case 'mysql':
|
|
273
|
+
return createDialect(provider, backtickQuote);
|
|
274
|
+
case 'sqlite':
|
|
275
|
+
return createDialect(provider, bracketQuote);
|
|
276
|
+
case 'googlesheets':
|
|
277
|
+
return SHEETS_DIALECT;
|
|
278
|
+
case 'mssql':
|
|
279
|
+
default:
|
|
280
|
+
return createDialect(provider, bracketQuote);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Renders a `@default(...)` expression as the SQL that follows the column type.
|
|
285
|
+
*
|
|
286
|
+
* Returns an empty string when the provider has no equivalent — SQLite has no
|
|
287
|
+
* default functions, so `uuid()` is left to the adapter, which fills a string
|
|
288
|
+
* primary key in before inserting.
|
|
289
|
+
*/
|
|
290
|
+
function defaultClause(expression, provider) {
|
|
291
|
+
const value = (expression ?? '').trim();
|
|
292
|
+
switch (value) {
|
|
293
|
+
case '':
|
|
294
|
+
case 'autoincrement()':
|
|
295
|
+
// Not a default value: it is the identity clause on the column type.
|
|
296
|
+
return '';
|
|
297
|
+
case 'uuid()':
|
|
298
|
+
case 'cuid()':
|
|
299
|
+
if (provider === 'mssql')
|
|
300
|
+
return 'DEFAULT NEWID()';
|
|
301
|
+
if (provider === 'postgres')
|
|
302
|
+
return 'DEFAULT gen_random_uuid()';
|
|
303
|
+
if (provider === 'mysql')
|
|
304
|
+
return 'DEFAULT (UUID())';
|
|
305
|
+
return '';
|
|
306
|
+
case 'now()':
|
|
307
|
+
return 'DEFAULT CURRENT_TIMESTAMP';
|
|
308
|
+
case 'true':
|
|
309
|
+
// PostgreSQL has a real boolean, so use it rather than 1/0.
|
|
310
|
+
return provider === 'postgres' ? 'DEFAULT TRUE' : 'DEFAULT 1';
|
|
311
|
+
case 'false':
|
|
312
|
+
return provider === 'postgres' ? 'DEFAULT FALSE' : 'DEFAULT 0';
|
|
313
|
+
default:
|
|
314
|
+
if (/^".*"$/.test(value))
|
|
315
|
+
return `DEFAULT '${value.slice(1, -1).replace(/'/g, "''")}'`;
|
|
316
|
+
return `DEFAULT ${value}`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Model } from './types';
|
|
2
2
|
export declare class DotnetGenerator {
|
|
3
3
|
private outputDir;
|
|
4
|
+
/** The database being generated for; decides types like `TIMESTAMP`. */
|
|
5
|
+
private provider;
|
|
4
6
|
constructor(outputDir: string);
|
|
5
7
|
generate(models: Model[]): void;
|
|
6
8
|
private getCsFilterType;
|
|
7
9
|
private generateOrmTypes;
|
|
8
10
|
private generateConfigClass;
|
|
11
|
+
/**
|
|
12
|
+
* The C# type for a field.
|
|
13
|
+
*
|
|
14
|
+
* Driven by the declared type, so a `DECIMAL` column is a `decimal` and a `FLOAT`
|
|
15
|
+
* one a `double`: both arrived as `number` and took the `int` branch.
|
|
16
|
+
*/
|
|
9
17
|
private mapType;
|
|
10
18
|
private generateEntityClass;
|
|
11
19
|
private generateDbContext;
|