@syncular/typegen 0.0.1-60
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/dist/generate.d.ts +21 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +86 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect-postgres.d.ts +8 -0
- package/dist/introspect-postgres.d.ts.map +1 -0
- package/dist/introspect-postgres.js +92 -0
- package/dist/introspect-postgres.js.map +1 -0
- package/dist/introspect-sqlite.d.ts +10 -0
- package/dist/introspect-sqlite.d.ts.map +1 -0
- package/dist/introspect-sqlite.js +88 -0
- package/dist/introspect-sqlite.js.map +1 -0
- package/dist/introspect.d.ts +8 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.js +18 -0
- package/dist/introspect.js.map +1 -0
- package/dist/map-types.d.ts +20 -0
- package/dist/map-types.d.ts.map +1 -0
- package/dist/map-types.js +154 -0
- package/dist/map-types.js.map +1 -0
- package/dist/render.d.ts +25 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +140 -0
- package/dist/render.js.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
- package/src/generate.ts +127 -0
- package/src/index.ts +14 -0
- package/src/introspect-postgres.ts +149 -0
- package/src/introspect-sqlite.ts +142 -0
- package/src/introspect.ts +36 -0
- package/src/map-types.ts +192 -0
- package/src/render.ts +195 -0
- package/src/types.ts +94 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Type generation entry point
|
|
3
|
+
*/
|
|
4
|
+
import type { GenerateTypesOptions, GenerateTypesResult } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Generate TypeScript types from migrations.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { generateTypes } from '@syncular/typegen';
|
|
11
|
+
* import { migrations } from './migrations';
|
|
12
|
+
*
|
|
13
|
+
* await generateTypes({
|
|
14
|
+
* migrations,
|
|
15
|
+
* output: './src/db.generated.ts',
|
|
16
|
+
* extendsSyncClientDb: true,
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateTypes<DB>(options: GenerateTypesOptions<DB>): Promise<GenerateTypesResult>;
|
|
21
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EAIpB,MAAM,SAAS,CAAC;AA6CjB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CAAC,EAAE,EACpC,OAAO,EAAE,oBAAoB,CAAC,EAAE,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAiD9B"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Type generation entry point
|
|
3
|
+
*/
|
|
4
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { dirname } from 'node:path';
|
|
6
|
+
import { introspectAllVersions, introspectCurrentSchema } from './introspect';
|
|
7
|
+
import { resolveColumnType } from './map-types';
|
|
8
|
+
import { renderTypes } from './render';
|
|
9
|
+
/**
|
|
10
|
+
* Apply type mapping to all columns in the schemas.
|
|
11
|
+
* Returns the schemas with tsType filled in and any custom imports collected.
|
|
12
|
+
*/
|
|
13
|
+
function applyTypeMappings(schemas, dialect, resolveType) {
|
|
14
|
+
const allImports = [];
|
|
15
|
+
const mapped = schemas.map((schema) => ({
|
|
16
|
+
...schema,
|
|
17
|
+
tables: schema.tables.map((table) => ({
|
|
18
|
+
...table,
|
|
19
|
+
columns: table.columns.map((col) => {
|
|
20
|
+
const resolved = resolveColumnType({
|
|
21
|
+
table: table.name,
|
|
22
|
+
column: col.name,
|
|
23
|
+
sqlType: col.sqlType,
|
|
24
|
+
nullable: col.nullable,
|
|
25
|
+
isPrimaryKey: col.isPrimaryKey,
|
|
26
|
+
hasDefault: col.hasDefault,
|
|
27
|
+
dialect,
|
|
28
|
+
}, resolveType);
|
|
29
|
+
allImports.push(...resolved.imports);
|
|
30
|
+
return {
|
|
31
|
+
...col,
|
|
32
|
+
tsType: resolved.tsType,
|
|
33
|
+
};
|
|
34
|
+
}),
|
|
35
|
+
})),
|
|
36
|
+
}));
|
|
37
|
+
return { schemas: mapped, customImports: allImports };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate TypeScript types from migrations.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import { generateTypes } from '@syncular/typegen';
|
|
45
|
+
* import { migrations } from './migrations';
|
|
46
|
+
*
|
|
47
|
+
* await generateTypes({
|
|
48
|
+
* migrations,
|
|
49
|
+
* output: './src/db.generated.ts',
|
|
50
|
+
* extendsSyncClientDb: true,
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export async function generateTypes(options) {
|
|
55
|
+
const { migrations, output, extendsSyncClientDb, includeVersionHistory, tables, dialect = 'sqlite', resolveType, } = options;
|
|
56
|
+
// Introspect schemas (raw SQL types, no TS mapping yet)
|
|
57
|
+
let rawSchemas;
|
|
58
|
+
if (includeVersionHistory) {
|
|
59
|
+
rawSchemas = await introspectAllVersions(migrations, dialect, tables);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const current = await introspectCurrentSchema(migrations, dialect, tables);
|
|
63
|
+
rawSchemas = [current];
|
|
64
|
+
}
|
|
65
|
+
// Apply type mapping (default + user resolver)
|
|
66
|
+
const { schemas, customImports } = applyTypeMappings(rawSchemas, dialect, resolveType);
|
|
67
|
+
// Render TypeScript code
|
|
68
|
+
const code = renderTypes({
|
|
69
|
+
schemas,
|
|
70
|
+
extendsSyncClientDb,
|
|
71
|
+
includeVersionHistory,
|
|
72
|
+
customImports,
|
|
73
|
+
});
|
|
74
|
+
// Ensure output directory exists
|
|
75
|
+
await mkdir(dirname(output), { recursive: true });
|
|
76
|
+
// Write the file
|
|
77
|
+
await writeFile(output, code, 'utf-8');
|
|
78
|
+
const latestSchema = schemas[schemas.length - 1];
|
|
79
|
+
return {
|
|
80
|
+
outputPath: output,
|
|
81
|
+
currentVersion: migrations.currentVersion,
|
|
82
|
+
tableCount: latestSchema?.tables.length ?? 0,
|
|
83
|
+
code,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Generate TypeScript types from migrations
|
|
3
|
+
*
|
|
4
|
+
* Creates type definitions by:
|
|
5
|
+
* 1. Applying migrations to an in-memory database (SQLite or PostgreSQL)
|
|
6
|
+
* 2. Introspecting the resulting schema
|
|
7
|
+
* 3. Generating TypeScript interfaces
|
|
8
|
+
*/
|
|
9
|
+
export * from './generate';
|
|
10
|
+
export * from './introspect';
|
|
11
|
+
export * from './map-types';
|
|
12
|
+
export * from './render';
|
|
13
|
+
export * from './types';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Generate TypeScript types from migrations
|
|
3
|
+
*
|
|
4
|
+
* Creates type definitions by:
|
|
5
|
+
* 1. Applying migrations to an in-memory database (SQLite or PostgreSQL)
|
|
6
|
+
* 2. Introspecting the resulting schema
|
|
7
|
+
* 3. Generating TypeScript interfaces
|
|
8
|
+
*/
|
|
9
|
+
export * from './generate';
|
|
10
|
+
export * from './introspect';
|
|
11
|
+
export * from './map-types';
|
|
12
|
+
export * from './render';
|
|
13
|
+
export * from './types';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - PostgreSQL schema introspection via PGlite
|
|
3
|
+
*/
|
|
4
|
+
import type { DefinedMigrations } from '@syncular/migrations';
|
|
5
|
+
import type { VersionedSchema } from './types';
|
|
6
|
+
export declare function introspectPostgresAllVersions<DB = unknown>(migrations: DefinedMigrations<DB>, filterTables?: string[]): Promise<VersionedSchema[]>;
|
|
7
|
+
export declare function introspectPostgresCurrentSchema<DB = unknown>(migrations: DefinedMigrations<DB>, filterTables?: string[]): Promise<VersionedSchema>;
|
|
8
|
+
//# sourceMappingURL=introspect-postgres.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-postgres.d.ts","sourceRoot":"","sources":["../src/introspect-postgres.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,SAAS,CAAC;AAiH5D,wBAAsB,6BAA6B,CAAC,EAAE,GAAG,OAAO,EAC9D,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAa5B;AAED,wBAAsB,+BAA+B,CAAC,EAAE,GAAG,OAAO,EAChE,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,CAAC,CAM1B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - PostgreSQL schema introspection via PGlite
|
|
3
|
+
*/
|
|
4
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
5
|
+
import { Kysely } from 'kysely';
|
|
6
|
+
import { PGliteDialect } from 'kysely-pglite-dialect';
|
|
7
|
+
async function introspectPg(pglite) {
|
|
8
|
+
const colResult = await pglite.query(`SELECT table_name, column_name, data_type, udt_name,
|
|
9
|
+
is_nullable, column_default, ordinal_position
|
|
10
|
+
FROM information_schema.columns
|
|
11
|
+
WHERE table_schema = 'public'
|
|
12
|
+
ORDER BY table_name, ordinal_position`);
|
|
13
|
+
const pkResult = await pglite.query(`SELECT kcu.column_name, tc.table_name
|
|
14
|
+
FROM information_schema.table_constraints tc
|
|
15
|
+
JOIN information_schema.key_column_usage kcu
|
|
16
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
17
|
+
AND tc.table_schema = kcu.table_schema
|
|
18
|
+
WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = 'public'`);
|
|
19
|
+
const pkSet = new Set(pkResult.rows.map((r) => `${r.table_name}.${r.column_name}`));
|
|
20
|
+
const tableMap = new Map();
|
|
21
|
+
for (const col of colResult.rows) {
|
|
22
|
+
let table = tableMap.get(col.table_name);
|
|
23
|
+
if (!table) {
|
|
24
|
+
table = { name: col.table_name, columns: [] };
|
|
25
|
+
tableMap.set(col.table_name, table);
|
|
26
|
+
}
|
|
27
|
+
const isPrimaryKey = pkSet.has(`${col.table_name}.${col.column_name}`);
|
|
28
|
+
const nullable = col.is_nullable === 'YES' && !isPrimaryKey;
|
|
29
|
+
const hasDefault = col.column_default !== null;
|
|
30
|
+
// Use udt_name for more precise type info (e.g. int4 instead of "integer")
|
|
31
|
+
// For arrays, data_type is "ARRAY" and udt_name starts with "_"
|
|
32
|
+
let sqlType;
|
|
33
|
+
if (col.data_type === 'ARRAY' && col.udt_name.startsWith('_')) {
|
|
34
|
+
// Convert _int4 → int4[], _text → text[], etc.
|
|
35
|
+
sqlType = `${col.udt_name.slice(1)}[]`;
|
|
36
|
+
}
|
|
37
|
+
else if (col.data_type === 'USER-DEFINED') {
|
|
38
|
+
sqlType = col.udt_name;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
sqlType = col.udt_name;
|
|
42
|
+
}
|
|
43
|
+
table.columns.push({
|
|
44
|
+
name: col.column_name,
|
|
45
|
+
sqlType,
|
|
46
|
+
tsType: '', // resolved later by map-types
|
|
47
|
+
nullable,
|
|
48
|
+
isPrimaryKey,
|
|
49
|
+
hasDefault,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Sort tables by name for deterministic output
|
|
53
|
+
return [...tableMap.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
54
|
+
}
|
|
55
|
+
async function introspectAtVersion(migrations, targetVersion, filterTables) {
|
|
56
|
+
const pglite = await PGlite.create();
|
|
57
|
+
try {
|
|
58
|
+
const db = new Kysely({
|
|
59
|
+
dialect: new PGliteDialect(pglite),
|
|
60
|
+
});
|
|
61
|
+
for (const migration of migrations.migrations) {
|
|
62
|
+
if (migration.version > targetVersion)
|
|
63
|
+
break;
|
|
64
|
+
await migration.fn(db);
|
|
65
|
+
}
|
|
66
|
+
await db.destroy();
|
|
67
|
+
let tables = await introspectPg(pglite);
|
|
68
|
+
if (filterTables && filterTables.length > 0) {
|
|
69
|
+
const filterSet = new Set(filterTables);
|
|
70
|
+
tables = tables.filter((t) => filterSet.has(t.name));
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
version: targetVersion,
|
|
74
|
+
tables,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
await pglite.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export async function introspectPostgresAllVersions(migrations, filterTables) {
|
|
82
|
+
const schemas = [];
|
|
83
|
+
for (const migration of migrations.migrations) {
|
|
84
|
+
const schema = await introspectAtVersion(migrations, migration.version, filterTables);
|
|
85
|
+
schemas.push(schema);
|
|
86
|
+
}
|
|
87
|
+
return schemas;
|
|
88
|
+
}
|
|
89
|
+
export async function introspectPostgresCurrentSchema(migrations, filterTables) {
|
|
90
|
+
return introspectAtVersion(migrations, migrations.currentVersion, filterTables);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=introspect-postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-postgres.js","sourceRoot":"","sources":["../src/introspect-postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - SQLite schema introspection
|
|
3
|
+
*
|
|
4
|
+
* Works with both better-sqlite3 (Node.js) and bun:sqlite (Bun runtime).
|
|
5
|
+
*/
|
|
6
|
+
import type { DefinedMigrations } from '@syncular/migrations';
|
|
7
|
+
import type { VersionedSchema } from './types';
|
|
8
|
+
export declare function introspectSqliteAllVersions<DB = unknown>(migrations: DefinedMigrations<DB>, filterTables?: string[]): Promise<VersionedSchema[]>;
|
|
9
|
+
export declare function introspectSqliteCurrentSchema<DB = unknown>(migrations: DefinedMigrations<DB>, filterTables?: string[]): Promise<VersionedSchema>;
|
|
10
|
+
//# sourceMappingURL=introspect-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-sqlite.d.ts","sourceRoot":"","sources":["../src/introspect-sqlite.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,SAAS,CAAC;AA0G5D,wBAAsB,2BAA2B,CAAC,EAAE,GAAG,OAAO,EAC5D,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAa5B;AAED,wBAAsB,6BAA6B,CAAC,EAAE,GAAG,OAAO,EAC9D,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,CAAC,CAM1B"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - SQLite schema introspection
|
|
3
|
+
*
|
|
4
|
+
* Works with both better-sqlite3 (Node.js) and bun:sqlite (Bun runtime).
|
|
5
|
+
*/
|
|
6
|
+
import { Kysely, SqliteDialect } from 'kysely';
|
|
7
|
+
const isBun = typeof globalThis.Bun !== 'undefined';
|
|
8
|
+
async function createSqliteDb() {
|
|
9
|
+
if (isBun) {
|
|
10
|
+
const { Database } = await import('bun:sqlite');
|
|
11
|
+
return new Database(':memory:');
|
|
12
|
+
}
|
|
13
|
+
const { default: Database } = await import('better-sqlite3');
|
|
14
|
+
return new Database(':memory:');
|
|
15
|
+
}
|
|
16
|
+
function createKysely(sqliteDb) {
|
|
17
|
+
return new Kysely({
|
|
18
|
+
dialect: new SqliteDialect({
|
|
19
|
+
database: sqliteDb,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function introspectTable(sqliteDb, tableName) {
|
|
24
|
+
const columns = sqliteDb
|
|
25
|
+
.prepare(`PRAGMA table_info("${tableName}")`)
|
|
26
|
+
.all();
|
|
27
|
+
return {
|
|
28
|
+
name: tableName,
|
|
29
|
+
columns: columns.map((col) => {
|
|
30
|
+
const nullable = col.notnull === 0 && col.pk === 0;
|
|
31
|
+
const hasDefault = col.dflt_value !== null;
|
|
32
|
+
return {
|
|
33
|
+
name: col.name,
|
|
34
|
+
sqlType: col.type,
|
|
35
|
+
tsType: '', // resolved later by map-types
|
|
36
|
+
nullable,
|
|
37
|
+
isPrimaryKey: col.pk === 1,
|
|
38
|
+
hasDefault,
|
|
39
|
+
};
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function getAllTables(sqliteDb) {
|
|
44
|
+
const rows = sqliteDb
|
|
45
|
+
.prepare(`SELECT name FROM sqlite_master
|
|
46
|
+
WHERE type='table'
|
|
47
|
+
AND name NOT LIKE 'sqlite_%'
|
|
48
|
+
ORDER BY name`)
|
|
49
|
+
.all();
|
|
50
|
+
return rows.map((r) => r.name);
|
|
51
|
+
}
|
|
52
|
+
async function introspectAtVersion(migrations, targetVersion, filterTables) {
|
|
53
|
+
const sqliteDb = await createSqliteDb();
|
|
54
|
+
try {
|
|
55
|
+
const db = createKysely(sqliteDb);
|
|
56
|
+
for (const migration of migrations.migrations) {
|
|
57
|
+
if (migration.version > targetVersion)
|
|
58
|
+
break;
|
|
59
|
+
await migration.fn(db);
|
|
60
|
+
}
|
|
61
|
+
let tableNames = getAllTables(sqliteDb);
|
|
62
|
+
if (filterTables && filterTables.length > 0) {
|
|
63
|
+
const filterSet = new Set(filterTables);
|
|
64
|
+
tableNames = tableNames.filter((t) => filterSet.has(t));
|
|
65
|
+
}
|
|
66
|
+
const tables = tableNames.map((name) => introspectTable(sqliteDb, name));
|
|
67
|
+
await db.destroy();
|
|
68
|
+
return {
|
|
69
|
+
version: targetVersion,
|
|
70
|
+
tables,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
sqliteDb.close();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function introspectSqliteAllVersions(migrations, filterTables) {
|
|
78
|
+
const schemas = [];
|
|
79
|
+
for (const migration of migrations.migrations) {
|
|
80
|
+
const schema = await introspectAtVersion(migrations, migration.version, filterTables);
|
|
81
|
+
schemas.push(schema);
|
|
82
|
+
}
|
|
83
|
+
return schemas;
|
|
84
|
+
}
|
|
85
|
+
export async function introspectSqliteCurrentSchema(migrations, filterTables) {
|
|
86
|
+
return introspectAtVersion(migrations, migrations.currentVersion, filterTables);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=introspect-sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-sqlite.js","sourceRoot":"","sources":["../src/introspect-sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Schema introspection dispatcher
|
|
3
|
+
*/
|
|
4
|
+
import type { DefinedMigrations } from '@syncular/migrations';
|
|
5
|
+
import type { TypegenDialect, VersionedSchema } from './types';
|
|
6
|
+
export declare function introspectAllVersions<DB = unknown>(migrations: DefinedMigrations<DB>, dialect: TypegenDialect, filterTables?: string[]): Promise<VersionedSchema[]>;
|
|
7
|
+
export declare function introspectCurrentSchema<DB = unknown>(migrations: DefinedMigrations<DB>, dialect: TypegenDialect, filterTables?: string[]): Promise<VersionedSchema>;
|
|
8
|
+
//# sourceMappingURL=introspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAS9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/D,wBAAsB,qBAAqB,CAAC,EAAE,GAAG,OAAO,EACtD,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,OAAO,EAAE,cAAc,EACvB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAK5B;AAED,wBAAsB,uBAAuB,CAAC,EAAE,GAAG,OAAO,EACxD,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,EACjC,OAAO,EAAE,cAAc,EACvB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,eAAe,CAAC,CAK1B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Schema introspection dispatcher
|
|
3
|
+
*/
|
|
4
|
+
import { introspectPostgresAllVersions, introspectPostgresCurrentSchema, } from './introspect-postgres';
|
|
5
|
+
import { introspectSqliteAllVersions, introspectSqliteCurrentSchema, } from './introspect-sqlite';
|
|
6
|
+
export async function introspectAllVersions(migrations, dialect, filterTables) {
|
|
7
|
+
if (dialect === 'postgres') {
|
|
8
|
+
return introspectPostgresAllVersions(migrations, filterTables);
|
|
9
|
+
}
|
|
10
|
+
return introspectSqliteAllVersions(migrations, filterTables);
|
|
11
|
+
}
|
|
12
|
+
export async function introspectCurrentSchema(migrations, dialect, filterTables) {
|
|
13
|
+
if (dialect === 'postgres') {
|
|
14
|
+
return introspectPostgresCurrentSchema(migrations, filterTables);
|
|
15
|
+
}
|
|
16
|
+
return introspectSqliteCurrentSchema(migrations, filterTables);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=introspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.js","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAG7B,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAiC,EACjC,OAAuB,EACvB,YAAuB,EACK;IAC5B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,6BAA6B,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,2BAA2B,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AAAA,CAC9D;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,UAAiC,EACjC,OAAuB,EACvB,YAAuB,EACG;IAC1B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,+BAA+B,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,6BAA6B,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AAAA,CAChE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Type mapping
|
|
3
|
+
*
|
|
4
|
+
* Maps SQL types to TypeScript types for each dialect,
|
|
5
|
+
* with support for user-provided resolver overrides.
|
|
6
|
+
*/
|
|
7
|
+
import type { ColumnInfo, ResolveTypeFn } from './types';
|
|
8
|
+
export interface ResolvedType {
|
|
9
|
+
tsType: string;
|
|
10
|
+
imports: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
from: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the TypeScript type for a column, applying the user resolver first
|
|
17
|
+
* and falling back to the default dialect mapping.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveColumnType(col: ColumnInfo, userResolver?: ResolveTypeFn): ResolvedType;
|
|
20
|
+
//# sourceMappingURL=map-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map-types.d.ts","sourceRoot":"","sources":["../src/map-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAkB,MAAM,SAAS,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AA4ID;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,UAAU,EACf,YAAY,CAAC,EAAE,aAAa,GAC3B,YAAY,CAgCd"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - Type mapping
|
|
3
|
+
*
|
|
4
|
+
* Maps SQL types to TypeScript types for each dialect,
|
|
5
|
+
* with support for user-provided resolver overrides.
|
|
6
|
+
*/
|
|
7
|
+
function mapSqliteType(sqlType) {
|
|
8
|
+
const upper = sqlType.toUpperCase();
|
|
9
|
+
if (upper.includes('INT'))
|
|
10
|
+
return 'number';
|
|
11
|
+
if (upper.includes('REAL') ||
|
|
12
|
+
upper.includes('FLOAT') ||
|
|
13
|
+
upper.includes('DOUBLE'))
|
|
14
|
+
return 'number';
|
|
15
|
+
if (upper.includes('BLOB'))
|
|
16
|
+
return 'Uint8Array';
|
|
17
|
+
if (upper.includes('BOOL'))
|
|
18
|
+
return 'number';
|
|
19
|
+
// TEXT, VARCHAR, CHAR, etc.
|
|
20
|
+
return 'string';
|
|
21
|
+
}
|
|
22
|
+
function mapPostgresType(sqlType) {
|
|
23
|
+
const lower = sqlType.toLowerCase().replace(/\s+/g, ' ').trim();
|
|
24
|
+
// Array types — strip trailing [] and map the element type
|
|
25
|
+
if (lower.endsWith('[]')) {
|
|
26
|
+
const element = mapPostgresType(lower.slice(0, -2));
|
|
27
|
+
return `${element}[]`;
|
|
28
|
+
}
|
|
29
|
+
// Integer types
|
|
30
|
+
if (lower === 'int2' ||
|
|
31
|
+
lower === 'int4' ||
|
|
32
|
+
lower === 'integer' ||
|
|
33
|
+
lower === 'smallint' ||
|
|
34
|
+
lower === 'serial')
|
|
35
|
+
return 'number';
|
|
36
|
+
// 64-bit integers — not safe in JS
|
|
37
|
+
if (lower === 'int8' || lower === 'bigint' || lower === 'bigserial')
|
|
38
|
+
return 'string';
|
|
39
|
+
// Floating-point / numeric
|
|
40
|
+
if (lower === 'float4' ||
|
|
41
|
+
lower === 'float8' ||
|
|
42
|
+
lower === 'real' ||
|
|
43
|
+
lower === 'double precision' ||
|
|
44
|
+
lower === 'numeric' ||
|
|
45
|
+
lower === 'decimal')
|
|
46
|
+
return 'number';
|
|
47
|
+
// Boolean
|
|
48
|
+
if (lower === 'bool' || lower === 'boolean')
|
|
49
|
+
return 'boolean';
|
|
50
|
+
// JSON
|
|
51
|
+
if (lower === 'json' || lower === 'jsonb')
|
|
52
|
+
return 'unknown';
|
|
53
|
+
// Date/time
|
|
54
|
+
if (lower === 'timestamp' ||
|
|
55
|
+
lower === 'timestamptz' ||
|
|
56
|
+
lower === 'timestamp with time zone' ||
|
|
57
|
+
lower === 'timestamp without time zone' ||
|
|
58
|
+
lower === 'date' ||
|
|
59
|
+
lower === 'time' ||
|
|
60
|
+
lower === 'timetz' ||
|
|
61
|
+
lower === 'time with time zone' ||
|
|
62
|
+
lower === 'time without time zone')
|
|
63
|
+
return 'string';
|
|
64
|
+
// Binary
|
|
65
|
+
if (lower === 'bytea')
|
|
66
|
+
return 'Uint8Array';
|
|
67
|
+
// Text types
|
|
68
|
+
if (lower === 'uuid' ||
|
|
69
|
+
lower === 'text' ||
|
|
70
|
+
lower === 'varchar' ||
|
|
71
|
+
lower === 'char' ||
|
|
72
|
+
lower === 'citext' ||
|
|
73
|
+
lower.startsWith('character varying') ||
|
|
74
|
+
lower.startsWith('character(') ||
|
|
75
|
+
lower.startsWith('varchar(') ||
|
|
76
|
+
lower.startsWith('char('))
|
|
77
|
+
return 'string';
|
|
78
|
+
// Interval
|
|
79
|
+
if (lower === 'interval')
|
|
80
|
+
return 'string';
|
|
81
|
+
// Network types
|
|
82
|
+
if (lower === 'inet' || lower === 'cidr' || lower === 'macaddr')
|
|
83
|
+
return 'string';
|
|
84
|
+
// Geometric types
|
|
85
|
+
if (lower === 'point' ||
|
|
86
|
+
lower === 'line' ||
|
|
87
|
+
lower === 'box' ||
|
|
88
|
+
lower === 'path' ||
|
|
89
|
+
lower === 'polygon' ||
|
|
90
|
+
lower === 'circle' ||
|
|
91
|
+
lower === 'lseg')
|
|
92
|
+
return 'string';
|
|
93
|
+
// Range types
|
|
94
|
+
if (lower === 'int4range' ||
|
|
95
|
+
lower === 'int8range' ||
|
|
96
|
+
lower === 'tsrange' ||
|
|
97
|
+
lower === 'tstzrange' ||
|
|
98
|
+
lower === 'daterange' ||
|
|
99
|
+
lower === 'numrange')
|
|
100
|
+
return 'string';
|
|
101
|
+
// Full-text search
|
|
102
|
+
if (lower === 'tsvector' || lower === 'tsquery')
|
|
103
|
+
return 'string';
|
|
104
|
+
// Other
|
|
105
|
+
if (lower === 'xml')
|
|
106
|
+
return 'string';
|
|
107
|
+
if (lower === 'money')
|
|
108
|
+
return 'string';
|
|
109
|
+
if (lower === 'bit' ||
|
|
110
|
+
lower === 'varbit' ||
|
|
111
|
+
lower.startsWith('bit(') ||
|
|
112
|
+
lower.startsWith('bit varying'))
|
|
113
|
+
return 'string';
|
|
114
|
+
return 'string';
|
|
115
|
+
}
|
|
116
|
+
function defaultMapper(dialect) {
|
|
117
|
+
return dialect === 'postgres' ? mapPostgresType : mapSqliteType;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the TypeScript type for a column, applying the user resolver first
|
|
121
|
+
* and falling back to the default dialect mapping.
|
|
122
|
+
*/
|
|
123
|
+
export function resolveColumnType(col, userResolver) {
|
|
124
|
+
const imports = [];
|
|
125
|
+
// Try user resolver first
|
|
126
|
+
if (userResolver) {
|
|
127
|
+
const override = userResolver(col);
|
|
128
|
+
if (override !== undefined) {
|
|
129
|
+
if (typeof override === 'string') {
|
|
130
|
+
const baseType = override;
|
|
131
|
+
return {
|
|
132
|
+
tsType: col.nullable ? `${baseType} | null` : baseType,
|
|
133
|
+
imports,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (override.import) {
|
|
137
|
+
imports.push(override.import);
|
|
138
|
+
}
|
|
139
|
+
const baseType = override.type;
|
|
140
|
+
return {
|
|
141
|
+
tsType: col.nullable ? `${baseType} | null` : baseType,
|
|
142
|
+
imports,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Default mapping
|
|
147
|
+
const mapper = defaultMapper(col.dialect);
|
|
148
|
+
const baseType = mapper(col.sqlType);
|
|
149
|
+
return {
|
|
150
|
+
tsType: col.nullable ? `${baseType} | null` : baseType,
|
|
151
|
+
imports,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=map-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map-types.js","sourceRoot":"","sources":["../src/map-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,SAAS,aAAa,CAAC,OAAe,EAAU;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3C,IACE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACtB,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QACvB,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAExB,OAAO,QAAQ,CAAC;IAClB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IAChD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC5C,4BAA4B;IAC5B,OAAO,QAAQ,CAAC;AAAA,CACjB;AAED,SAAS,eAAe,CAAC,OAAe,EAAU;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAEhE,6DAA2D;IAC3D,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,OAAO,GAAG,OAAO,IAAI,CAAC;IACxB,CAAC;IAED,gBAAgB;IAChB,IACE,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,QAAQ;QAElB,OAAO,QAAQ,CAAC;IAElB,qCAAmC;IACnC,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,WAAW;QACjE,OAAO,QAAQ,CAAC;IAElB,2BAA2B;IAC3B,IACE,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,kBAAkB;QAC5B,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,SAAS;QAEnB,OAAO,QAAQ,CAAC;IAElB,UAAU;IACV,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE9D,OAAO;IACP,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAE5D,YAAY;IACZ,IACE,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,aAAa;QACvB,KAAK,KAAK,0BAA0B;QACpC,KAAK,KAAK,6BAA6B;QACvC,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,qBAAqB;QAC/B,KAAK,KAAK,wBAAwB;QAElC,OAAO,QAAQ,CAAC;IAElB,SAAS;IACT,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,YAAY,CAAC;IAE3C,aAAa;IACb,IACE,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,QAAQ;QAClB,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC;QACrC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC;QAC9B,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC;QAC5B,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QAEzB,OAAO,QAAQ,CAAC;IAElB,WAAW;IACX,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAC;IAE1C,gBAAgB;IAChB,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS;QAC7D,OAAO,QAAQ,CAAC;IAElB,kBAAkB;IAClB,IACE,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,KAAK;QACf,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,MAAM;QAEhB,OAAO,QAAQ,CAAC;IAElB,cAAc;IACd,IACE,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,UAAU;QAEpB,OAAO,QAAQ,CAAC;IAElB,mBAAmB;IACnB,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAEjE,QAAQ;IACR,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IACrC,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IACvC,IACE,KAAK,KAAK,KAAK;QACf,KAAK,KAAK,QAAQ;QAClB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QACxB,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC;QAE/B,OAAO,QAAQ,CAAC;IAElB,OAAO,QAAQ,CAAC;AAAA,CACjB;AAED,SAAS,aAAa,CAAC,OAAuB,EAA+B;IAC3E,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC;AAAA,CACjE;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAe,EACf,YAA4B,EACd;IACd,MAAM,OAAO,GAA0C,EAAE,CAAC;IAE1D,0BAA0B;IAC1B,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,QAAQ,CAAC;gBAC1B,OAAO;oBACL,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,SAAS,CAAC,CAAC,CAAC,QAAQ;oBACtD,OAAO;iBACR,CAAC;YACJ,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC/B,OAAO;gBACL,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,SAAS,CAAC,CAAC,CAAC,QAAQ;gBACtD,OAAO;aACR,CAAC;QACJ,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,SAAS,CAAC,CAAC,CAAC,QAAQ;QACtD,OAAO;KACR,CAAC;AAAA,CACH"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/typegen - TypeScript code generation
|
|
3
|
+
*/
|
|
4
|
+
import type { VersionedSchema } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Options for rendering types.
|
|
7
|
+
*/
|
|
8
|
+
export interface RenderOptions {
|
|
9
|
+
/** Schemas at each version (for version history) */
|
|
10
|
+
schemas: VersionedSchema[];
|
|
11
|
+
/** Whether to extend SyncClientDb */
|
|
12
|
+
extendsSyncClientDb?: boolean;
|
|
13
|
+
/** Generate versioned interfaces */
|
|
14
|
+
includeVersionHistory?: boolean;
|
|
15
|
+
/** Custom imports collected from resolver results */
|
|
16
|
+
customImports?: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
from: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Render complete TypeScript type definitions.
|
|
23
|
+
*/
|
|
24
|
+
export declare function renderTypes(options: RenderOptions): string;
|
|
25
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAA6B,eAAe,EAAE,MAAM,SAAS,CAAC;AAgD1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oCAAoC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qDAAqD;IACrD,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAsG1D"}
|