@an5/orm 1.0.0
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 +138 -0
- package/dist/an5Orm.d.ts +29 -0
- package/dist/an5Orm.js +1348 -0
- package/dist/cleanup.d.ts +2 -0
- package/dist/cleanup.js +117 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/migrate.d.ts +11 -0
- package/dist/migrate.js +298 -0
- package/dist/pull.d.ts +2 -0
- package/dist/pull.js +336 -0
- package/dist/push.d.ts +2 -0
- package/dist/push.js +258 -0
- package/dist/scripts/release-cli.d.ts +3 -0
- package/dist/scripts/release-cli.js +116 -0
- package/dist/seed.d.ts +2 -0
- package/dist/seed.js +401 -0
- package/generator/src/code-generator.ts +234 -0
- package/generator/src/dotnet-generator.ts +544 -0
- package/generator/src/index.ts +92 -0
- package/generator/src/metadata-generator.ts +79 -0
- package/generator/src/parser.ts +202 -0
- package/generator/src/python-generator.ts +90 -0
- package/generator/src/types.ts +29 -0
- package/package.json +49 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
function run(cmd, allowFail = false) {
|
|
11
|
+
try {
|
|
12
|
+
return (0, child_process_1.execSync)(cmd, { encoding: 'utf8' }).trim();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (allowFail)
|
|
16
|
+
return error.stdout?.toString()?.trim() || '';
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function inferComponent(file) {
|
|
21
|
+
const normalized = file.replace('\\', '/').toLowerCase();
|
|
22
|
+
if (normalized.includes('/generator/'))
|
|
23
|
+
return 'generator';
|
|
24
|
+
if (normalized.includes('/an5client/'))
|
|
25
|
+
return 'client';
|
|
26
|
+
if (normalized.includes('/an5schema/'))
|
|
27
|
+
return 'schema';
|
|
28
|
+
if (normalized.includes('/.github/'))
|
|
29
|
+
return 'ci';
|
|
30
|
+
if (normalized.includes('package.json') || normalized.includes('tsconfig'))
|
|
31
|
+
return 'build';
|
|
32
|
+
if (normalized.includes('.md'))
|
|
33
|
+
return 'docs';
|
|
34
|
+
return 'misc';
|
|
35
|
+
}
|
|
36
|
+
function collectChanges() {
|
|
37
|
+
const status = run('git status --porcelain');
|
|
38
|
+
const files = status
|
|
39
|
+
.split('\n')
|
|
40
|
+
.map(l => l.trim())
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.map(l => l.slice(3).trim())
|
|
43
|
+
.filter(Boolean);
|
|
44
|
+
const groups = new Map();
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
const component = inferComponent(file);
|
|
47
|
+
if (!groups.has(component)) {
|
|
48
|
+
groups.set(component, { component, files: [], summary: '' });
|
|
49
|
+
}
|
|
50
|
+
groups.get(component).files.push(file);
|
|
51
|
+
}
|
|
52
|
+
return Array.from(groups.values()).map(group => ({
|
|
53
|
+
...group,
|
|
54
|
+
summary: `${group.component} updates`
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
function generateChangelog(groups) {
|
|
58
|
+
const lines = ['# Changelog', ''];
|
|
59
|
+
for (const group of groups) {
|
|
60
|
+
lines.push(`## ${group.component}`);
|
|
61
|
+
lines.push(`- ${group.summary}`);
|
|
62
|
+
for (const file of group.files) {
|
|
63
|
+
lines.push(` - ${file}`);
|
|
64
|
+
}
|
|
65
|
+
lines.push('');
|
|
66
|
+
}
|
|
67
|
+
return lines.join('\n').trim();
|
|
68
|
+
}
|
|
69
|
+
async function maybeUseLLM(summary) {
|
|
70
|
+
let apiKey = '';
|
|
71
|
+
try {
|
|
72
|
+
const configPath = require('path').join(__dirname, '..', '..', 'an5Adapters', 'typescript', 'config');
|
|
73
|
+
const mod = require(configPath);
|
|
74
|
+
if (mod?.getLlmConfig) {
|
|
75
|
+
const db = await mod.getLlmConfig();
|
|
76
|
+
if (db)
|
|
77
|
+
apiKey = db.apiKey;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch { }
|
|
81
|
+
if (!apiKey)
|
|
82
|
+
return summary;
|
|
83
|
+
try {
|
|
84
|
+
const prompt = `Summarize these changes into one concise release note in English:\n${summary}`;
|
|
85
|
+
const payload = JSON.stringify({ model: 'gpt-4o-mini', messages: [{ role: 'system', content: 'You are a helpful release note writer.' }, { role: 'user', content: prompt }] });
|
|
86
|
+
const response = run(`curl -s https://api.openai.com/v1/chat/completions -H "Authorization: Bearer ${apiKey}" -H "Content-Type: application/json" -d '${payload}'`, true);
|
|
87
|
+
const parsed = JSON.parse(response);
|
|
88
|
+
return parsed.choices?.[0]?.message?.content?.trim() || summary;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return summary;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function main() {
|
|
95
|
+
const groups = collectChanges();
|
|
96
|
+
if (groups.length === 0) {
|
|
97
|
+
console.log('No modified files detected.');
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
const changelog = generateChangelog(groups);
|
|
101
|
+
const outputPath = path_1.default.resolve(process.cwd(), 'CHANGELOG.md');
|
|
102
|
+
fs_1.default.writeFileSync(outputPath, changelog + '\n');
|
|
103
|
+
const summary = groups.map(g => `${g.component}: ${g.files.join(', ')}`).join('\n');
|
|
104
|
+
const llmSummary = await maybeUseLLM(summary);
|
|
105
|
+
console.log('\nGenerated changelog:\n');
|
|
106
|
+
console.log(changelog);
|
|
107
|
+
console.log('\nLLM summary:\n');
|
|
108
|
+
console.log(llmSummary);
|
|
109
|
+
const message = groups.map(g => g.component).join(', ');
|
|
110
|
+
const commitMessage = `chore: update ${message}`;
|
|
111
|
+
run(`git add -A`);
|
|
112
|
+
run(`git commit -m "${commitMessage}"`, true);
|
|
113
|
+
console.log(`\nCommitted with: ${commitMessage}`);
|
|
114
|
+
}
|
|
115
|
+
main().catch(console.error);
|
|
116
|
+
//# sourceMappingURL=release-cli.js.map
|
package/dist/seed.d.ts
ADDED
package/dist/seed.js
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("dotenv/config");
|
|
4
|
+
const config_1 = require("@an5/lib/config");
|
|
5
|
+
const an5Orm_1 = require("../an5Orm");
|
|
6
|
+
let bcrypt;
|
|
7
|
+
try {
|
|
8
|
+
bcrypt = require("bcryptjs");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
bcrypt = { hash: async (s) => s };
|
|
12
|
+
}
|
|
13
|
+
const connectionString = process.env.DATABASE_URL;
|
|
14
|
+
// Create ORM client instance. If it fails, fall back to raw mssql seeding.
|
|
15
|
+
let db = null;
|
|
16
|
+
let dbLoadError = null;
|
|
17
|
+
try {
|
|
18
|
+
if (connectionString) {
|
|
19
|
+
db = new an5Orm_1.An5ORM();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
dbLoadError = e;
|
|
24
|
+
console.log('Database client failed to initialize:', e?.message ?? e);
|
|
25
|
+
console.log('Falling back to raw mssql seeding.');
|
|
26
|
+
}
|
|
27
|
+
async function main() {
|
|
28
|
+
console.log("🌱 Seeding LLM providers from llm-config.json...");
|
|
29
|
+
try {
|
|
30
|
+
// Only check table existence if db client initialized successfully
|
|
31
|
+
if (db) {
|
|
32
|
+
await db.lLMProvider.findMany({ take: 1 });
|
|
33
|
+
// Ensure mcp_servers table exists
|
|
34
|
+
await db.$executeRawUnsafe(`
|
|
35
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'mcp_servers')
|
|
36
|
+
BEGIN
|
|
37
|
+
CREATE TABLE [mcp_servers] (
|
|
38
|
+
[id] NVARCHAR(255) NOT NULL PRIMARY KEY,
|
|
39
|
+
[name] NVARCHAR(255) NOT NULL,
|
|
40
|
+
[command] NVARCHAR(255) NOT NULL,
|
|
41
|
+
[args] NVARCHAR(MAX) NOT NULL,
|
|
42
|
+
[env] NVARCHAR(MAX) NULL,
|
|
43
|
+
[isActive] BIT NOT NULL DEFAULT 1,
|
|
44
|
+
[createdAt] DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
45
|
+
[updatedAt] DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
46
|
+
);
|
|
47
|
+
END
|
|
48
|
+
`);
|
|
49
|
+
console.log("✅ Verified mcp_servers table exists or created.");
|
|
50
|
+
// Ensure pipeline_packages table exists
|
|
51
|
+
await db.$executeRawUnsafe(`
|
|
52
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'pipeline_packages')
|
|
53
|
+
BEGIN
|
|
54
|
+
CREATE TABLE [pipeline_packages] (
|
|
55
|
+
[id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(),
|
|
56
|
+
[name] NVARCHAR(255) NOT NULL UNIQUE,
|
|
57
|
+
[description] NVARCHAR(MAX) NULL,
|
|
58
|
+
[definition] NVARCHAR(MAX) NOT NULL,
|
|
59
|
+
[generatedSql] NVARCHAR(MAX) NULL,
|
|
60
|
+
[lastRunAt] DATETIME2 NULL,
|
|
61
|
+
[lastStatus] NVARCHAR(50) NOT NULL DEFAULT 'idle',
|
|
62
|
+
[createdAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
|
|
63
|
+
[updatedAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME()
|
|
64
|
+
);
|
|
65
|
+
END
|
|
66
|
+
`);
|
|
67
|
+
console.log("✅ Verified pipeline_packages table exists or created.");
|
|
68
|
+
// Ensure pipeline_execution_logs table exists
|
|
69
|
+
await db.$executeRawUnsafe(`
|
|
70
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'pipeline_execution_logs')
|
|
71
|
+
BEGIN
|
|
72
|
+
CREATE TABLE [pipeline_execution_logs] (
|
|
73
|
+
[id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(),
|
|
74
|
+
[packageId] UNIQUEIDENTIFIER NOT NULL,
|
|
75
|
+
[packageName] NVARCHAR(255) NOT NULL,
|
|
76
|
+
[status] NVARCHAR(50) NOT NULL DEFAULT 'running',
|
|
77
|
+
[rowsAffected] INT NULL,
|
|
78
|
+
[durationMs] INT NULL,
|
|
79
|
+
[errorMessage] NVARCHAR(MAX) NULL,
|
|
80
|
+
[executedSql] NVARCHAR(MAX) NULL,
|
|
81
|
+
[connectionId] NVARCHAR(255) NULL,
|
|
82
|
+
[startedAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
|
|
83
|
+
[finishedAt] DATETIME2 NULL
|
|
84
|
+
);
|
|
85
|
+
CREATE INDEX [idx_ssis_exec_logs_packageId] ON [pipeline_execution_logs] ([packageId]);
|
|
86
|
+
CREATE INDEX [idx_ssis_exec_logs_startedAt] ON [pipeline_execution_logs] ([startedAt] DESC);
|
|
87
|
+
END
|
|
88
|
+
`);
|
|
89
|
+
console.log("✅ Verified pipeline_execution_logs table exists or created.");
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
console.log('⚠️ Database client not available yet; will attempt fallback after reading config.');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error("❌ Error checking LLM Provider table:", error);
|
|
97
|
+
console.log("⚠️ LLM Provider table not found. Run migrations first:");
|
|
98
|
+
console.log(" npx mssql migrate dev");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Use centralized config
|
|
102
|
+
const cfg = config_1.config.llm;
|
|
103
|
+
if (!cfg.providers || !Array.isArray(cfg.providers)) {
|
|
104
|
+
console.error("❌ Invalid config: providers array not found");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// If db client failed to initialize, run fallback seeder and exit early.
|
|
108
|
+
if (!db && dbLoadError) {
|
|
109
|
+
await runFallbackAn5Seed(cfg);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Seed each provider
|
|
113
|
+
for (const provider of cfg.providers) {
|
|
114
|
+
try {
|
|
115
|
+
const providerData = {
|
|
116
|
+
provider: provider.provider,
|
|
117
|
+
model: provider.model,
|
|
118
|
+
modelType: provider.modelType,
|
|
119
|
+
apiKey: provider.apiKey || "",
|
|
120
|
+
apiEndpoint: provider.apiEndpoint,
|
|
121
|
+
...(provider.modelType === "chat" && {
|
|
122
|
+
temperature: provider.temperature,
|
|
123
|
+
maxTokens: provider.maxTokens,
|
|
124
|
+
topP: provider.topP,
|
|
125
|
+
topK: provider.topK,
|
|
126
|
+
minP: provider.minP,
|
|
127
|
+
presencePenalty: provider.presencePenalty,
|
|
128
|
+
repetitionPenalty: provider.repetitionPenalty,
|
|
129
|
+
chatTemplateKwargs: provider.chatTemplateKwargs,
|
|
130
|
+
}),
|
|
131
|
+
...(provider.modelType === "embedding" && {
|
|
132
|
+
dimensions: provider.dimensions,
|
|
133
|
+
}),
|
|
134
|
+
supportsVision: provider.supportsVision || false,
|
|
135
|
+
isActive: provider.isActive,
|
|
136
|
+
isDefault: provider.isDefault,
|
|
137
|
+
description: provider.description,
|
|
138
|
+
};
|
|
139
|
+
await db.lLMProvider.upsert({
|
|
140
|
+
where: { name: provider.name },
|
|
141
|
+
update: providerData,
|
|
142
|
+
create: {
|
|
143
|
+
name: provider.name,
|
|
144
|
+
...providerData,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
console.log(`✅ Created/Updated: ${provider.name}`);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.log(`⚠️ Skipped: ${provider.name} (conflict or error)`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
console.log("🎉 LLM seeding completed!");
|
|
154
|
+
// Setup user relations
|
|
155
|
+
console.log("🔧 Setting up user relations...");
|
|
156
|
+
try {
|
|
157
|
+
// Create or update admin user
|
|
158
|
+
const hashedPassword = await bcrypt.hash("admin2025", 10);
|
|
159
|
+
const adminUser = await db.user.upsert({
|
|
160
|
+
where: { email: "admin@local.com" },
|
|
161
|
+
update: {
|
|
162
|
+
password: hashedPassword,
|
|
163
|
+
type: "admin",
|
|
164
|
+
name: "Admin",
|
|
165
|
+
isActive: true,
|
|
166
|
+
},
|
|
167
|
+
create: {
|
|
168
|
+
email: "admin@local.com",
|
|
169
|
+
password: hashedPassword,
|
|
170
|
+
type: "admin",
|
|
171
|
+
name: "Admin",
|
|
172
|
+
isActive: true,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
console.log("✅ Admin user ready:", adminUser.email);
|
|
176
|
+
// Update existing files and jobs to admin user
|
|
177
|
+
const filesUpdated = await db.file.updateMany({
|
|
178
|
+
where: { userId: "00000000-0000-0000-0000-000000000000" },
|
|
179
|
+
data: { userId: adminUser.id },
|
|
180
|
+
});
|
|
181
|
+
console.log(`✅ Updated ${filesUpdated.count} files`);
|
|
182
|
+
console.log("🎉 User relations setup completed!");
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error("❌ Error setting up user relations:", error);
|
|
186
|
+
}
|
|
187
|
+
// Seed database connections
|
|
188
|
+
console.log("🔧 Seeding database connections...");
|
|
189
|
+
try {
|
|
190
|
+
const dbConnections = loadDbConnectionsFromEnv();
|
|
191
|
+
for (const conn of dbConnections) {
|
|
192
|
+
try {
|
|
193
|
+
const connData = {
|
|
194
|
+
host: conn.host,
|
|
195
|
+
database: conn.database,
|
|
196
|
+
username: conn.username,
|
|
197
|
+
password: conn.password,
|
|
198
|
+
type: conn.type,
|
|
199
|
+
isActive: true,
|
|
200
|
+
};
|
|
201
|
+
await db.databaseConnection.upsert({
|
|
202
|
+
where: { name: conn.name },
|
|
203
|
+
update: connData,
|
|
204
|
+
create: {
|
|
205
|
+
name: conn.name,
|
|
206
|
+
port: 1433,
|
|
207
|
+
...connData,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
console.log(`✅ Created/Updated database connection: ${conn.name}`);
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
console.log(`⚠️ Skipped database connection: ${conn.name} (conflict or error)`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
console.log("🎉 Database connections seeding completed!");
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
console.error("❌ Error seeding database connections:", error);
|
|
220
|
+
}
|
|
221
|
+
console.log("🎉 All seeding completed!");
|
|
222
|
+
}
|
|
223
|
+
main()
|
|
224
|
+
.catch((e) => {
|
|
225
|
+
console.error("❌ Error seeding database:", e);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
})
|
|
228
|
+
.finally(async () => {
|
|
229
|
+
if (db) {
|
|
230
|
+
await db.$disconnect();
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
function loadDbConnectionsFromEnv() {
|
|
234
|
+
const raw = process.env.DB_CONNECTIONS;
|
|
235
|
+
if (raw) {
|
|
236
|
+
try {
|
|
237
|
+
return JSON.parse(raw);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
console.warn("⚠️ DB_CONNECTIONS env var is not valid JSON. Using empty list.");
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
async function runFallbackAn5Seed(config) {
|
|
247
|
+
// Minimal fallback seeder using `an5` for SQL Server when an5Orm cannot
|
|
248
|
+
// initialize (e.g. missing adapter). This performs basic upserts for
|
|
249
|
+
// providers, admin user and database connections.
|
|
250
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
251
|
+
const sql = require('mssql');
|
|
252
|
+
const pool = new sql.ConnectionPool(connectionString);
|
|
253
|
+
try {
|
|
254
|
+
await pool.connect();
|
|
255
|
+
// Ensure mcp_servers table exists in fallback seeder
|
|
256
|
+
await pool.request().query(`
|
|
257
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'mcp_servers')
|
|
258
|
+
BEGIN
|
|
259
|
+
CREATE TABLE [mcp_servers] (
|
|
260
|
+
[id] NVARCHAR(255) NOT NULL PRIMARY KEY,
|
|
261
|
+
[name] NVARCHAR(255) NOT NULL,
|
|
262
|
+
[command] NVARCHAR(255) NOT NULL,
|
|
263
|
+
[args] NVARCHAR(MAX) NOT NULL,
|
|
264
|
+
[env] NVARCHAR(MAX) NULL,
|
|
265
|
+
[isActive] BIT NOT NULL DEFAULT 1,
|
|
266
|
+
[createdAt] DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
267
|
+
[updatedAt] DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
268
|
+
);
|
|
269
|
+
END
|
|
270
|
+
`);
|
|
271
|
+
console.log("✅ Fallback: Verified mcp_servers table exists or created.");
|
|
272
|
+
// Ensure pipeline_packages table exists in fallback seeder
|
|
273
|
+
await pool.request().query(`
|
|
274
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'pipeline_packages')
|
|
275
|
+
BEGIN
|
|
276
|
+
CREATE TABLE [pipeline_packages] (
|
|
277
|
+
[id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(),
|
|
278
|
+
[name] NVARCHAR(255) NOT NULL UNIQUE,
|
|
279
|
+
[description] NVARCHAR(MAX) NULL,
|
|
280
|
+
[definition] NVARCHAR(MAX) NOT NULL,
|
|
281
|
+
[generatedSql] NVARCHAR(MAX) NULL,
|
|
282
|
+
[lastRunAt] DATETIME2 NULL,
|
|
283
|
+
[lastStatus] NVARCHAR(50) NOT NULL DEFAULT 'idle',
|
|
284
|
+
[createdAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
|
|
285
|
+
[updatedAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME()
|
|
286
|
+
);
|
|
287
|
+
END
|
|
288
|
+
`);
|
|
289
|
+
console.log("✅ Fallback: Verified pipeline_packages table exists or created.");
|
|
290
|
+
// Ensure pipeline_execution_logs table exists in fallback seeder
|
|
291
|
+
await pool.request().query(`
|
|
292
|
+
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'pipeline_execution_logs')
|
|
293
|
+
BEGIN
|
|
294
|
+
CREATE TABLE [pipeline_execution_logs] (
|
|
295
|
+
[id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(),
|
|
296
|
+
[packageId] UNIQUEIDENTIFIER NOT NULL,
|
|
297
|
+
[packageName] NVARCHAR(255) NOT NULL,
|
|
298
|
+
[status] NVARCHAR(50) NOT NULL DEFAULT 'running',
|
|
299
|
+
[rowsAffected] INT NULL,
|
|
300
|
+
[durationMs] INT NULL,
|
|
301
|
+
[errorMessage] NVARCHAR(MAX) NULL,
|
|
302
|
+
[executedSql] NVARCHAR(MAX) NULL,
|
|
303
|
+
[connectionId] NVARCHAR(255) NULL,
|
|
304
|
+
[startedAt] DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
|
|
305
|
+
[finishedAt] DATETIME2 NULL
|
|
306
|
+
);
|
|
307
|
+
CREATE INDEX [idx_ssis_exec_logs_packageId] ON [pipeline_execution_logs] ([packageId]);
|
|
308
|
+
CREATE INDEX [idx_ssis_exec_logs_startedAt] ON [pipeline_execution_logs] ([startedAt] DESC);
|
|
309
|
+
END
|
|
310
|
+
`);
|
|
311
|
+
console.log("✅ Fallback: Verified pipeline_execution_logs table exists or created.");
|
|
312
|
+
// Seed providers
|
|
313
|
+
for (const provider of config.providers) {
|
|
314
|
+
const req = pool.request();
|
|
315
|
+
req.input('name', sql.NVarChar(sql.MAX), provider.name);
|
|
316
|
+
req.input('provider', sql.NVarChar(sql.MAX), provider.provider ?? null);
|
|
317
|
+
req.input('model', sql.NVarChar(sql.MAX), provider.model ?? null);
|
|
318
|
+
req.input('modelType', sql.NVarChar(sql.MAX), provider.modelType ?? null);
|
|
319
|
+
req.input('apiKey', sql.NVarChar(sql.MAX), provider.apiKey ?? null);
|
|
320
|
+
req.input('apiEndpoint', sql.NVarChar(sql.MAX), provider.apiEndpoint ?? null);
|
|
321
|
+
req.input('supportsVision', sql.Bit, provider.supportsVision ? 1 : 0);
|
|
322
|
+
req.input('isActive', sql.Bit, provider.isActive ? 1 : 0);
|
|
323
|
+
req.input('isDefault', sql.Bit, provider.isDefault ? 1 : 0);
|
|
324
|
+
req.input('description', sql.NVarChar(sql.MAX), provider.description ?? null);
|
|
325
|
+
req.input('dimensions', sql.Int, provider.dimensions ?? null);
|
|
326
|
+
const upsertSql = `
|
|
327
|
+
IF EXISTS (SELECT 1 FROM llm_providers WHERE name = @name)
|
|
328
|
+
BEGIN
|
|
329
|
+
UPDATE llm_providers SET provider=@provider, model=@model, modelType=@modelType, apiKey=@apiKey, apiEndpoint=@apiEndpoint, supportsVision=@supportsVision, isActive=@isActive, isDefault=@isDefault, description=@description, dimensions=@dimensions WHERE name=@name;
|
|
330
|
+
END
|
|
331
|
+
ELSE
|
|
332
|
+
BEGIN
|
|
333
|
+
INSERT INTO llm_providers (name, provider, model, modelType, apiKey, apiEndpoint, supportsVision, isActive, isDefault, description, dimensions)
|
|
334
|
+
VALUES (@name,@provider,@model,@modelType,@apiKey,@apiEndpoint,@supportsVision,@isActive,@isDefault,@description,@dimensions);
|
|
335
|
+
END`;
|
|
336
|
+
await req.query(upsertSql);
|
|
337
|
+
console.log(`✅ Fallback Created/Updated provider: ${provider.name}`);
|
|
338
|
+
}
|
|
339
|
+
// Admin user upsert
|
|
340
|
+
const adminEmail = 'admin@local.com';
|
|
341
|
+
const hashedPassword = await bcrypt.hash('admin2025', 10);
|
|
342
|
+
const reqUser = pool.request();
|
|
343
|
+
reqUser.input('email', sql.NVarChar(sql.MAX), adminEmail);
|
|
344
|
+
reqUser.input('password', sql.NVarChar(sql.MAX), hashedPassword);
|
|
345
|
+
const userSql = `
|
|
346
|
+
IF EXISTS (SELECT 1 FROM users WHERE email = @email)
|
|
347
|
+
BEGIN
|
|
348
|
+
UPDATE users SET password=@password, type='admin', name='Admin', isActive=1, updatedAt=SYSDATETIME() WHERE email=@email;
|
|
349
|
+
END
|
|
350
|
+
ELSE
|
|
351
|
+
BEGIN
|
|
352
|
+
INSERT INTO users (id, email, password, type, name, isActive, createdAt, updatedAt)
|
|
353
|
+
VALUES (NEWID(), @email, @password, 'admin', 'Admin', 1, SYSDATETIME(), SYSDATETIME());
|
|
354
|
+
END`;
|
|
355
|
+
await reqUser.query(userSql);
|
|
356
|
+
// Get admin id
|
|
357
|
+
const res = await pool.request().input('email', sql.NVarChar(sql.MAX), adminEmail).query('SELECT id FROM users WHERE email = @email');
|
|
358
|
+
const adminId = res.recordset?.[0]?.id;
|
|
359
|
+
if (adminId) {
|
|
360
|
+
await pool.request().input('adminId', sql.NVarChar(sql.MAX), adminId).query("UPDATE files SET userId = @adminId WHERE userId = '00000000-0000-0000-0000-000000000000'");
|
|
361
|
+
console.log('✅ Fallback admin user ready and files updated');
|
|
362
|
+
}
|
|
363
|
+
// Seed database connections
|
|
364
|
+
const dbConnections = [
|
|
365
|
+
// same list as in-memory above — reuse the original list by reconstructing
|
|
366
|
+
];
|
|
367
|
+
const connections = loadDbConnectionsFromEnv();
|
|
368
|
+
for (const conn of connections) {
|
|
369
|
+
const r = pool.request();
|
|
370
|
+
r.input('name', sql.NVarChar(sql.MAX), conn.name);
|
|
371
|
+
r.input('host', sql.NVarChar(sql.MAX), conn.host);
|
|
372
|
+
r.input('database', sql.NVarChar(sql.MAX), conn.database);
|
|
373
|
+
r.input('username', sql.NVarChar(sql.MAX), conn.username);
|
|
374
|
+
r.input('password', sql.NVarChar(sql.MAX), conn.password);
|
|
375
|
+
r.input('type', sql.NVarChar(sql.MAX), conn.type);
|
|
376
|
+
const upsertConn = `
|
|
377
|
+
IF EXISTS (SELECT 1 FROM database_connections WHERE name = @name)
|
|
378
|
+
BEGIN
|
|
379
|
+
UPDATE database_connections SET host=@host, database=@database, username=@username, password=@password, type=@type, isActive=1 WHERE name=@name;
|
|
380
|
+
END
|
|
381
|
+
ELSE
|
|
382
|
+
BEGIN
|
|
383
|
+
INSERT INTO database_connections (id, name, host, port, database, username, password, type, isActive, createdAt, updatedAt)
|
|
384
|
+
VALUES (NEWID(), @name, @host, 1433, @database, @username, @password, @type, 1, SYSDATETIME(), SYSDATETIME());
|
|
385
|
+
END`;
|
|
386
|
+
await r.query(upsertConn);
|
|
387
|
+
console.log(`✅ Fallback Created/Updated connection: ${conn.name}`);
|
|
388
|
+
}
|
|
389
|
+
console.log('🎉 Fallback seeding completed');
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
console.error('❌ Fallback seeding failed:', err);
|
|
393
|
+
}
|
|
394
|
+
finally {
|
|
395
|
+
try {
|
|
396
|
+
await pool.close();
|
|
397
|
+
}
|
|
398
|
+
catch (_) { }
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=seed.js.map
|