admindb 2.1.0 → 2.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 +1 -1
- package/dist/app.d.ts +1 -69
- package/dist/app.js +1 -257
- package/dist/auth/config.d.ts +1 -19
- package/dist/auth/config.js +1 -147
- package/dist/auth/crypto.d.ts +1 -27
- package/dist/auth/crypto.js +1 -133
- package/dist/auth/index.d.ts +1 -5
- package/dist/auth/index.js +1 -22
- package/dist/auth/middleware.d.ts +1 -14
- package/dist/auth/middleware.js +1 -100
- package/dist/auth/routes.d.ts +1 -7
- package/dist/auth/routes.js +1 -78
- package/dist/auth/types.d.ts +1 -35
- package/dist/auth/types.js +1 -11
- package/dist/cli/args.d.ts +1 -45
- package/dist/cli/args.js +1 -328
- package/dist/cli/config.d.ts +1 -56
- package/dist/cli/config.js +1 -133
- package/dist/cli/index.d.ts +1 -4
- package/dist/cli/index.js +1 -21
- package/dist/cli/runner.d.ts +1 -1
- package/dist/cli/runner.js +1 -222
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +1 -5
- package/dist/data/datasets.d.ts +1 -17
- package/dist/data/datasets.js +1 -133
- package/dist/data/detector.d.ts +1 -30
- package/dist/data/detector.js +1 -472
- package/dist/data/engine.d.ts +1 -10
- package/dist/data/engine.js +1 -211
- package/dist/data/index.d.ts +1 -5
- package/dist/data/index.js +1 -22
- package/dist/data/strategies.d.ts +1 -30
- package/dist/data/strategies.js +1 -343
- package/dist/data/types.d.ts +1 -73
- package/dist/data/types.js +1 -8
- package/dist/db/database.d.ts +1 -119
- package/dist/db/database.js +1 -471
- package/dist/db/export.d.ts +1 -12
- package/dist/db/export.js +1 -42
- package/dist/db/filters.d.ts +1 -22
- package/dist/db/filters.js +1 -158
- package/dist/db/index.d.ts +1 -8
- package/dist/db/index.js +1 -25
- package/dist/db/introspection.d.ts +1 -6
- package/dist/db/introspection.js +1 -172
- package/dist/db/manager.d.ts +1 -81
- package/dist/db/manager.js +1 -397
- package/dist/db/migrations.d.ts +1 -5
- package/dist/db/migrations.js +1 -110
- package/dist/db/postgres.d.ts +1 -85
- package/dist/db/postgres.js +1 -745
- package/dist/db/types.d.ts +1 -206
- package/dist/db/types.js +1 -7
- package/dist/index.d.ts +1 -23
- package/dist/index.js +1 -66
- package/dist/public/js/api.js +1 -47
- package/dist/public/js/app.js +1 -262
- package/dist/public/js/browse.js +1 -1371
- package/dist/public/js/databases.js +1 -235
- package/dist/public/js/designer.js +1 -258
- package/dist/public/js/forms.js +1 -826
- package/dist/public/js/icons.js +1 -51
- package/dist/public/js/inspector.js +1 -638
- package/dist/public/js/query.js +1 -322
- package/dist/public/js/schema.js +1 -447
- package/dist/public/js/seed.js +1 -1090
- package/dist/routes/api/helpers.d.ts +1 -42
- package/dist/routes/api/helpers.js +1 -133
- package/dist/routes/api/import-export.d.ts +1 -3
- package/dist/routes/api/import-export.js +1 -85
- package/dist/routes/api/index.d.ts +1 -4
- package/dist/routes/api/index.js +1 -37
- package/dist/routes/api/query.d.ts +1 -3
- package/dist/routes/api/query.js +1 -76
- package/dist/routes/api/rows.d.ts +1 -3
- package/dist/routes/api/rows.js +1 -373
- package/dist/routes/api/seed.d.ts +1 -3
- package/dist/routes/api/seed.js +1 -82
- package/dist/routes/api/tables.d.ts +1 -3
- package/dist/routes/api/tables.js +1 -160
- package/dist/routes/databases.d.ts +1 -26
- package/dist/routes/databases.js +1 -230
- package/dist/routes/index.d.ts +1 -3
- package/dist/routes/index.js +1 -20
- package/dist/routes/pages.d.ts +1 -9
- package/dist/routes/pages.js +1 -390
- package/dist/serverless.d.ts +1 -40
- package/dist/serverless.js +1 -210
- package/dist/sql/classifier.d.ts +1 -19
- package/dist/sql/classifier.js +1 -37
- package/dist/sql/generator.d.ts +1 -81
- package/dist/sql/generator.js +1 -348
- package/dist/sql/index.d.ts +1 -2
- package/dist/sql/index.js +1 -19
- package/dist/types/api.d.ts +1 -412
- package/dist/types/api.js +1 -9
- package/dist/utils/colors.d.ts +1 -40
- package/dist/utils/colors.js +1 -64
- package/dist/utils/common.d.ts +1 -50
- package/dist/utils/common.js +1 -229
- package/dist/utils/csv.d.ts +1 -15
- package/dist/utils/csv.js +1 -80
- package/dist/utils/datatype.d.ts +1 -49
- package/dist/utils/datatype.js +1 -222
- package/dist/utils/icons.d.ts +1 -11
- package/dist/utils/icons.js +1 -72
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -21
- package/dist/utils/logger.d.ts +1 -10
- package/dist/utils/logger.js +1 -40
- package/dist/views/layouts/main.hbs +0 -4
- package/dist/views/pages/databases.hbs +0 -18
- package/dist/views/pages/designer.hbs +0 -10
- package/dist/views/pages/error.hbs +0 -2
- package/dist/views/pages/form.hbs +0 -5
- package/dist/views/pages/home.hbs +0 -8
- package/dist/views/pages/login.hbs +0 -13
- package/dist/views/pages/query.hbs +0 -9
- package/dist/views/pages/schema.hbs +0 -20
- package/dist/views/pages/seed.hbs +0 -31
- package/dist/views/pages/table.hbs +0 -14
- package/dist/views/partials/icon.hbs +0 -1
- package/dist/views/partials/navbar.hbs +0 -6
- package/dist/views/partials/sidebar.hbs +0 -8
- package/package.json +3 -2
- package/dist/app.js.map +0 -1
- package/dist/auth/config.js.map +0 -1
- package/dist/auth/crypto.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/routes.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/runner.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/data/datasets.js.map +0 -1
- package/dist/data/detector.js.map +0 -1
- package/dist/data/engine.js.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/strategies.js.map +0 -1
- package/dist/data/types.js.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/db/export.js.map +0 -1
- package/dist/db/filters.js.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/db/introspection.js.map +0 -1
- package/dist/db/manager.js.map +0 -1
- package/dist/db/migrations.js.map +0 -1
- package/dist/db/postgres.js.map +0 -1
- package/dist/db/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/public/css/input.css +0 -302
- package/dist/routes/api/helpers.js.map +0 -1
- package/dist/routes/api/import-export.js.map +0 -1
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/query.js.map +0 -1
- package/dist/routes/api/rows.js.map +0 -1
- package/dist/routes/api/seed.js.map +0 -1
- package/dist/routes/api/tables.js.map +0 -1
- package/dist/routes/databases.js.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/pages.js.map +0 -1
- package/dist/serverless.js.map +0 -1
- package/dist/sql/classifier.js.map +0 -1
- package/dist/sql/generator.js.map +0 -1
- package/dist/sql/index.js.map +0 -1
- package/dist/types/api.js.map +0 -1
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/common.js.map +0 -1
- package/dist/utils/csv.js.map +0 -1
- package/dist/utils/datatype.js.map +0 -1
- package/dist/utils/icons.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.js.map +0 -1
package/dist/sql/classifier.d.ts
CHANGED
|
@@ -1,19 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Classify incoming SQL as a read (SELECT), a count query, or a write
|
|
3
|
-
* statement, so the query runner can decide how to render/execute it.
|
|
4
|
-
*/
|
|
5
|
-
export type SqlKind = 'select' | 'count' | 'read' | 'write';
|
|
6
|
-
/** Extract the first keyword, skipping leading whitespace and comments. */
|
|
7
|
-
export declare function firstKeyword(sql: string): string;
|
|
8
|
-
export interface Classification {
|
|
9
|
-
kind: SqlKind;
|
|
10
|
-
keyword: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Classify a SQL statement.
|
|
14
|
-
* - SELECT / WITH → `select`, unless it is a pure `count(...)` (no GROUP BY)
|
|
15
|
-
* in which case it is `count`.
|
|
16
|
-
* - INSERT / UPDATE / DELETE / REPLACE / CREATE / DROP / ALTER → `write`.
|
|
17
|
-
* - Anything else that may still return rows (PRAGMA, EXPLAIN, …) → `read`.
|
|
18
|
-
*/
|
|
19
|
-
export declare function classifySql(sql: string): Classification;
|
|
1
|
+
export type SqlKind='select'|'count'|'read'|'write';export declare function firstKeyword(sql:string):string;export interface Classification{kind:SqlKind;keyword:string;}export declare function classifySql(sql:string):Classification;
|
package/dist/sql/classifier.js
CHANGED
|
@@ -1,37 +1 @@
|
|
|
1
|
-
"
|
|
2
|
-
/**
|
|
3
|
-
* Classify incoming SQL as a read (SELECT), a count query, or a write
|
|
4
|
-
* statement, so the query runner can decide how to render/execute it.
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.firstKeyword = firstKeyword;
|
|
8
|
-
exports.classifySql = classifySql;
|
|
9
|
-
const LEADING_NOISE = /^\s*((\/\*[\s\S]*?\*\/)|(--[^\n]*\n))*\s*/;
|
|
10
|
-
/** Extract the first keyword, skipping leading whitespace and comments. */
|
|
11
|
-
function firstKeyword(sql) {
|
|
12
|
-
const cleaned = String(sql).replace(LEADING_NOISE, '').trim();
|
|
13
|
-
const m = cleaned.match(/^([a-zA-Z]+)/);
|
|
14
|
-
return m ? m[1].toUpperCase() : '';
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Classify a SQL statement.
|
|
18
|
-
* - SELECT / WITH → `select`, unless it is a pure `count(...)` (no GROUP BY)
|
|
19
|
-
* in which case it is `count`.
|
|
20
|
-
* - INSERT / UPDATE / DELETE / REPLACE / CREATE / DROP / ALTER → `write`.
|
|
21
|
-
* - Anything else that may still return rows (PRAGMA, EXPLAIN, …) → `read`.
|
|
22
|
-
*/
|
|
23
|
-
function classifySql(sql) {
|
|
24
|
-
const keyword = firstKeyword(sql);
|
|
25
|
-
if (keyword === 'SELECT' || keyword === 'WITH') {
|
|
26
|
-
const body = String(sql).replace(LEADING_NOISE, '').trim();
|
|
27
|
-
const isCount = /^select\b[\s\S]*?\bcount\s*\(/i.test(body) &&
|
|
28
|
-
!/\bgroup\s+by\b/i.test(body) &&
|
|
29
|
-
!/\bunion\b/i.test(body);
|
|
30
|
-
return { kind: isCount ? 'count' : 'select', keyword };
|
|
31
|
-
}
|
|
32
|
-
if (['INSERT', 'UPDATE', 'DELETE', 'REPLACE', 'CREATE', 'DROP', 'ALTER'].includes(keyword)) {
|
|
33
|
-
return { kind: 'write', keyword };
|
|
34
|
-
}
|
|
35
|
-
return { kind: 'read', keyword: keyword || 'UNKNOWN' };
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=classifier.js.map
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.firstKeyword=firstKeyword,exports.classifySql=function(sql){const keyword=firstKeyword(sql);if("SELECT"===keyword||"WITH"===keyword){const body=String(sql).replace(LEADING_NOISE,"").trim();return{kind:/^select\b[\s\S]*?\bcount\s*\(/i.test(body)&&!/\bgroup\s+by\b/i.test(body)&&!/\bunion\b/i.test(body)?"count":"select",keyword:keyword}}if(["INSERT","UPDATE","DELETE","REPLACE","CREATE","DROP","ALTER"].includes(keyword))return{kind:"write",keyword:keyword};return{kind:"read",keyword:keyword||"UNKNOWN"}};const LEADING_NOISE=/^\s*((\/\*[\s\S]*?\*\/)|(--[^\n]*\n))*\s*/;function firstKeyword(sql){const m=String(sql).replace(LEADING_NOISE,"").trim().match(/^([a-zA-Z]+)/);return m?m[1].toUpperCase():""}
|
package/dist/sql/generator.d.ts
CHANGED
|
@@ -1,81 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Pure SQL generators. Kept completely free of any I/O so they are easy to
|
|
3
|
-
* unit-test. Both the "run" and the "generate" (get-query) variants of every
|
|
4
|
-
* mutating operation share these functions.
|
|
5
|
-
*/
|
|
6
|
-
export declare const SQLITE_DESIGNER_TYPES: readonly ["TEXT", "INTEGER", "REAL", "BLOB", "BOOLEAN", "DATE", "DATETIME", "NUMERIC", "VARCHAR(255)", "JSON"];
|
|
7
|
-
export declare const POSTGRES_DESIGNER_TYPES: readonly ["TEXT", "VARCHAR(255)", "INTEGER", "BIGINT", "SMALLINT", "SERIAL", "BIGSERIAL", "REAL", "DECIMAL(10,2)", "NUMERIC", "BOOLEAN", "DATE", "DATETIME", "TIMESTAMP", "TIMESTAMPTZ", "TIME", "INTERVAL", "JSON", "JSONB", "UUID", "BYTEA", "INET"];
|
|
8
|
-
export declare const DESIGNER_TYPES: readonly ["TEXT", "VARCHAR(255)", "INTEGER", "BIGINT", "SMALLINT", "SERIAL", "BIGSERIAL", "REAL", "DECIMAL(10,2)", "NUMERIC", "BOOLEAN", "DATE", "DATETIME", "TIMESTAMP", "TIMESTAMPTZ", "TIME", "INTERVAL", "JSON", "JSONB", "UUID", "BYTEA", "BLOB", "INET"];
|
|
9
|
-
export declare function getDesignerTypes(dialect?: 'sqlite' | 'postgres'): readonly string[];
|
|
10
|
-
export type DesignerColumnType = (typeof DESIGNER_TYPES)[number];
|
|
11
|
-
export interface ColumnDef {
|
|
12
|
-
name: string;
|
|
13
|
-
type: string;
|
|
14
|
-
primaryKey?: boolean;
|
|
15
|
-
notNull?: boolean;
|
|
16
|
-
unique?: boolean;
|
|
17
|
-
/** Raw SQL expression used after DEFAULT (e.g. `0`, `'x'`, `CURRENT_TIMESTAMP`). */
|
|
18
|
-
defaultValue?: string | null;
|
|
19
|
-
foreignKey?: {
|
|
20
|
-
table: string;
|
|
21
|
-
column: string;
|
|
22
|
-
} | null;
|
|
23
|
-
}
|
|
24
|
-
export interface FieldValue {
|
|
25
|
-
column: string;
|
|
26
|
-
value: unknown;
|
|
27
|
-
}
|
|
28
|
-
/** Quote an SQL identifier (table/column name), escaping embedded double quotes. */
|
|
29
|
-
export declare function quoteIdentifier(identifier: string): string;
|
|
30
|
-
/** Escape a string for use inside a single-quoted SQL literal. */
|
|
31
|
-
export declare function escapeString(value: string): string;
|
|
32
|
-
/** Render a JS value as a safe SQL literal. */
|
|
33
|
-
export declare function sqlValue(value: unknown): string;
|
|
34
|
-
export interface MappedType {
|
|
35
|
-
sqlType: string;
|
|
36
|
-
/** Auto default applied when the user provides none (used for DATE). */
|
|
37
|
-
defaultAuto?: string;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Map a designer-friendly or custom SQL type to a real database column type.
|
|
41
|
-
* DATE-style types map to a datetime column with a current-timestamp default.
|
|
42
|
-
*/
|
|
43
|
-
export declare function mapColumnType(type: string): MappedType;
|
|
44
|
-
export interface RenderOptions {
|
|
45
|
-
/** Constrain DDL to what `ALTER TABLE ADD COLUMN` supports. */
|
|
46
|
-
forAddColumn?: boolean;
|
|
47
|
-
}
|
|
48
|
-
/** Format a raw user-provided default value safely for SQL DDL. */
|
|
49
|
-
export declare function formatSqlDefault(raw: string, colType?: string): string;
|
|
50
|
-
/**
|
|
51
|
-
* Render a single column definition.
|
|
52
|
-
* When `forAddColumn` is set, enforces SQLite's ADD COLUMN restrictions
|
|
53
|
-
* (no PRIMARY KEY / UNIQUE, NOT NULL requires a default, FK requires NULL default).
|
|
54
|
-
*/
|
|
55
|
-
export declare function renderColumnDef(col: ColumnDef, opts?: RenderOptions): string;
|
|
56
|
-
/** Build a `CREATE TABLE` statement from structured column definitions. */
|
|
57
|
-
export declare function generateCreateTable(tableName: string, columns: ColumnDef[]): string;
|
|
58
|
-
/** Build an `ALTER TABLE … ADD COLUMN` statement. */
|
|
59
|
-
export declare function generateAddColumn(tableName: string, col: ColumnDef): string;
|
|
60
|
-
/** Build an `ALTER TABLE … RENAME TO …` statement. */
|
|
61
|
-
export declare function generateRenameTable(tableName: string, newName: string): string;
|
|
62
|
-
/** Build an `ALTER TABLE … RENAME COLUMN … TO …` statement. */
|
|
63
|
-
export declare function generateRenameColumn(tableName: string, oldName: string, newName: string): string;
|
|
64
|
-
/** Build an `ALTER TABLE … DROP COLUMN …` statement. */
|
|
65
|
-
export declare function generateDropColumn(tableName: string, column: string): string;
|
|
66
|
-
/** Build a `DROP TABLE …` statement. */
|
|
67
|
-
export declare function generateDropTable(tableName: string): string;
|
|
68
|
-
export interface IndexDef {
|
|
69
|
-
/** Optional explicit index name; a default `idx_<table>_<cols>` is generated when omitted. */
|
|
70
|
-
name?: string;
|
|
71
|
-
columns: string[];
|
|
72
|
-
unique?: boolean;
|
|
73
|
-
}
|
|
74
|
-
/** Build a `CREATE INDEX` (or `CREATE UNIQUE INDEX`) statement. */
|
|
75
|
-
export declare function generateCreateIndex(tableName: string, index: IndexDef): string;
|
|
76
|
-
/** Build a `DROP INDEX …` statement. */
|
|
77
|
-
export declare function generateDropIndex(indexName: string): string;
|
|
78
|
-
/** Build an `INSERT` statement from column/value pairs. */
|
|
79
|
-
export declare function generateInsert(table: string, fields: FieldValue[]): string;
|
|
80
|
-
/** Build an `UPDATE` statement from SET fields and a WHERE clause. */
|
|
81
|
-
export declare function generateUpdate(table: string, fields: FieldValue[], where: FieldValue[]): string;
|
|
1
|
+
export declare const SQLITE_DESIGNER_TYPES:readonly ["TEXT","INTEGER","REAL","BLOB","BOOLEAN","DATE","DATETIME","NUMERIC","VARCHAR(255)","JSON"];export declare const POSTGRES_DESIGNER_TYPES:readonly ["TEXT","VARCHAR(255)","INTEGER","BIGINT","SMALLINT","SERIAL","BIGSERIAL","REAL","DECIMAL(10,2)","NUMERIC","BOOLEAN","DATE","DATETIME","TIMESTAMP","TIMESTAMPTZ","TIME","INTERVAL","JSON","JSONB","UUID","BYTEA","INET"];export declare const DESIGNER_TYPES:readonly ["TEXT","VARCHAR(255)","INTEGER","BIGINT","SMALLINT","SERIAL","BIGSERIAL","REAL","DECIMAL(10,2)","NUMERIC","BOOLEAN","DATE","DATETIME","TIMESTAMP","TIMESTAMPTZ","TIME","INTERVAL","JSON","JSONB","UUID","BYTEA","BLOB","INET"];export declare function getDesignerTypes(dialect?:'sqlite'|'postgres'):readonly string[];export type DesignerColumnType=( typeof DESIGNER_TYPES)[number];export interface ColumnDef{name:string;type:string;primaryKey?:boolean;notNull?:boolean;unique?:boolean;defaultValue?:string|null;foreignKey?:{table:string;column:string;}|null;}export interface FieldValue{column:string;value:unknown;}export declare function quoteIdentifier(identifier:string):string;export declare function escapeString(value:string):string;export declare function sqlValue(value:unknown):string;export interface MappedType{sqlType:string;defaultAuto?:string;}export declare function mapColumnType(type:string):MappedType;export interface RenderOptions{forAddColumn?:boolean;}export declare function formatSqlDefault(raw:string,colType?:string):string;export declare function renderColumnDef(col:ColumnDef,opts?:RenderOptions):string;export declare function generateCreateTable(tableName:string,columns:ColumnDef[]):string;export declare function generateAddColumn(tableName:string,col:ColumnDef):string;export declare function generateRenameTable(tableName:string,newName:string):string;export declare function generateRenameColumn(tableName:string,oldName:string,newName:string):string;export declare function generateDropColumn(tableName:string,column:string):string;export declare function generateDropTable(tableName:string):string;export interface IndexDef{name?:string;columns:string[];unique?:boolean;}export declare function generateCreateIndex(tableName:string,index:IndexDef):string;export declare function generateDropIndex(indexName:string):string;export declare function generateInsert(table:string,fields:FieldValue[]):string;export declare function generateUpdate(table:string,fields:FieldValue[],where:FieldValue[]):string;
|
package/dist/sql/generator.js
CHANGED
|
@@ -1,348 +1 @@
|
|
|
1
|
-
"
|
|
2
|
-
/**
|
|
3
|
-
* Pure SQL generators. Kept completely free of any I/O so they are easy to
|
|
4
|
-
* unit-test. Both the "run" and the "generate" (get-query) variants of every
|
|
5
|
-
* mutating operation share these functions.
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.DESIGNER_TYPES = exports.POSTGRES_DESIGNER_TYPES = exports.SQLITE_DESIGNER_TYPES = void 0;
|
|
9
|
-
exports.getDesignerTypes = getDesignerTypes;
|
|
10
|
-
exports.quoteIdentifier = quoteIdentifier;
|
|
11
|
-
exports.escapeString = escapeString;
|
|
12
|
-
exports.sqlValue = sqlValue;
|
|
13
|
-
exports.mapColumnType = mapColumnType;
|
|
14
|
-
exports.formatSqlDefault = formatSqlDefault;
|
|
15
|
-
exports.renderColumnDef = renderColumnDef;
|
|
16
|
-
exports.generateCreateTable = generateCreateTable;
|
|
17
|
-
exports.generateAddColumn = generateAddColumn;
|
|
18
|
-
exports.generateRenameTable = generateRenameTable;
|
|
19
|
-
exports.generateRenameColumn = generateRenameColumn;
|
|
20
|
-
exports.generateDropColumn = generateDropColumn;
|
|
21
|
-
exports.generateDropTable = generateDropTable;
|
|
22
|
-
exports.generateCreateIndex = generateCreateIndex;
|
|
23
|
-
exports.generateDropIndex = generateDropIndex;
|
|
24
|
-
exports.generateInsert = generateInsert;
|
|
25
|
-
exports.generateUpdate = generateUpdate;
|
|
26
|
-
exports.SQLITE_DESIGNER_TYPES = [
|
|
27
|
-
'TEXT',
|
|
28
|
-
'INTEGER',
|
|
29
|
-
'REAL',
|
|
30
|
-
'BLOB',
|
|
31
|
-
'BOOLEAN',
|
|
32
|
-
'DATE',
|
|
33
|
-
'DATETIME',
|
|
34
|
-
'NUMERIC',
|
|
35
|
-
'VARCHAR(255)',
|
|
36
|
-
'JSON',
|
|
37
|
-
];
|
|
38
|
-
exports.POSTGRES_DESIGNER_TYPES = [
|
|
39
|
-
'TEXT',
|
|
40
|
-
'VARCHAR(255)',
|
|
41
|
-
'INTEGER',
|
|
42
|
-
'BIGINT',
|
|
43
|
-
'SMALLINT',
|
|
44
|
-
'SERIAL',
|
|
45
|
-
'BIGSERIAL',
|
|
46
|
-
'REAL',
|
|
47
|
-
'DECIMAL(10,2)',
|
|
48
|
-
'NUMERIC',
|
|
49
|
-
'BOOLEAN',
|
|
50
|
-
'DATE',
|
|
51
|
-
'DATETIME',
|
|
52
|
-
'TIMESTAMP',
|
|
53
|
-
'TIMESTAMPTZ',
|
|
54
|
-
'TIME',
|
|
55
|
-
'INTERVAL',
|
|
56
|
-
'JSON',
|
|
57
|
-
'JSONB',
|
|
58
|
-
'UUID',
|
|
59
|
-
'BYTEA',
|
|
60
|
-
'INET',
|
|
61
|
-
];
|
|
62
|
-
exports.DESIGNER_TYPES = [
|
|
63
|
-
'TEXT',
|
|
64
|
-
'VARCHAR(255)',
|
|
65
|
-
'INTEGER',
|
|
66
|
-
'BIGINT',
|
|
67
|
-
'SMALLINT',
|
|
68
|
-
'SERIAL',
|
|
69
|
-
'BIGSERIAL',
|
|
70
|
-
'REAL',
|
|
71
|
-
'DECIMAL(10,2)',
|
|
72
|
-
'NUMERIC',
|
|
73
|
-
'BOOLEAN',
|
|
74
|
-
'DATE',
|
|
75
|
-
'DATETIME',
|
|
76
|
-
'TIMESTAMP',
|
|
77
|
-
'TIMESTAMPTZ',
|
|
78
|
-
'TIME',
|
|
79
|
-
'INTERVAL',
|
|
80
|
-
'JSON',
|
|
81
|
-
'JSONB',
|
|
82
|
-
'UUID',
|
|
83
|
-
'BYTEA',
|
|
84
|
-
'BLOB',
|
|
85
|
-
'INET',
|
|
86
|
-
];
|
|
87
|
-
function getDesignerTypes(dialect = 'sqlite') {
|
|
88
|
-
return dialect === 'postgres' ? exports.POSTGRES_DESIGNER_TYPES : exports.SQLITE_DESIGNER_TYPES;
|
|
89
|
-
}
|
|
90
|
-
const IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
91
|
-
/** Quote an SQL identifier (table/column name), escaping embedded double quotes. */
|
|
92
|
-
function quoteIdentifier(identifier) {
|
|
93
|
-
return `"${String(identifier).replace(/"/g, '""')}"`;
|
|
94
|
-
}
|
|
95
|
-
/** Escape a string for use inside a single-quoted SQL literal. */
|
|
96
|
-
function escapeString(value) {
|
|
97
|
-
return `'${String(value).replace(/'/g, "''")}'`;
|
|
98
|
-
}
|
|
99
|
-
/** Render a JS value as a safe SQL literal. */
|
|
100
|
-
function sqlValue(value) {
|
|
101
|
-
if (value === null || value === undefined)
|
|
102
|
-
return 'NULL';
|
|
103
|
-
if (typeof value === 'number')
|
|
104
|
-
return Number.isFinite(value) ? String(value) : 'NULL';
|
|
105
|
-
if (typeof value === 'bigint')
|
|
106
|
-
return String(value);
|
|
107
|
-
if (typeof value === 'boolean')
|
|
108
|
-
return value ? '1' : '0';
|
|
109
|
-
if (value instanceof Uint8Array)
|
|
110
|
-
return `X'${Buffer.from(value).toString('hex')}'`;
|
|
111
|
-
if (value instanceof Date)
|
|
112
|
-
return escapeString(value.toISOString());
|
|
113
|
-
return escapeString(String(value));
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Map a designer-friendly or custom SQL type to a real database column type.
|
|
117
|
-
* DATE-style types map to a datetime column with a current-timestamp default.
|
|
118
|
-
*/
|
|
119
|
-
function mapColumnType(type) {
|
|
120
|
-
const t = String(type ?? '').trim().toUpperCase();
|
|
121
|
-
if (!t)
|
|
122
|
-
return { sqlType: 'TEXT' };
|
|
123
|
-
switch (t) {
|
|
124
|
-
case 'INTEGER':
|
|
125
|
-
case 'INT':
|
|
126
|
-
case 'TINYINT':
|
|
127
|
-
return { sqlType: 'INTEGER' };
|
|
128
|
-
case 'BIGINT':
|
|
129
|
-
case 'SMALLINT':
|
|
130
|
-
case 'SERIAL':
|
|
131
|
-
case 'BIGSERIAL':
|
|
132
|
-
case 'SMALLSERIAL':
|
|
133
|
-
return { sqlType: t };
|
|
134
|
-
case 'TEXT':
|
|
135
|
-
case 'VARCHAR':
|
|
136
|
-
case 'CHAR':
|
|
137
|
-
case 'CLOB':
|
|
138
|
-
case 'STRING':
|
|
139
|
-
case 'CITEXT':
|
|
140
|
-
return { sqlType: 'TEXT' };
|
|
141
|
-
case 'REAL':
|
|
142
|
-
case 'FLOAT':
|
|
143
|
-
case 'DOUBLE':
|
|
144
|
-
case 'DECIMAL':
|
|
145
|
-
case 'NUMERIC':
|
|
146
|
-
case 'NUMBER':
|
|
147
|
-
case 'MONEY':
|
|
148
|
-
return { sqlType: 'REAL' };
|
|
149
|
-
case 'BLOB':
|
|
150
|
-
case 'BINARY':
|
|
151
|
-
case 'VARBINARY':
|
|
152
|
-
return { sqlType: 'BLOB' };
|
|
153
|
-
case 'BYTEA':
|
|
154
|
-
return { sqlType: 'BYTEA' };
|
|
155
|
-
case 'BOOLEAN':
|
|
156
|
-
case 'BOOL':
|
|
157
|
-
return { sqlType: 'INTEGER' };
|
|
158
|
-
case 'DATE':
|
|
159
|
-
return { sqlType: 'DATETIME', defaultAuto: 'CURRENT_TIMESTAMP' };
|
|
160
|
-
case 'DATETIME':
|
|
161
|
-
return { sqlType: 'DATETIME' };
|
|
162
|
-
case 'TIMESTAMP':
|
|
163
|
-
case 'TIMESTAMPTZ':
|
|
164
|
-
case 'TIMESTAMP WITHOUT TIME ZONE':
|
|
165
|
-
case 'TIMESTAMP WITH TIME ZONE':
|
|
166
|
-
return { sqlType: t };
|
|
167
|
-
case 'TIME':
|
|
168
|
-
case 'TIMETZ':
|
|
169
|
-
case 'TIME WITHOUT TIME ZONE':
|
|
170
|
-
case 'TIME WITH TIME ZONE':
|
|
171
|
-
return { sqlType: t };
|
|
172
|
-
case 'INTERVAL':
|
|
173
|
-
case 'JSON':
|
|
174
|
-
case 'JSONB':
|
|
175
|
-
case 'UUID':
|
|
176
|
-
case 'INET':
|
|
177
|
-
case 'CIDR':
|
|
178
|
-
case 'MACADDR':
|
|
179
|
-
case 'SERIAL':
|
|
180
|
-
case 'BIGSERIAL':
|
|
181
|
-
case 'SMALLSERIAL':
|
|
182
|
-
return { sqlType: t };
|
|
183
|
-
default:
|
|
184
|
-
if (/^[A-Za-z0-9_(),\s\[\]]+$/.test(t)) {
|
|
185
|
-
return { sqlType: t };
|
|
186
|
-
}
|
|
187
|
-
throw new Error(`Unsupported column type: "${type}". Supported types include: ${exports.DESIGNER_TYPES.join(', ')} or standard SQL types.`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
function validateIdentifier(kind, name) {
|
|
191
|
-
const label = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
192
|
-
const trimmed = String(name ?? '').trim();
|
|
193
|
-
if (!trimmed)
|
|
194
|
-
throw new Error(`${label} name is required.`);
|
|
195
|
-
if (!IDENTIFIER_RE.test(trimmed)) {
|
|
196
|
-
throw new Error(`Invalid ${label.toLowerCase()} name: "${trimmed}". Use letters, digits and underscores.`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
/** Format a raw user-provided default value safely for SQL DDL. */
|
|
200
|
-
function formatSqlDefault(raw, colType) {
|
|
201
|
-
const s = String(raw ?? '').trim().replace(/;/g, '');
|
|
202
|
-
if (!s)
|
|
203
|
-
return '';
|
|
204
|
-
if (/^null$/i.test(s))
|
|
205
|
-
return 'NULL';
|
|
206
|
-
if (/^[-+]?\d+(\.\d+)?$/.test(s))
|
|
207
|
-
return s;
|
|
208
|
-
if (/^(true|false)$/i.test(s))
|
|
209
|
-
return s.toUpperCase() === 'TRUE' ? '1' : '0';
|
|
210
|
-
if (/^'.*'$/s.test(s) || /^".*"$/s.test(s))
|
|
211
|
-
return s;
|
|
212
|
-
if (/^[a-zA-Z_]\w*\s*\(.*\)$/s.test(s))
|
|
213
|
-
return s;
|
|
214
|
-
if (/^CURRENT_TIMESTAMP|CURRENT_DATE|CURRENT_TIME$/i.test(s))
|
|
215
|
-
return s.toUpperCase();
|
|
216
|
-
const t = (colType || '').toUpperCase();
|
|
217
|
-
if (t.includes('TEXT') || t.includes('CHAR') || t.includes('CLOB') || t.includes('VARCHAR') || t.includes('STRING')) {
|
|
218
|
-
return escapeString(s);
|
|
219
|
-
}
|
|
220
|
-
return s;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Render a single column definition.
|
|
224
|
-
* When `forAddColumn` is set, enforces SQLite's ADD COLUMN restrictions
|
|
225
|
-
* (no PRIMARY KEY / UNIQUE, NOT NULL requires a default, FK requires NULL default).
|
|
226
|
-
*/
|
|
227
|
-
function renderColumnDef(col, opts = {}) {
|
|
228
|
-
const colName = String(col?.name ?? '').trim();
|
|
229
|
-
validateIdentifier('column', colName);
|
|
230
|
-
const mapped = mapColumnType(col.type);
|
|
231
|
-
if (opts.forAddColumn) {
|
|
232
|
-
if (col.primaryKey) {
|
|
233
|
-
throw new Error(`Cannot add "${colName}" as PRIMARY KEY: ALTER TABLE ADD COLUMN does not support primary keys.`);
|
|
234
|
-
}
|
|
235
|
-
if (col.unique) {
|
|
236
|
-
throw new Error(`Cannot add "${colName}" with UNIQUE: ALTER TABLE ADD COLUMN does not support UNIQUE constraints.`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
let def = `${quoteIdentifier(colName)} ${mapped.sqlType}`;
|
|
240
|
-
if (!opts.forAddColumn && col.primaryKey)
|
|
241
|
-
def += ' PRIMARY KEY';
|
|
242
|
-
if (col.notNull)
|
|
243
|
-
def += ' NOT NULL';
|
|
244
|
-
if (!opts.forAddColumn && col.unique)
|
|
245
|
-
def += ' UNIQUE';
|
|
246
|
-
const rawDefault = formatSqlDefault(String(col.defaultValue ?? ''), col.type);
|
|
247
|
-
const dflt = rawDefault || mapped.defaultAuto || '';
|
|
248
|
-
if (dflt)
|
|
249
|
-
def += ` DEFAULT ${dflt}`;
|
|
250
|
-
else if (opts.forAddColumn && col.notNull) {
|
|
251
|
-
throw new Error(`Cannot add "${colName}" as NOT NULL without a default value.`);
|
|
252
|
-
}
|
|
253
|
-
if (col.foreignKey?.table && col.foreignKey.column) {
|
|
254
|
-
if (opts.forAddColumn && (col.notNull || dflt)) {
|
|
255
|
-
throw new Error(`Cannot add "${colName}" as a foreign key with NOT NULL or a non-NULL default.`);
|
|
256
|
-
}
|
|
257
|
-
def += ` REFERENCES ${quoteIdentifier(col.foreignKey.table)}(${quoteIdentifier(col.foreignKey.column)})`;
|
|
258
|
-
}
|
|
259
|
-
return def;
|
|
260
|
-
}
|
|
261
|
-
/** Build a `CREATE TABLE` statement from structured column definitions. */
|
|
262
|
-
function generateCreateTable(tableName, columns) {
|
|
263
|
-
const table = String(tableName ?? '').trim();
|
|
264
|
-
validateIdentifier('table', table);
|
|
265
|
-
if (!Array.isArray(columns) || columns.length === 0) {
|
|
266
|
-
throw new Error('At least one column is required.');
|
|
267
|
-
}
|
|
268
|
-
const seen = new Set();
|
|
269
|
-
let pkCount = 0;
|
|
270
|
-
const parts = [];
|
|
271
|
-
for (const col of columns) {
|
|
272
|
-
const colName = String(col?.name ?? '').trim();
|
|
273
|
-
validateIdentifier('column', colName);
|
|
274
|
-
if (seen.has(colName))
|
|
275
|
-
throw new Error(`Duplicate column name: "${colName}".`);
|
|
276
|
-
seen.add(colName);
|
|
277
|
-
if (col.primaryKey)
|
|
278
|
-
pkCount += 1;
|
|
279
|
-
parts.push(renderColumnDef(col));
|
|
280
|
-
}
|
|
281
|
-
if (pkCount > 1)
|
|
282
|
-
throw new Error('At most one primary key column is allowed.');
|
|
283
|
-
return `CREATE TABLE ${quoteIdentifier(table)} (\n ${parts.join(',\n ')}\n);`;
|
|
284
|
-
}
|
|
285
|
-
/** Build an `ALTER TABLE … ADD COLUMN` statement. */
|
|
286
|
-
function generateAddColumn(tableName, col) {
|
|
287
|
-
const table = String(tableName ?? '').trim();
|
|
288
|
-
validateIdentifier('table', table);
|
|
289
|
-
const def = renderColumnDef(col, { forAddColumn: true });
|
|
290
|
-
return `ALTER TABLE ${quoteIdentifier(table)} ADD COLUMN ${def};`;
|
|
291
|
-
}
|
|
292
|
-
/** Build an `ALTER TABLE … RENAME TO …` statement. */
|
|
293
|
-
function generateRenameTable(tableName, newName) {
|
|
294
|
-
validateIdentifier('table', tableName);
|
|
295
|
-
validateIdentifier('table', newName);
|
|
296
|
-
return `ALTER TABLE ${quoteIdentifier(tableName)} RENAME TO ${quoteIdentifier(newName)};`;
|
|
297
|
-
}
|
|
298
|
-
/** Build an `ALTER TABLE … RENAME COLUMN … TO …` statement. */
|
|
299
|
-
function generateRenameColumn(tableName, oldName, newName) {
|
|
300
|
-
validateIdentifier('table', tableName);
|
|
301
|
-
validateIdentifier('column', oldName);
|
|
302
|
-
validateIdentifier('column', newName);
|
|
303
|
-
return `ALTER TABLE ${quoteIdentifier(tableName)} RENAME COLUMN ${quoteIdentifier(oldName)} TO ${quoteIdentifier(newName)};`;
|
|
304
|
-
}
|
|
305
|
-
/** Build an `ALTER TABLE … DROP COLUMN …` statement. */
|
|
306
|
-
function generateDropColumn(tableName, column) {
|
|
307
|
-
validateIdentifier('table', tableName);
|
|
308
|
-
validateIdentifier('column', column);
|
|
309
|
-
return `ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(column)};`;
|
|
310
|
-
}
|
|
311
|
-
/** Build a `DROP TABLE …` statement. */
|
|
312
|
-
function generateDropTable(tableName) {
|
|
313
|
-
validateIdentifier('table', tableName);
|
|
314
|
-
return `DROP TABLE ${quoteIdentifier(tableName)};`;
|
|
315
|
-
}
|
|
316
|
-
/** Build a `CREATE INDEX` (or `CREATE UNIQUE INDEX`) statement. */
|
|
317
|
-
function generateCreateIndex(tableName, index) {
|
|
318
|
-
validateIdentifier('table', tableName);
|
|
319
|
-
const cols = Array.isArray(index?.columns) ? index.columns : [];
|
|
320
|
-
if (!cols.length)
|
|
321
|
-
throw new Error('At least one column is required for an index.');
|
|
322
|
-
for (const c of cols)
|
|
323
|
-
validateIdentifier('column', c);
|
|
324
|
-
const unique = index.unique ? 'UNIQUE ' : '';
|
|
325
|
-
let name = String(index?.name ?? '').trim();
|
|
326
|
-
if (!name)
|
|
327
|
-
name = `idx_${tableName}_${cols.join('_')}`;
|
|
328
|
-
validateIdentifier('index', name);
|
|
329
|
-
return `CREATE ${unique}INDEX ${quoteIdentifier(name)} ON ${quoteIdentifier(tableName)} (${cols.map(quoteIdentifier).join(', ')});`;
|
|
330
|
-
}
|
|
331
|
-
/** Build a `DROP INDEX …` statement. */
|
|
332
|
-
function generateDropIndex(indexName) {
|
|
333
|
-
validateIdentifier('index', indexName);
|
|
334
|
-
return `DROP INDEX ${quoteIdentifier(indexName)};`;
|
|
335
|
-
}
|
|
336
|
-
/** Build an `INSERT` statement from column/value pairs. */
|
|
337
|
-
function generateInsert(table, fields) {
|
|
338
|
-
const cols = fields.map((f) => quoteIdentifier(f.column));
|
|
339
|
-
const vals = fields.map((f) => sqlValue(f.value));
|
|
340
|
-
return `INSERT INTO ${quoteIdentifier(table)} (${cols.join(', ')}) VALUES (${vals.join(', ')});`;
|
|
341
|
-
}
|
|
342
|
-
/** Build an `UPDATE` statement from SET fields and a WHERE clause. */
|
|
343
|
-
function generateUpdate(table, fields, where) {
|
|
344
|
-
const sets = fields.map((f) => `${quoteIdentifier(f.column)} = ${sqlValue(f.value)}`);
|
|
345
|
-
const conds = where.map((w) => `${quoteIdentifier(w.column)} = ${sqlValue(w.value)}`);
|
|
346
|
-
return `UPDATE ${quoteIdentifier(table)} SET ${sets.join(', ')} WHERE ${conds.join(' AND ')};`;
|
|
347
|
-
}
|
|
348
|
-
//# sourceMappingURL=generator.js.map
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.DESIGNER_TYPES=exports.POSTGRES_DESIGNER_TYPES=exports.SQLITE_DESIGNER_TYPES=void 0,exports.getDesignerTypes=function(dialect="sqlite"){return"postgres"===dialect?exports.POSTGRES_DESIGNER_TYPES:exports.SQLITE_DESIGNER_TYPES},exports.quoteIdentifier=quoteIdentifier,exports.escapeString=escapeString,exports.sqlValue=sqlValue,exports.mapColumnType=mapColumnType,exports.formatSqlDefault=formatSqlDefault,exports.renderColumnDef=renderColumnDef,exports.generateCreateTable=function(tableName,columns){const table=String(tableName??"").trim();if(validateIdentifier("table",table),!Array.isArray(columns)||0===columns.length)throw new Error("At least one column is required.");const seen=new Set;let pkCount=0;const parts=[];for(const col of columns){const colName=String(col?.name??"").trim();if(validateIdentifier("column",colName),seen.has(colName))throw new Error(`Duplicate column name: "${colName}".`);seen.add(colName),col.primaryKey&&(pkCount+=1),parts.push(renderColumnDef(col))}if(pkCount>1)throw new Error("At most one primary key column is allowed.");return`CREATE TABLE ${quoteIdentifier(table)} (\n ${parts.join(",\n ")}\n);`},exports.generateAddColumn=function(tableName,col){const table=String(tableName??"").trim();validateIdentifier("table",table);const def=renderColumnDef(col,{forAddColumn:!0});return`ALTER TABLE ${quoteIdentifier(table)} ADD COLUMN ${def};`},exports.generateRenameTable=function(tableName,newName){return validateIdentifier("table",tableName),validateIdentifier("table",newName),`ALTER TABLE ${quoteIdentifier(tableName)} RENAME TO ${quoteIdentifier(newName)};`},exports.generateRenameColumn=function(tableName,oldName,newName){return validateIdentifier("table",tableName),validateIdentifier("column",oldName),validateIdentifier("column",newName),`ALTER TABLE ${quoteIdentifier(tableName)} RENAME COLUMN ${quoteIdentifier(oldName)} TO ${quoteIdentifier(newName)};`},exports.generateDropColumn=function(tableName,column){return validateIdentifier("table",tableName),validateIdentifier("column",column),`ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(column)};`},exports.generateDropTable=function(tableName){return validateIdentifier("table",tableName),`DROP TABLE ${quoteIdentifier(tableName)};`},exports.generateCreateIndex=function(tableName,index){validateIdentifier("table",tableName);const cols=Array.isArray(index?.columns)?index.columns:[];if(!cols.length)throw new Error("At least one column is required for an index.");for(const c of cols)validateIdentifier("column",c);const unique=index.unique?"UNIQUE ":"";let name=String(index?.name??"").trim();name||(name=`idx_${tableName}_${cols.join("_")}`);return validateIdentifier("index",name),`CREATE ${unique}INDEX ${quoteIdentifier(name)} ON ${quoteIdentifier(tableName)} (${cols.map(quoteIdentifier).join(", ")});`},exports.generateDropIndex=function(indexName){return validateIdentifier("index",indexName),`DROP INDEX ${quoteIdentifier(indexName)};`},exports.generateInsert=function(table,fields){const cols=fields.map(f=>quoteIdentifier(f.column)),vals=fields.map(f=>sqlValue(f.value));return`INSERT INTO ${quoteIdentifier(table)} (${cols.join(", ")}) VALUES (${vals.join(", ")});`},exports.generateUpdate=function(table,fields,where){const sets=fields.map(f=>`${quoteIdentifier(f.column)} = ${sqlValue(f.value)}`),conds=where.map(w=>`${quoteIdentifier(w.column)} = ${sqlValue(w.value)}`);return`UPDATE ${quoteIdentifier(table)} SET ${sets.join(", ")} WHERE ${conds.join(" AND ")};`},exports.SQLITE_DESIGNER_TYPES=["TEXT","INTEGER","REAL","BLOB","BOOLEAN","DATE","DATETIME","NUMERIC","VARCHAR(255)","JSON"],exports.POSTGRES_DESIGNER_TYPES=["TEXT","VARCHAR(255)","INTEGER","BIGINT","SMALLINT","SERIAL","BIGSERIAL","REAL","DECIMAL(10,2)","NUMERIC","BOOLEAN","DATE","DATETIME","TIMESTAMP","TIMESTAMPTZ","TIME","INTERVAL","JSON","JSONB","UUID","BYTEA","INET"],exports.DESIGNER_TYPES=["TEXT","VARCHAR(255)","INTEGER","BIGINT","SMALLINT","SERIAL","BIGSERIAL","REAL","DECIMAL(10,2)","NUMERIC","BOOLEAN","DATE","DATETIME","TIMESTAMP","TIMESTAMPTZ","TIME","INTERVAL","JSON","JSONB","UUID","BYTEA","BLOB","INET"];const IDENTIFIER_RE=/^[A-Za-z_][A-Za-z0-9_$]*$/;function quoteIdentifier(identifier){return`"${String(identifier).replace(/"/g,'""')}"`}function escapeString(value){return`'${String(value).replace(/'/g,"''")}'`}function sqlValue(value){return null==value?"NULL":"number"==typeof value?Number.isFinite(value)?String(value):"NULL":"bigint"==typeof value?String(value):"boolean"==typeof value?value?"1":"0":value instanceof Uint8Array?`X'${Buffer.from(value).toString("hex")}'`:value instanceof Date?escapeString(value.toISOString()):escapeString(String(value))}function mapColumnType(type){const t=String(type??"").trim().toUpperCase();if(!t)return{sqlType:"TEXT"};switch(t){case"INTEGER":case"INT":case"TINYINT":case"BOOLEAN":case"BOOL":return{sqlType:"INTEGER"};case"BIGINT":case"SMALLINT":case"SERIAL":case"BIGSERIAL":case"SMALLSERIAL":case"TIMESTAMP":case"TIMESTAMPTZ":case"TIMESTAMP WITHOUT TIME ZONE":case"TIMESTAMP WITH TIME ZONE":case"TIME":case"TIMETZ":case"TIME WITHOUT TIME ZONE":case"TIME WITH TIME ZONE":case"INTERVAL":case"JSON":case"JSONB":case"UUID":case"INET":case"CIDR":case"MACADDR":case"SERIAL":case"BIGSERIAL":case"SMALLSERIAL":return{sqlType:t};case"TEXT":case"VARCHAR":case"CHAR":case"CLOB":case"STRING":case"CITEXT":return{sqlType:"TEXT"};case"REAL":case"FLOAT":case"DOUBLE":case"DECIMAL":case"NUMERIC":case"NUMBER":case"MONEY":return{sqlType:"REAL"};case"BLOB":case"BINARY":case"VARBINARY":return{sqlType:"BLOB"};case"BYTEA":return{sqlType:"BYTEA"};case"DATE":return{sqlType:"DATETIME",defaultAuto:"CURRENT_TIMESTAMP"};case"DATETIME":return{sqlType:"DATETIME"};default:if(/^[A-Za-z0-9_(),\s\[\]]+$/.test(t))return{sqlType:t};throw new Error(`Unsupported column type: "${type}". Supported types include: ${exports.DESIGNER_TYPES.join(", ")} or standard SQL types.`)}}function validateIdentifier(kind,name){const label=kind.charAt(0).toUpperCase()+kind.slice(1),trimmed=String(name??"").trim();if(!trimmed)throw new Error(`${label} name is required.`);if(!IDENTIFIER_RE.test(trimmed))throw new Error(`Invalid ${label.toLowerCase()} name: "${trimmed}". Use letters, digits and underscores.`)}function formatSqlDefault(raw,colType){const s=String(raw??"").trim().replace(/;/g,"");if(!s)return"";if(/^null$/i.test(s))return"NULL";if(/^[-+]?\d+(\.\d+)?$/.test(s))return s;if(/^(true|false)$/i.test(s))return"TRUE"===s.toUpperCase()?"1":"0";if(/^'.*'$/s.test(s)||/^".*"$/s.test(s))return s;if(/^[a-zA-Z_]\w*\s*\(.*\)$/s.test(s))return s;if(/^CURRENT_TIMESTAMP|CURRENT_DATE|CURRENT_TIME$/i.test(s))return s.toUpperCase();const t=(colType||"").toUpperCase();return t.includes("TEXT")||t.includes("CHAR")||t.includes("CLOB")||t.includes("VARCHAR")||t.includes("STRING")?escapeString(s):s}function renderColumnDef(col,opts={}){const colName=String(col?.name??"").trim();validateIdentifier("column",colName);const mapped=mapColumnType(col.type);if(opts.forAddColumn){if(col.primaryKey)throw new Error(`Cannot add "${colName}" as PRIMARY KEY: ALTER TABLE ADD COLUMN does not support primary keys.`);if(col.unique)throw new Error(`Cannot add "${colName}" with UNIQUE: ALTER TABLE ADD COLUMN does not support UNIQUE constraints.`)}let def=`${quoteIdentifier(colName)} ${mapped.sqlType}`;!opts.forAddColumn&&col.primaryKey&&(def+=" PRIMARY KEY"),col.notNull&&(def+=" NOT NULL"),!opts.forAddColumn&&col.unique&&(def+=" UNIQUE");const dflt=formatSqlDefault(String(col.defaultValue??""),col.type)||mapped.defaultAuto||"";if(dflt)def+=` DEFAULT ${dflt}`;else if(opts.forAddColumn&&col.notNull)throw new Error(`Cannot add "${colName}" as NOT NULL without a default value.`);if(col.foreignKey?.table&&col.foreignKey.column){if(opts.forAddColumn&&(col.notNull||dflt))throw new Error(`Cannot add "${colName}" as a foreign key with NOT NULL or a non-NULL default.`);def+=` REFERENCES ${quoteIdentifier(col.foreignKey.table)}(${quoteIdentifier(col.foreignKey.column)})`}return def}
|
package/dist/sql/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from './classifier';
|
|
2
|
-
export * from './generator';
|
|
1
|
+
export * from './classifier';export * from './generator';
|
package/dist/sql/index.js
CHANGED
|
@@ -1,19 +1 @@
|
|
|
1
|
-
"
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./classifier"), exports);
|
|
18
|
-
__exportStar(require("./generator"), exports);
|
|
19
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:!0,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__exportStar=this&&this.__exportStar||function(m,exports){for(var p in m)"default"===p||Object.prototype.hasOwnProperty.call(exports,p)||__createBinding(exports,m,p)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./classifier"),exports),__exportStar(require("./generator"),exports);
|