fastify-auto-sqlapi 0.0.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/LICENSE +21 -0
- package/README.md +422 -0
- package/dist/bin/generate-schema.d.ts +3 -0
- package/dist/bin/generate-schema.d.ts.map +1 -0
- package/dist/bin/generate-schema.js +122 -0
- package/dist/bin/generate-tables.d.ts +3 -0
- package/dist/bin/generate-tables.d.ts.map +1 -0
- package/dist/bin/generate-tables.js +135 -0
- package/dist/bin/utils.d.ts +18 -0
- package/dist/bin/utils.d.ts.map +1 -0
- package/dist/bin/utils.js +54 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/lib/adapters/mysql-adapter.d.ts +9 -0
- package/dist/lib/adapters/mysql-adapter.d.ts.map +1 -0
- package/dist/lib/adapters/mysql-adapter.js +21 -0
- package/dist/lib/adapters/pg-adapter.d.ts +9 -0
- package/dist/lib/adapters/pg-adapter.d.ts.map +1 -0
- package/dist/lib/adapters/pg-adapter.js +11 -0
- package/dist/lib/cli/config.d.ts +3 -0
- package/dist/lib/cli/config.d.ts.map +1 -0
- package/dist/lib/cli/config.js +29 -0
- package/dist/lib/cli/mysql-introspect.d.ts +16 -0
- package/dist/lib/cli/mysql-introspect.d.ts.map +1 -0
- package/dist/lib/cli/mysql-introspect.js +98 -0
- package/dist/lib/cli/pg-introspect.d.ts +4 -0
- package/dist/lib/cli/pg-introspect.d.ts.map +1 -0
- package/dist/lib/cli/pg-introspect.js +36 -0
- package/dist/lib/cli/schema-codegen.d.ts +8 -0
- package/dist/lib/cli/schema-codegen.d.ts.map +1 -0
- package/dist/lib/cli/schema-codegen.js +100 -0
- package/dist/lib/cli/tables-codegen.d.ts +18 -0
- package/dist/lib/cli/tables-codegen.d.ts.map +1 -0
- package/dist/lib/cli/tables-codegen.js +249 -0
- package/dist/lib/condition-methods.d.ts +11 -0
- package/dist/lib/condition-methods.d.ts.map +1 -0
- package/dist/lib/condition-methods.js +20 -0
- package/dist/lib/db.d.ts +28 -0
- package/dist/lib/db.d.ts.map +1 -0
- package/dist/lib/db.js +224 -0
- package/dist/lib/dialect.d.ts +17 -0
- package/dist/lib/dialect.d.ts.map +1 -0
- package/dist/lib/dialect.js +56 -0
- package/dist/lib/engine/bulk/bulk-delete.d.ts +3 -0
- package/dist/lib/engine/bulk/bulk-delete.d.ts.map +1 -0
- package/dist/lib/engine/bulk/bulk-delete.js +30 -0
- package/dist/lib/engine/bulk/bulk-upsert.d.ts +3 -0
- package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -0
- package/dist/lib/engine/bulk/bulk-upsert.js +74 -0
- package/dist/lib/engine/rest/delete.d.ts +3 -0
- package/dist/lib/engine/rest/delete.d.ts.map +1 -0
- package/dist/lib/engine/rest/delete.js +25 -0
- package/dist/lib/engine/rest/get.d.ts +3 -0
- package/dist/lib/engine/rest/get.d.ts.map +1 -0
- package/dist/lib/engine/rest/get.js +32 -0
- package/dist/lib/engine/rest/insert.d.ts +3 -0
- package/dist/lib/engine/rest/insert.d.ts.map +1 -0
- package/dist/lib/engine/rest/insert.js +58 -0
- package/dist/lib/engine/rest/update.d.ts +3 -0
- package/dist/lib/engine/rest/update.d.ts.map +1 -0
- package/dist/lib/engine/rest/update.js +110 -0
- package/dist/lib/engine/search/search.d.ts +3 -0
- package/dist/lib/engine/search/search.d.ts.map +1 -0
- package/dist/lib/engine/search/search.js +300 -0
- package/dist/lib/engine/write-helpers.d.ts +8 -0
- package/dist/lib/engine/write-helpers.d.ts.map +1 -0
- package/dist/lib/engine/write-helpers.js +83 -0
- package/dist/lib/naming.d.ts +6 -0
- package/dist/lib/naming.d.ts.map +1 -0
- package/dist/lib/naming.js +23 -0
- package/dist/lib/schema/bulk-delete.d.ts +10 -0
- package/dist/lib/schema/bulk-delete.d.ts.map +1 -0
- package/dist/lib/schema/bulk-delete.js +16 -0
- package/dist/lib/schema/bulk-upsert.d.ts +5 -0
- package/dist/lib/schema/bulk-upsert.d.ts.map +1 -0
- package/dist/lib/schema/bulk-upsert.js +43 -0
- package/dist/lib/schema/helpers.d.ts +14 -0
- package/dist/lib/schema/helpers.d.ts.map +1 -0
- package/dist/lib/schema/helpers.js +33 -0
- package/dist/lib/schema/insert.d.ts +5 -0
- package/dist/lib/schema/insert.d.ts.map +1 -0
- package/dist/lib/schema/insert.js +43 -0
- package/dist/lib/schema/search.d.ts +14 -0
- package/dist/lib/schema/search.d.ts.map +1 -0
- package/dist/lib/schema/search.js +99 -0
- package/dist/lib/schema/update.d.ts +5 -0
- package/dist/lib/schema/update.d.ts.map +1 -0
- package/dist/lib/schema/update.js +47 -0
- package/dist/lib/setup-swagger.d.ts +4 -0
- package/dist/lib/setup-swagger.d.ts.map +1 -0
- package/dist/lib/setup-swagger.js +27 -0
- package/dist/lib/sql-api.d.ts +49 -0
- package/dist/lib/sql-api.d.ts.map +1 -0
- package/dist/lib/sql-api.js +124 -0
- package/dist/lib/table-helpers.d.ts +17 -0
- package/dist/lib/table-helpers.d.ts.map +1 -0
- package/dist/lib/table-helpers.js +34 -0
- package/dist/lib/tenant.d.ts +19 -0
- package/dist/lib/tenant.d.ts.map +1 -0
- package/dist/lib/tenant.js +110 -0
- package/dist/routes/auto/bulk-delete.routes.d.ts +4 -0
- package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -0
- package/dist/routes/auto/bulk-delete.routes.js +27 -0
- package/dist/routes/auto/bulk-upsert.routes.d.ts +4 -0
- package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -0
- package/dist/routes/auto/bulk-upsert.routes.js +25 -0
- package/dist/routes/auto/delete.routes.d.ts +4 -0
- package/dist/routes/auto/delete.routes.d.ts.map +1 -0
- package/dist/routes/auto/delete.routes.js +29 -0
- package/dist/routes/auto/get.routes.d.ts +4 -0
- package/dist/routes/auto/get.routes.d.ts.map +1 -0
- package/dist/routes/auto/get.routes.js +26 -0
- package/dist/routes/auto/insert.routes.d.ts +4 -0
- package/dist/routes/auto/insert.routes.d.ts.map +1 -0
- package/dist/routes/auto/insert.routes.js +29 -0
- package/dist/routes/auto/plugin.d.ts +11 -0
- package/dist/routes/auto/plugin.d.ts.map +1 -0
- package/dist/routes/auto/plugin.js +81 -0
- package/dist/routes/auto/route-helpers.d.ts +7 -0
- package/dist/routes/auto/route-helpers.d.ts.map +1 -0
- package/dist/routes/auto/route-helpers.js +12 -0
- package/dist/routes/auto/search.routes.d.ts +4 -0
- package/dist/routes/auto/search.routes.d.ts.map +1 -0
- package/dist/routes/auto/search.routes.js +50 -0
- package/dist/routes/auto/update.routes.d.ts +4 -0
- package/dist/routes/auto/update.routes.d.ts.map +1 -0
- package/dist/routes/auto/update.routes.js +30 -0
- package/dist/types.d.ts +240 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/package.json +106 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { loadConfig } from '../lib/cli/config.js';
|
|
5
|
+
import { parseSchemaFile, generateSingleTableFile, generateDbTablesIndex } from '../lib/cli/tables-codegen.js';
|
|
6
|
+
import { loadEnvFile, CONSOLE_COLORS, display, displayAsTableRow, error } from './utils.js';
|
|
7
|
+
loadEnvFile();
|
|
8
|
+
function printHelp() {
|
|
9
|
+
console.log('');
|
|
10
|
+
display('Usage:', CONSOLE_COLORS.yellow);
|
|
11
|
+
console.log(' sqlapi-generate-tables <table1> [table2 ...] Generate specific tables (comma or space separated)');
|
|
12
|
+
console.log(' sqlapi-generate-tables --all Generate all tables');
|
|
13
|
+
console.log('');
|
|
14
|
+
display('Options:', CONSOLE_COLORS.yellow);
|
|
15
|
+
console.log(' --all Generate Table*.ts for all schemas found');
|
|
16
|
+
console.log(' --output <dir> Output directory (default: from sqlapi.config)');
|
|
17
|
+
console.log('');
|
|
18
|
+
display('Examples:', CONSOLE_COLORS.yellow);
|
|
19
|
+
console.log(' sqlapi-generate-tables customer customer_order');
|
|
20
|
+
console.log(' sqlapi-generate-tables customer,customer_order');
|
|
21
|
+
console.log(' sqlapi-generate-tables --all');
|
|
22
|
+
console.log('');
|
|
23
|
+
display('Table*.ts files are only created if they do not already exist.', CONSOLE_COLORS.magenta);
|
|
24
|
+
display('dbTables.ts is always regenerated to include all schemas.', CONSOLE_COLORS.magenta);
|
|
25
|
+
}
|
|
26
|
+
function parseCliArgs() {
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
const result = { all: false, tables: [] };
|
|
29
|
+
for (let i = 0; i < args.length; i++) {
|
|
30
|
+
if (args[i] === '--output' && i + 1 < args.length) {
|
|
31
|
+
result.output = args[++i];
|
|
32
|
+
}
|
|
33
|
+
else if (args[i] === '--all') {
|
|
34
|
+
result.all = true;
|
|
35
|
+
}
|
|
36
|
+
else if (!args[i].startsWith('--')) {
|
|
37
|
+
// Split by comma to support both "a b" and "a,b" and "a, b"
|
|
38
|
+
for (const part of args[i].split(',')) {
|
|
39
|
+
const trimmed = part.trim();
|
|
40
|
+
if (trimmed)
|
|
41
|
+
result.tables.push(trimmed);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const cliArgs = parseCliArgs();
|
|
49
|
+
if (!cliArgs.all && cliArgs.tables.length === 0) {
|
|
50
|
+
display('++++++ fastify-auto-sqlapi: generate tables template ++++++', CONSOLE_COLORS.yellow);
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
display('++++++ fastify-auto-sqlapi: generating tables template ++++++', CONSOLE_COLORS.yellow);
|
|
55
|
+
const config = await loadConfig();
|
|
56
|
+
const outputDir = path.resolve(process.cwd(), cliArgs.output || config.outputDir);
|
|
57
|
+
const schemasDir = path.join(outputDir, 'schemas');
|
|
58
|
+
const tablesDir = path.join(outputDir, 'tables');
|
|
59
|
+
if (!fs.existsSync(schemasDir)) {
|
|
60
|
+
error(`Schemas directory not found: ${schemasDir}`);
|
|
61
|
+
display('Run sqlapi-generate-schema first.', CONSOLE_COLORS.magenta);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
if (!fs.existsSync(tablesDir)) {
|
|
65
|
+
fs.mkdirSync(tablesDir, { recursive: true });
|
|
66
|
+
display(`Created directory: ${tablesDir}`, CONSOLE_COLORS.green);
|
|
67
|
+
}
|
|
68
|
+
const schemaFiles = fs
|
|
69
|
+
.readdirSync(schemasDir)
|
|
70
|
+
.filter((f) => f.startsWith('Schema') && f.endsWith('.ts'))
|
|
71
|
+
.sort();
|
|
72
|
+
if (schemaFiles.length === 0) {
|
|
73
|
+
error('No Schema*.ts files found.');
|
|
74
|
+
display('Run sqlapi-generate-schema first.', CONSOLE_COLORS.magenta);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
// Parse all schemas (needed for relation detection even when generating a subset)
|
|
78
|
+
const allSchemas = [];
|
|
79
|
+
for (const file of schemaFiles) {
|
|
80
|
+
const content = fs.readFileSync(path.join(schemasDir, file), 'utf-8');
|
|
81
|
+
const parsed = parseSchemaFile(content);
|
|
82
|
+
if (parsed) {
|
|
83
|
+
allSchemas.push(parsed);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (allSchemas.length === 0) {
|
|
87
|
+
error('No valid schemas parsed.');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
// Determine which schemas to generate Table files for
|
|
91
|
+
let targetSchemas;
|
|
92
|
+
if (cliArgs.all) {
|
|
93
|
+
targetSchemas = allSchemas;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const requestedSet = new Set(cliArgs.tables);
|
|
97
|
+
targetSchemas = allSchemas.filter((s) => requestedSet.has(s.tableName));
|
|
98
|
+
const foundNames = new Set(targetSchemas.map((s) => s.tableName));
|
|
99
|
+
for (const name of requestedSet) {
|
|
100
|
+
if (!foundNames.has(name)) {
|
|
101
|
+
error(`Table "${name}" not found. Available: ${allSchemas.map((s) => s.tableName).join(', ')}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Generate individual Table*.ts files (skip if already exists)
|
|
107
|
+
for (const schema of targetSchemas) {
|
|
108
|
+
const tableVarName = 'Table' + schema.schemaName.replace(/^Schema/, '');
|
|
109
|
+
const tableFile = path.join(tablesDir, `${tableVarName}.ts`);
|
|
110
|
+
if (fs.existsSync(tableFile)) {
|
|
111
|
+
displayAsTableRow(`${tableVarName}.ts`, 'skipped (already exists)', 60, CONSOLE_COLORS.gray);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const content = generateSingleTableFile(schema, allSchemas);
|
|
115
|
+
fs.writeFileSync(tableFile, content);
|
|
116
|
+
displayAsTableRow(`${tableVarName}.ts`, 'created', 60, CONSOLE_COLORS.green);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Generate dbTables.ts only if it does not exist
|
|
120
|
+
const dbTablesFile = path.join(tablesDir, 'dbTables.ts');
|
|
121
|
+
if (fs.existsSync(dbTablesFile)) {
|
|
122
|
+
displayAsTableRow('dbTables.ts', 'skipped (already exists)', 60, CONSOLE_COLORS.gray);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const dbTablesContent = generateDbTablesIndex(allSchemas);
|
|
126
|
+
fs.writeFileSync(dbTablesFile, dbTablesContent);
|
|
127
|
+
displayAsTableRow('dbTables.ts', 'created', 60, CONSOLE_COLORS.green);
|
|
128
|
+
}
|
|
129
|
+
console.log('');
|
|
130
|
+
display('Edit the generated Table*.ts files to customize your table configuration.', CONSOLE_COLORS.magenta);
|
|
131
|
+
}
|
|
132
|
+
main().catch((e) => {
|
|
133
|
+
error(`Error: ${e.message}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load .env file from cwd if it exists.
|
|
3
|
+
* Does not override already-set environment variables.
|
|
4
|
+
*/
|
|
5
|
+
export declare function loadEnvFile(): void;
|
|
6
|
+
export declare const CONSOLE_COLORS: {
|
|
7
|
+
readonly black: 30;
|
|
8
|
+
readonly gray: 90;
|
|
9
|
+
readonly red: 31;
|
|
10
|
+
readonly green: 32;
|
|
11
|
+
readonly yellow: 33;
|
|
12
|
+
readonly magenta: 35;
|
|
13
|
+
readonly cyan: 36;
|
|
14
|
+
};
|
|
15
|
+
export declare function displayAsTableRow(pref: string, value: string, distance: number, color?: number): void;
|
|
16
|
+
export declare function display(text: string, color?: number): void;
|
|
17
|
+
export declare function error(text: string): void;
|
|
18
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bin/utils.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAqBlC;AAED,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAEX,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAU,GAChB,IAAI,CAQN;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,IAAI,CAE7D;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAExC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Load .env file from cwd if it exists.
|
|
5
|
+
* Does not override already-set environment variables.
|
|
6
|
+
*/
|
|
7
|
+
export function loadEnvFile() {
|
|
8
|
+
const envPath = resolve(process.cwd(), '.env');
|
|
9
|
+
if (!existsSync(envPath))
|
|
10
|
+
return;
|
|
11
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
12
|
+
for (const line of content.split('\n')) {
|
|
13
|
+
const trimmed = line.trim();
|
|
14
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
15
|
+
continue;
|
|
16
|
+
const eqIndex = trimmed.indexOf('=');
|
|
17
|
+
if (eqIndex === -1)
|
|
18
|
+
continue;
|
|
19
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
20
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
21
|
+
// Strip surrounding quotes
|
|
22
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
23
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
24
|
+
value = value.slice(1, -1);
|
|
25
|
+
}
|
|
26
|
+
if (!(key in process.env)) {
|
|
27
|
+
process.env[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export const CONSOLE_COLORS = {
|
|
32
|
+
black: 30,
|
|
33
|
+
gray: 90,
|
|
34
|
+
red: 31,
|
|
35
|
+
green: 32,
|
|
36
|
+
yellow: 33,
|
|
37
|
+
magenta: 35,
|
|
38
|
+
cyan: 36,
|
|
39
|
+
};
|
|
40
|
+
export function displayAsTableRow(pref, value, distance, color = 0) {
|
|
41
|
+
const len = pref.length;
|
|
42
|
+
let text = pref + ' \x1b[' + color + 'm';
|
|
43
|
+
for (let i = 0; i < distance - len; i++) {
|
|
44
|
+
text += '_';
|
|
45
|
+
}
|
|
46
|
+
text += ' ' + value + '\x1b[0m';
|
|
47
|
+
console.log(text);
|
|
48
|
+
}
|
|
49
|
+
export function display(text, color = 0) {
|
|
50
|
+
console.log('\x1b[' + color + 'm' + text + '\x1b[0m');
|
|
51
|
+
}
|
|
52
|
+
export function error(text) {
|
|
53
|
+
display(text, CONSOLE_COLORS.red);
|
|
54
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { toCamelCase, toUnderscore, toSchemaName, camelcaseObject, snakecaseRecord, } from './lib/naming.js';
|
|
2
|
+
export { QueryClient, createQueryClient, escapeIdent } from './lib/db.js';
|
|
3
|
+
export { getDialect, type SqlDialect, type DialectName } from './lib/dialect.js';
|
|
4
|
+
export { pgQueryable } from './lib/adapters/pg-adapter.js';
|
|
5
|
+
export { mysqlQueryable } from './lib/adapters/mysql-adapter.js';
|
|
6
|
+
export { exportTableInfo, defineTable, buildRelation, buildUpsertRule, buildUpsertRules } from './lib/table-helpers.js';
|
|
7
|
+
export { resolveTenant } from './lib/tenant.js';
|
|
8
|
+
export { SqlApi, createSqlApi } from './lib/sql-api.js';
|
|
9
|
+
export type { SqlApiOptions, SqlApiSearchParams, SqlApiInsertParams, SqlApiUpdateParams } from './lib/sql-api.js';
|
|
10
|
+
export { default as fastifyAutoSqlApi } from './routes/auto/plugin.js';
|
|
11
|
+
export { setupSwagger } from './lib/setup-swagger.js';
|
|
12
|
+
export { searchEngine } from './lib/engine/search/search.js';
|
|
13
|
+
export { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from './lib/schema/search.js';
|
|
14
|
+
export { default as searchRoutes } from './routes/auto/search.routes.js';
|
|
15
|
+
export { insertEngine } from './lib/engine/rest/insert.js';
|
|
16
|
+
export { InsertTableBody, InsertTableResponse } from './lib/schema/insert.js';
|
|
17
|
+
export { default as insertRoutes } from './routes/auto/insert.routes.js';
|
|
18
|
+
export { getEngine } from './lib/engine/rest/get.js';
|
|
19
|
+
export { default as getRoutes } from './routes/auto/get.routes.js';
|
|
20
|
+
export { deleteEngine } from './lib/engine/rest/delete.js';
|
|
21
|
+
export { default as deleteRoutes } from './routes/auto/delete.routes.js';
|
|
22
|
+
export { updateEngine } from './lib/engine/rest/update.js';
|
|
23
|
+
export { UpdateTableBody, UpdateTableResponse } from './lib/schema/update.js';
|
|
24
|
+
export { default as updateRoutes } from './routes/auto/update.routes.js';
|
|
25
|
+
export { bulkUpsertEngine } from './lib/engine/bulk/bulk-upsert.js';
|
|
26
|
+
export { BulkUpsertTableBody, BulkUpsertTableResponse } from './lib/schema/bulk-upsert.js';
|
|
27
|
+
export { default as bulkUpsertRoutes } from './routes/auto/bulk-upsert.routes.js';
|
|
28
|
+
export { bulkDeleteEngine } from './lib/engine/bulk/bulk-delete.js';
|
|
29
|
+
export { BulkDeleteTableBody, BulkDeleteTableResponse } from './lib/schema/bulk-delete.js';
|
|
30
|
+
export { default as bulkDeleteRoutes } from './routes/auto/bulk-delete.routes.js';
|
|
31
|
+
export { Type, type Static } from '@sinclair/typebox';
|
|
32
|
+
export { ConditionBuilder, Expression } from 'node-condition-builder';
|
|
33
|
+
export type { SqlApiConfig, ColumnInfo, TableMap, Queryable, SqlResult, DbRecord, DbRecordValue, SelectOptions, SchemaDefinition, JoinDefinition, ITable, DbTables, SqlApiPluginOptions, SwaggerOptions, SearchParams, SearchResult, Paginator, PaginationResult, TableFilterFn, ExtendedConditionFn, FilterRecord, AggregationRequest, JoinGroupRequest, GetParams, GetResult, DeleteParams, DeleteResult, InsertParams, InsertResult, BulkUpsertItem, BulkUpsertParams, BulkUpsertResult, BulkDeleteParams, BulkDeleteResult, ConditionMethod, SearchCondition, UpdateParams, UpdateResult, TenantId, TenantScope, TenantScopeDirect, TenantScopeIndirect, TenantContext, } from './types.js';
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Re-export utilities
|
|
2
|
+
export { toCamelCase, toUnderscore, toSchemaName, camelcaseObject, snakecaseRecord, } from './lib/naming.js';
|
|
3
|
+
// DB
|
|
4
|
+
export { QueryClient, createQueryClient, escapeIdent } from './lib/db.js';
|
|
5
|
+
// Dialect
|
|
6
|
+
export { getDialect } from './lib/dialect.js';
|
|
7
|
+
// Adapters
|
|
8
|
+
export { pgQueryable } from './lib/adapters/pg-adapter.js';
|
|
9
|
+
export { mysqlQueryable } from './lib/adapters/mysql-adapter.js';
|
|
10
|
+
// Table helpers
|
|
11
|
+
export { exportTableInfo, defineTable, buildRelation, buildUpsertRule, buildUpsertRules } from './lib/table-helpers.js';
|
|
12
|
+
// Tenant
|
|
13
|
+
export { resolveTenant } from './lib/tenant.js';
|
|
14
|
+
// SqlApi — programmatic high-level API
|
|
15
|
+
export { SqlApi, createSqlApi } from './lib/sql-api.js';
|
|
16
|
+
// Plugin
|
|
17
|
+
export { default as fastifyAutoSqlApi } from './routes/auto/plugin.js';
|
|
18
|
+
// Swagger
|
|
19
|
+
export { setupSwagger } from './lib/setup-swagger.js';
|
|
20
|
+
// Search
|
|
21
|
+
export { searchEngine } from './lib/engine/search/search.js';
|
|
22
|
+
export { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from './lib/schema/search.js';
|
|
23
|
+
export { default as searchRoutes } from './routes/auto/search.routes.js';
|
|
24
|
+
// Insert
|
|
25
|
+
export { insertEngine } from './lib/engine/rest/insert.js';
|
|
26
|
+
export { InsertTableBody, InsertTableResponse } from './lib/schema/insert.js';
|
|
27
|
+
export { default as insertRoutes } from './routes/auto/insert.routes.js';
|
|
28
|
+
// Get
|
|
29
|
+
export { getEngine } from './lib/engine/rest/get.js';
|
|
30
|
+
export { default as getRoutes } from './routes/auto/get.routes.js';
|
|
31
|
+
// Delete
|
|
32
|
+
export { deleteEngine } from './lib/engine/rest/delete.js';
|
|
33
|
+
export { default as deleteRoutes } from './routes/auto/delete.routes.js';
|
|
34
|
+
// Update
|
|
35
|
+
export { updateEngine } from './lib/engine/rest/update.js';
|
|
36
|
+
export { UpdateTableBody, UpdateTableResponse } from './lib/schema/update.js';
|
|
37
|
+
export { default as updateRoutes } from './routes/auto/update.routes.js';
|
|
38
|
+
// Bulk Upsert
|
|
39
|
+
export { bulkUpsertEngine } from './lib/engine/bulk/bulk-upsert.js';
|
|
40
|
+
export { BulkUpsertTableBody, BulkUpsertTableResponse } from './lib/schema/bulk-upsert.js';
|
|
41
|
+
export { default as bulkUpsertRoutes } from './routes/auto/bulk-upsert.routes.js';
|
|
42
|
+
// Bulk Delete
|
|
43
|
+
export { bulkDeleteEngine } from './lib/engine/bulk/bulk-delete.js';
|
|
44
|
+
export { BulkDeleteTableBody, BulkDeleteTableResponse } from './lib/schema/bulk-delete.js';
|
|
45
|
+
export { default as bulkDeleteRoutes } from './routes/auto/bulk-delete.routes.js';
|
|
46
|
+
// Re-export deps
|
|
47
|
+
export { Type } from '@sinclair/typebox';
|
|
48
|
+
export { ConditionBuilder, Expression } from 'node-condition-builder';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Queryable } from '../../types.js';
|
|
2
|
+
export interface MysqlQueryable {
|
|
3
|
+
query<T = Record<string, unknown>>(sql: string, values?: unknown[]): Promise<[T[] & {
|
|
4
|
+
affectedRows?: number;
|
|
5
|
+
insertId?: number;
|
|
6
|
+
}, unknown]>;
|
|
7
|
+
}
|
|
8
|
+
export declare function mysqlQueryable(pool: MysqlQueryable): Queryable;
|
|
9
|
+
//# sourceMappingURL=mysql-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/mysql-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,CAyB9D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function mysqlQueryable(pool) {
|
|
2
|
+
return {
|
|
3
|
+
async query(text, values) {
|
|
4
|
+
const [result] = await pool.query(text, values);
|
|
5
|
+
// SELECT returns an array of rows
|
|
6
|
+
if (Array.isArray(result) && !('affectedRows' in result)) {
|
|
7
|
+
return {
|
|
8
|
+
rows: result,
|
|
9
|
+
affectedRows: result.length,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
// INSERT/UPDATE/DELETE returns ResultSetHeader-like
|
|
13
|
+
const header = result;
|
|
14
|
+
return {
|
|
15
|
+
rows: [],
|
|
16
|
+
affectedRows: header.affectedRows ?? 0,
|
|
17
|
+
insertId: header.insertId,
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Queryable } from '../../types.js';
|
|
2
|
+
export interface PgQueryable {
|
|
3
|
+
query<T = Record<string, unknown>>(text: string, values?: unknown[]): Promise<{
|
|
4
|
+
rows: T[];
|
|
5
|
+
rowCount: number | null;
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
8
|
+
export declare function pgQueryable(client: PgQueryable): Queryable;
|
|
9
|
+
//# sourceMappingURL=pg-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/pg-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAa1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAOnD,wBAAsB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,CAyBxD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { pathToFileURL } from 'node:url';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
outputDir: './src/db',
|
|
6
|
+
schema: 'public',
|
|
7
|
+
};
|
|
8
|
+
export async function loadConfig() {
|
|
9
|
+
const candidates = ['sqlapi.config.ts', 'sqlapi.config.mjs', 'sqlapi.config.js'];
|
|
10
|
+
const configPath = candidates
|
|
11
|
+
.map((f) => resolve(process.cwd(), f))
|
|
12
|
+
.find((p) => existsSync(p)) ?? null;
|
|
13
|
+
if (!configPath) {
|
|
14
|
+
return { ...DEFAULTS };
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const configUrl = pathToFileURL(configPath).href;
|
|
18
|
+
const mod = await import(configUrl);
|
|
19
|
+
const userConfig = mod.default ?? mod;
|
|
20
|
+
return {
|
|
21
|
+
...DEFAULTS,
|
|
22
|
+
...userConfig,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
console.warn(`Warning: failed to load ${configPath}, using defaults. Error: ${err.message}`);
|
|
27
|
+
return { ...DEFAULTS };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ColumnInfo } from '../../types.js';
|
|
2
|
+
export declare function buildMysqlConnectionConfig(): {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
user: string;
|
|
6
|
+
password: string;
|
|
7
|
+
database: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function introspectMysqlTables(connectionConfig: {
|
|
10
|
+
host: string;
|
|
11
|
+
port: number;
|
|
12
|
+
user: string;
|
|
13
|
+
password: string;
|
|
14
|
+
database: string;
|
|
15
|
+
}, schema: string): Promise<ColumnInfo[]>;
|
|
16
|
+
//# sourceMappingURL=mysql-introspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql-introspect.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/mysql-introspect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,0BAA0B,IAAI;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAmBA;AAkDD,wBAAsB,qBAAqB,CACzC,gBAAgB,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAClG,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,EAAE,CAAC,CAiCvB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
export function buildMysqlConnectionConfig() {
|
|
3
|
+
if (process.env.DATABASE_URL) {
|
|
4
|
+
const url = new URL(process.env.DATABASE_URL);
|
|
5
|
+
return {
|
|
6
|
+
host: url.hostname,
|
|
7
|
+
port: parseInt(url.port || '3306', 10),
|
|
8
|
+
user: url.username,
|
|
9
|
+
password: url.password,
|
|
10
|
+
database: url.pathname.replace('/', ''),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
host: process.env.MYSQL_HOST || '127.0.0.1',
|
|
15
|
+
port: parseInt(process.env.MYSQL_PORT || '3306', 10),
|
|
16
|
+
user: process.env.MYSQL_USER || 'test',
|
|
17
|
+
password: process.env.MYSQL_PASSWORD || 'test',
|
|
18
|
+
database: process.env.MYSQL_DB || 'testdb',
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// Map MySQL DATA_TYPE to equivalent PG udt_name for schema-codegen compatibility
|
|
22
|
+
function mapMysqlType(dataType) {
|
|
23
|
+
switch (dataType.toLowerCase()) {
|
|
24
|
+
case 'int':
|
|
25
|
+
case 'mediumint':
|
|
26
|
+
return 'int4';
|
|
27
|
+
case 'smallint':
|
|
28
|
+
case 'tinyint':
|
|
29
|
+
return 'int2';
|
|
30
|
+
case 'bigint':
|
|
31
|
+
return 'int8';
|
|
32
|
+
case 'decimal':
|
|
33
|
+
case 'double':
|
|
34
|
+
case 'float':
|
|
35
|
+
return 'numeric';
|
|
36
|
+
case 'varchar':
|
|
37
|
+
return 'varchar';
|
|
38
|
+
case 'char':
|
|
39
|
+
return 'char';
|
|
40
|
+
case 'text':
|
|
41
|
+
case 'mediumtext':
|
|
42
|
+
case 'longtext':
|
|
43
|
+
case 'tinytext':
|
|
44
|
+
return 'text';
|
|
45
|
+
case 'datetime':
|
|
46
|
+
case 'timestamp':
|
|
47
|
+
return 'timestamp';
|
|
48
|
+
case 'date':
|
|
49
|
+
return 'date';
|
|
50
|
+
case 'time':
|
|
51
|
+
return 'time';
|
|
52
|
+
case 'json':
|
|
53
|
+
return 'json';
|
|
54
|
+
case 'boolean':
|
|
55
|
+
case 'bool':
|
|
56
|
+
return 'bool';
|
|
57
|
+
case 'enum':
|
|
58
|
+
return 'varchar';
|
|
59
|
+
case 'blob':
|
|
60
|
+
case 'mediumblob':
|
|
61
|
+
case 'longblob':
|
|
62
|
+
case 'tinyblob':
|
|
63
|
+
return 'text';
|
|
64
|
+
default:
|
|
65
|
+
return 'varchar';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function introspectMysqlTables(connectionConfig, schema) {
|
|
69
|
+
// Dynamic import: mysql2 is optional peer dependency.
|
|
70
|
+
// Use createRequire from cwd so it works with npm link.
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
let mysql2;
|
|
73
|
+
try {
|
|
74
|
+
const require = createRequire(process.cwd() + '/noop.js');
|
|
75
|
+
mysql2 = require('mysql2/promise');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw new Error('mysql2 is required for MySQL/MariaDB introspection. Install it with: npm install mysql2');
|
|
79
|
+
}
|
|
80
|
+
const connection = await mysql2.createConnection(connectionConfig);
|
|
81
|
+
try {
|
|
82
|
+
const [rows] = await connection.query(`SELECT table_name, column_name, data_type, column_default, is_nullable
|
|
83
|
+
FROM information_schema.columns
|
|
84
|
+
WHERE table_schema = ?
|
|
85
|
+
ORDER BY table_name, ordinal_position`, [schema]);
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
return rows.map((row) => ({
|
|
88
|
+
table_name: row.TABLE_NAME || row.table_name,
|
|
89
|
+
column_name: row.COLUMN_NAME || row.column_name,
|
|
90
|
+
udt_name: mapMysqlType(row.DATA_TYPE || row.data_type),
|
|
91
|
+
column_default: row.COLUMN_DEFAULT || row.column_default,
|
|
92
|
+
is_nullable: row.IS_NULLABLE || row.is_nullable,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await connection.end();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-introspect.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/pg-introspect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,qBAAqB,IAAI,MAAM,CAY9C;AAED,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,EAAE,CAAC,CA4BvB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
export function buildConnectionString() {
|
|
3
|
+
if (process.env.DATABASE_URL) {
|
|
4
|
+
return process.env.DATABASE_URL;
|
|
5
|
+
}
|
|
6
|
+
const host = process.env.POSTGRES_HOST || '127.0.0.1';
|
|
7
|
+
const port = process.env.POSTGRES_PORT || '5433';
|
|
8
|
+
const user = process.env.POSTGRES_USER || 'test';
|
|
9
|
+
const password = process.env.POSTGRES_PASSWORD || 'test';
|
|
10
|
+
const db = process.env.POSTGRES_DB || 'testdb';
|
|
11
|
+
return `postgres://${user}:${password}@${host}:${port}/${db}`;
|
|
12
|
+
}
|
|
13
|
+
export async function introspectTables(connectionString, schema) {
|
|
14
|
+
// Dynamic require from cwd so it works with npm link
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
let pg;
|
|
17
|
+
try {
|
|
18
|
+
const require = createRequire(process.cwd() + '/noop.js');
|
|
19
|
+
pg = require('pg');
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
throw new Error('pg is required for PostgreSQL introspection. Install it with: npm install pg');
|
|
23
|
+
}
|
|
24
|
+
const client = new pg.Client({ connectionString });
|
|
25
|
+
try {
|
|
26
|
+
await client.connect();
|
|
27
|
+
const result = await client.query(`SELECT table_name, column_name, udt_name, column_default, is_nullable
|
|
28
|
+
FROM information_schema.columns
|
|
29
|
+
WHERE table_schema = $1
|
|
30
|
+
ORDER BY table_name, ordinal_position`, [schema]);
|
|
31
|
+
return result.rows;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
await client.end();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ColumnInfo, TableMap } from '../../types.js';
|
|
2
|
+
export declare function convertColType(udtName: string, columnInfo: {
|
|
3
|
+
column_default: string | null;
|
|
4
|
+
is_nullable: string;
|
|
5
|
+
}): string;
|
|
6
|
+
export declare function buildTableMap(rows: ColumnInfo[]): TableMap;
|
|
7
|
+
export declare function generateSchemaFile(schemaName: string, tableName: string, fields: Record<string, string>): string;
|
|
8
|
+
//# sourceMappingURL=schema-codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-codegen.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/schema-codegen.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE3D,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE;IAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACjE,MAAM,CAoDR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,QAAQ,CAkB1D;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAsCR"}
|