simplemdg-dev-cli 2.0.4 → 2.4.4
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 +63 -354
- package/USER_GUIDE.md +55 -378
- package/dist/commands/cds.command.js +69 -60
- package/dist/commands/cds.command.js.map +1 -1
- package/dist/commands/cf-db.command.d.ts +2 -0
- package/dist/commands/cf-db.command.js +606 -0
- package/dist/commands/cf-db.command.js.map +1 -0
- package/dist/commands/cf.command.js +291 -280
- package/dist/commands/cf.command.js.map +1 -1
- package/dist/commands/gitlab.command.d.ts +2 -0
- package/dist/commands/gitlab.command.js +351 -0
- package/dist/commands/gitlab.command.js.map +1 -0
- package/dist/commands/npmrc.command.js +50 -44
- package/dist/commands/npmrc.command.js.map +1 -1
- package/dist/core/cache.d.ts +1 -1
- package/dist/core/cache.js +58 -31
- package/dist/core/cache.js.map +1 -1
- package/dist/core/cds.js +32 -22
- package/dist/core/cds.js.map +1 -1
- package/dist/core/cf-env-parser.d.ts +1 -1
- package/dist/core/cf-env-parser.js +4 -1
- package/dist/core/cf-env-parser.js.map +1 -1
- package/dist/core/cf.d.ts +1 -1
- package/dist/core/cf.js +46 -31
- package/dist/core/cf.js.map +1 -1
- package/dist/core/db/db-btp.d.ts +48 -0
- package/dist/core/db/db-btp.js +162 -0
- package/dist/core/db/db-btp.js.map +1 -0
- package/dist/core/db/db-cache.d.ts +35 -0
- package/dist/core/db/db-cache.js +164 -0
- package/dist/core/db/db-cache.js.map +1 -0
- package/dist/core/db/db-connection.d.ts +22 -0
- package/dist/core/db/db-connection.js +73 -0
- package/dist/core/db/db-connection.js.map +1 -0
- package/dist/core/db/db-crypto.d.ts +3 -0
- package/dist/core/db/db-crypto.js +54 -0
- package/dist/core/db/db-crypto.js.map +1 -0
- package/dist/core/db/db-hana-adapter.d.ts +32 -0
- package/dist/core/db/db-hana-adapter.js +243 -0
- package/dist/core/db/db-hana-adapter.js.map +1 -0
- package/dist/core/db/db-metadata.d.ts +25 -0
- package/dist/core/db/db-metadata.js +150 -0
- package/dist/core/db/db-metadata.js.map +1 -0
- package/dist/core/db/db-postgres-adapter.d.ts +30 -0
- package/dist/core/db/db-postgres-adapter.js +245 -0
- package/dist/core/db/db-postgres-adapter.js.map +1 -0
- package/dist/core/db/db-query-files.d.ts +20 -0
- package/dist/core/db/db-query-files.js +106 -0
- package/dist/core/db/db-query-files.js.map +1 -0
- package/dist/core/db/db-query-history.d.ts +5 -0
- package/dist/core/db/db-query-history.js +49 -0
- package/dist/core/db/db-query-history.js.map +1 -0
- package/dist/core/db/db-row.d.ts +22 -0
- package/dist/core/db/db-row.js +70 -0
- package/dist/core/db/db-row.js.map +1 -0
- package/dist/core/db/db-studio-html.d.ts +4 -0
- package/dist/core/db/db-studio-html.js +437 -0
- package/dist/core/db/db-studio-html.js.map +1 -0
- package/dist/core/db/db-studio-server.d.ts +11 -0
- package/dist/core/db/db-studio-server.js +465 -0
- package/dist/core/db/db-studio-server.js.map +1 -0
- package/dist/core/db/db-types.d.ts +174 -0
- package/dist/core/db/db-types.js +3 -0
- package/dist/core/db/db-types.js.map +1 -0
- package/dist/core/db/db-vcap-parser.d.ts +7 -0
- package/dist/core/db/db-vcap-parser.js +137 -0
- package/dist/core/db/db-vcap-parser.js.map +1 -0
- package/dist/core/doctor.d.ts +1 -1
- package/dist/core/doctor.js +14 -8
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/guide.js +31 -26
- package/dist/core/guide.js.map +1 -1
- package/dist/core/install.d.ts +1 -1
- package/dist/core/install.js +17 -11
- package/dist/core/install.js.map +1 -1
- package/dist/core/navigator.d.ts +17 -0
- package/dist/core/navigator.js +140 -0
- package/dist/core/navigator.js.map +1 -0
- package/dist/core/npmrc.js +29 -16
- package/dist/core/npmrc.js.map +1 -1
- package/dist/core/process.js +11 -6
- package/dist/core/process.js.map +1 -1
- package/dist/core/prompts.js +16 -8
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/repository.d.ts +1 -1
- package/dist/core/repository.js +16 -9
- package/dist/core/repository.js.map +1 -1
- package/dist/core/scanner.d.ts +1 -1
- package/dist/core/scanner.js +13 -7
- package/dist/core/scanner.js.map +1 -1
- package/dist/core/tooling.d.ts +28 -0
- package/dist/core/tooling.js +168 -0
- package/dist/core/tooling.js.map +1 -0
- package/dist/core/types.js +2 -1
- package/dist/core/version-conflict.d.ts +2 -2
- package/dist/core/version-conflict.js +11 -6
- package/dist/core/version-conflict.js.map +1 -1
- package/dist/index.js +65 -48
- package/dist/index.js.map +1 -1
- package/dist/types-local.js +2 -1
- package/package.json +12 -6
- package/src/commands/cds.command.ts +529 -0
- package/src/commands/cf-db.command.ts +636 -0
- package/src/commands/cf.command.ts +3345 -0
- package/src/commands/gitlab.command.ts +373 -0
- package/src/commands/npmrc.command.ts +581 -0
- package/src/core/cache.ts +332 -0
- package/src/core/cds.ts +278 -0
- package/src/core/cf-env-parser.ts +131 -0
- package/src/core/cf.ts +271 -0
- package/src/core/db/db-btp.ts +207 -0
- package/src/core/db/db-cache.ts +215 -0
- package/src/core/db/db-connection.ts +79 -0
- package/src/core/db/db-crypto.ts +53 -0
- package/src/core/db/db-hana-adapter.ts +294 -0
- package/src/core/db/db-metadata.ts +174 -0
- package/src/core/db/db-postgres-adapter.ts +275 -0
- package/src/core/db/db-query-files.ts +130 -0
- package/src/core/db/db-query-history.ts +53 -0
- package/src/core/db/db-row.ts +93 -0
- package/src/core/db/db-studio-html.ts +439 -0
- package/src/core/db/db-studio-server.ts +559 -0
- package/src/core/db/db-types.ts +195 -0
- package/src/core/db/db-vcap-parser.ts +182 -0
- package/src/core/doctor.ts +70 -0
- package/src/core/guide.ts +261 -0
- package/src/core/install.ts +91 -0
- package/src/core/navigator.ts +164 -0
- package/src/core/npmrc.ts +171 -0
- package/src/core/process.ts +75 -0
- package/src/core/prompts.ts +225 -0
- package/src/core/repository.ts +36 -0
- package/src/core/scanner.ts +41 -0
- package/src/core/tooling.ts +207 -0
- package/src/core/types.ts +152 -0
- package/src/core/version-conflict.ts +46 -0
- package/src/index.ts +460 -0
- package/src/types/external.d.ts +3 -0
- package/src/types-local.ts +11 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.quoteIdentifier = quoteIdentifier;
|
|
4
|
+
exports.buildQualifiedName = buildQualifiedName;
|
|
5
|
+
exports.generateSelectSql = generateSelectSql;
|
|
6
|
+
exports.generateCountSql = generateCountSql;
|
|
7
|
+
exports.generateCreateTableDdl = generateCreateTableDdl;
|
|
8
|
+
exports.getLeadingStatementKeyword = getLeadingStatementKeyword;
|
|
9
|
+
exports.isSingleSelectStatement = isSingleSelectStatement;
|
|
10
|
+
exports.appendSafeLimit = appendSafeLimit;
|
|
11
|
+
exports.analyzeSqlSafety = analyzeSqlSafety;
|
|
12
|
+
exports.looksLikeProduction = looksLikeProduction;
|
|
13
|
+
// Keywords blocked when the studio runs in read-only mode.
|
|
14
|
+
const READ_ONLY_BLOCKED_KEYWORDS = [
|
|
15
|
+
"INSERT",
|
|
16
|
+
"UPDATE",
|
|
17
|
+
"DELETE",
|
|
18
|
+
"DROP",
|
|
19
|
+
"TRUNCATE",
|
|
20
|
+
"ALTER",
|
|
21
|
+
"CREATE",
|
|
22
|
+
"REPLACE",
|
|
23
|
+
"GRANT",
|
|
24
|
+
"REVOKE",
|
|
25
|
+
"MERGE",
|
|
26
|
+
"UPSERT",
|
|
27
|
+
];
|
|
28
|
+
// Statements that always warrant an explicit confirmation before running.
|
|
29
|
+
const DESTRUCTIVE_KEYWORDS = ["DROP", "TRUNCATE", "ALTER", "GRANT", "REVOKE"];
|
|
30
|
+
function quoteIdentifier(_type, identifier) {
|
|
31
|
+
// Both HANA and PostgreSQL use double quotes for delimited identifiers and
|
|
32
|
+
// escape an embedded double quote by doubling it.
|
|
33
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
34
|
+
}
|
|
35
|
+
function buildQualifiedName(type, schema, name) {
|
|
36
|
+
if (!schema) {
|
|
37
|
+
return quoteIdentifier(type, name);
|
|
38
|
+
}
|
|
39
|
+
return `${quoteIdentifier(type, schema)}.${quoteIdentifier(type, name)}`;
|
|
40
|
+
}
|
|
41
|
+
function generateSelectSql(type, schema, table, limit = 100) {
|
|
42
|
+
return `SELECT * FROM ${buildQualifiedName(type, schema, table)} LIMIT ${limit}`;
|
|
43
|
+
}
|
|
44
|
+
function generateCountSql(type, schema, table) {
|
|
45
|
+
return `SELECT COUNT(*) AS ROW_COUNT FROM ${buildQualifiedName(type, schema, table)}`;
|
|
46
|
+
}
|
|
47
|
+
function formatColumnType(column) {
|
|
48
|
+
const dataType = column.dataType.toUpperCase();
|
|
49
|
+
if (column.length && /CHAR|VARCHAR|NVARCHAR|VARBINARY|BINARY/.test(dataType)) {
|
|
50
|
+
return `${column.dataType}(${column.length})`;
|
|
51
|
+
}
|
|
52
|
+
if (column.scale != null && /DECIMAL|NUMERIC/.test(dataType)) {
|
|
53
|
+
return `${column.dataType}(${column.length ?? 38},${column.scale})`;
|
|
54
|
+
}
|
|
55
|
+
return column.dataType;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Best-effort CREATE TABLE statement reconstructed from column metadata. Useful
|
|
59
|
+
* as a starting point for editing in the SQL console.
|
|
60
|
+
*/
|
|
61
|
+
function generateCreateTableDdl(type, schema, table, columns) {
|
|
62
|
+
const columnLines = columns.map((column) => {
|
|
63
|
+
const nullable = column.nullable ? "" : " NOT NULL";
|
|
64
|
+
const defaultValue = column.defaultValue ? ` DEFAULT ${column.defaultValue}` : "";
|
|
65
|
+
return ` ${quoteIdentifier(type, column.name)} ${formatColumnType(column)}${nullable}${defaultValue}`;
|
|
66
|
+
});
|
|
67
|
+
const primaryKeyColumns = columns.filter((column) => column.isPrimaryKey).map((column) => quoteIdentifier(type, column.name));
|
|
68
|
+
if (primaryKeyColumns.length > 0) {
|
|
69
|
+
columnLines.push(` PRIMARY KEY (${primaryKeyColumns.join(", ")})`);
|
|
70
|
+
}
|
|
71
|
+
return `CREATE TABLE ${buildQualifiedName(type, schema, table)} (\n${columnLines.join(",\n")}\n);`;
|
|
72
|
+
}
|
|
73
|
+
function stripSqlComments(sql) {
|
|
74
|
+
return sql
|
|
75
|
+
.replace(/--[^\n]*/g, " ")
|
|
76
|
+
.replace(/\/\*[\s\S]*?\*\//g, " ");
|
|
77
|
+
}
|
|
78
|
+
function getLeadingStatementKeyword(sql) {
|
|
79
|
+
const cleaned = stripSqlComments(sql).trim();
|
|
80
|
+
const match = cleaned.match(/^([a-z]+)/i);
|
|
81
|
+
return match ? match[1].toUpperCase() : "";
|
|
82
|
+
}
|
|
83
|
+
function isSingleSelectStatement(sql) {
|
|
84
|
+
const cleaned = stripSqlComments(sql).trim().replace(/;\s*$/, "");
|
|
85
|
+
if (cleaned.includes(";")) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const keyword = getLeadingStatementKeyword(cleaned);
|
|
89
|
+
return keyword === "SELECT" || keyword === "WITH";
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Append a row limit to a single SELECT statement when one is not already
|
|
93
|
+
* present, so accidental full-table scans stay bounded.
|
|
94
|
+
*/
|
|
95
|
+
function appendSafeLimit(_type, sql, limit) {
|
|
96
|
+
if (limit <= 0) {
|
|
97
|
+
return sql;
|
|
98
|
+
}
|
|
99
|
+
if (!isSingleSelectStatement(sql)) {
|
|
100
|
+
return sql;
|
|
101
|
+
}
|
|
102
|
+
const cleaned = stripSqlComments(sql);
|
|
103
|
+
if (/\blimit\s+\d+/i.test(cleaned) || /\btop\s+\d+/i.test(cleaned) || /\bfetch\s+first\b/i.test(cleaned)) {
|
|
104
|
+
return sql;
|
|
105
|
+
}
|
|
106
|
+
const trimmed = sql.replace(/;\s*$/, "").trimEnd();
|
|
107
|
+
return `${trimmed} LIMIT ${limit}`;
|
|
108
|
+
}
|
|
109
|
+
function analyzeSqlSafety(sql, options) {
|
|
110
|
+
const cleaned = stripSqlComments(sql).trim();
|
|
111
|
+
const upper = cleaned.toUpperCase();
|
|
112
|
+
const matchedKeywords = [];
|
|
113
|
+
for (const keyword of READ_ONLY_BLOCKED_KEYWORDS) {
|
|
114
|
+
if (new RegExp(`\\b${keyword}\\b`).test(upper)) {
|
|
115
|
+
matchedKeywords.push(keyword);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const hasDestructiveKeyword = DESTRUCTIVE_KEYWORDS.some((keyword) => new RegExp(`\\b${keyword}\\b`).test(upper));
|
|
119
|
+
const leadingKeyword = getLeadingStatementKeyword(cleaned);
|
|
120
|
+
const isDeleteWithoutWhere = leadingKeyword === "DELETE" && !/\bWHERE\b/.test(upper);
|
|
121
|
+
const isUpdateWithoutWhere = leadingKeyword === "UPDATE" && !/\bWHERE\b/.test(upper);
|
|
122
|
+
const isDestructive = hasDestructiveKeyword || isDeleteWithoutWhere || isUpdateWithoutWhere;
|
|
123
|
+
const isReadOnly = matchedKeywords.length === 0;
|
|
124
|
+
const blockedByReadOnly = options.readOnly && matchedKeywords.length > 0;
|
|
125
|
+
let reason;
|
|
126
|
+
if (isDeleteWithoutWhere) {
|
|
127
|
+
reason = "DELETE without a WHERE clause affects every row.";
|
|
128
|
+
}
|
|
129
|
+
else if (isUpdateWithoutWhere) {
|
|
130
|
+
reason = "UPDATE without a WHERE clause affects every row.";
|
|
131
|
+
}
|
|
132
|
+
else if (hasDestructiveKeyword) {
|
|
133
|
+
reason = `Statement contains a destructive keyword: ${matchedKeywords.filter((keyword) => DESTRUCTIVE_KEYWORDS.includes(keyword)).join(", ")}.`;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
isDestructive,
|
|
137
|
+
isReadOnly,
|
|
138
|
+
blockedByReadOnly,
|
|
139
|
+
matchedKeywords,
|
|
140
|
+
reason,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Heuristic: an org or app name that looks production-like, used to warn the
|
|
145
|
+
* developer before they connect.
|
|
146
|
+
*/
|
|
147
|
+
function looksLikeProduction(...values) {
|
|
148
|
+
return values.some((value) => value && /\b(prod|production|prd|live)\b/i.test(value));
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=db-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-metadata.js","sourceRoot":"","sources":["../../../src/core/db/db-metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IDatabaseAdapter, TConnectionTestResult, TDatabaseColumn, TDatabaseIndex, TDatabaseObject, TDatabaseQueryResult, TDatabaseSchema, TDatabaseType, TListObjectsOptions, TResolvedDatabaseConnection, TTableDataOptions } from "./db-types";
|
|
2
|
+
export declare class PostgresAdapter implements IDatabaseAdapter {
|
|
3
|
+
private readonly connection;
|
|
4
|
+
readonly type: TDatabaseType;
|
|
5
|
+
private client;
|
|
6
|
+
private readonly queryTimeoutMs;
|
|
7
|
+
constructor(connection: TResolvedDatabaseConnection, options?: {
|
|
8
|
+
queryTimeoutMs?: number;
|
|
9
|
+
});
|
|
10
|
+
connect(): Promise<void>;
|
|
11
|
+
disconnect(): Promise<void>;
|
|
12
|
+
private getClient;
|
|
13
|
+
testConnection(): Promise<TConnectionTestResult>;
|
|
14
|
+
private toQueryResult;
|
|
15
|
+
runQuery(sql: string, options?: {
|
|
16
|
+
maxRows?: number;
|
|
17
|
+
}): Promise<TDatabaseQueryResult>;
|
|
18
|
+
runParameterized(sql: string, params: unknown[], options?: {
|
|
19
|
+
maxRows?: number;
|
|
20
|
+
}): Promise<TDatabaseQueryResult>;
|
|
21
|
+
placeholder(index: number): string;
|
|
22
|
+
listSchemas(): Promise<TDatabaseSchema[]>;
|
|
23
|
+
listObjects(options: TListObjectsOptions): Promise<TDatabaseObject[]>;
|
|
24
|
+
listColumns(schema: string, table: string): Promise<TDatabaseColumn[]>;
|
|
25
|
+
listIndexes(schema: string, table: string): Promise<TDatabaseIndex[]>;
|
|
26
|
+
countRows(schema: string, table: string): Promise<number>;
|
|
27
|
+
getTableData(options: TTableDataOptions): Promise<TDatabaseQueryResult>;
|
|
28
|
+
quoteIdentifier(identifier: string): string;
|
|
29
|
+
buildQualifiedName(schema: string, name: string): string;
|
|
30
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PostgresAdapter = void 0;
|
|
37
|
+
const db_metadata_1 = require("./db-metadata");
|
|
38
|
+
const SYSTEM_SCHEMAS = new Set(["pg_catalog", "information_schema", "pg_toast"]);
|
|
39
|
+
class PostgresAdapter {
|
|
40
|
+
connection;
|
|
41
|
+
type = "postgresql";
|
|
42
|
+
client;
|
|
43
|
+
queryTimeoutMs;
|
|
44
|
+
constructor(connection, options) {
|
|
45
|
+
this.connection = connection;
|
|
46
|
+
this.queryTimeoutMs = options?.queryTimeoutMs ?? 30000;
|
|
47
|
+
}
|
|
48
|
+
async connect() {
|
|
49
|
+
if (this.client) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let pgModule;
|
|
53
|
+
try {
|
|
54
|
+
pgModule = await Promise.resolve().then(() => __importStar(require("pg")));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error("PostgreSQL driver 'pg' is not installed. Run: npm install pg");
|
|
58
|
+
}
|
|
59
|
+
const PgClientCtor = pgModule.Client ?? pgModule.default.Client;
|
|
60
|
+
const client = new PgClientCtor({
|
|
61
|
+
host: this.connection.host,
|
|
62
|
+
port: this.connection.port,
|
|
63
|
+
user: this.connection.username,
|
|
64
|
+
password: this.connection.password,
|
|
65
|
+
database: this.connection.database,
|
|
66
|
+
ssl: this.connection.ssl ? { rejectUnauthorized: this.connection.sslValidateCertificate ?? false } : undefined,
|
|
67
|
+
statement_timeout: this.queryTimeoutMs,
|
|
68
|
+
connectionTimeoutMillis: 15000,
|
|
69
|
+
});
|
|
70
|
+
await client.connect();
|
|
71
|
+
this.client = client;
|
|
72
|
+
}
|
|
73
|
+
async disconnect() {
|
|
74
|
+
if (this.client) {
|
|
75
|
+
await this.client.end().catch(() => undefined);
|
|
76
|
+
this.client = undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async getClient() {
|
|
80
|
+
if (!this.client) {
|
|
81
|
+
await this.connect();
|
|
82
|
+
}
|
|
83
|
+
if (!this.client) {
|
|
84
|
+
throw new Error("PostgreSQL connection is not established");
|
|
85
|
+
}
|
|
86
|
+
return this.client;
|
|
87
|
+
}
|
|
88
|
+
async testConnection() {
|
|
89
|
+
const startedAt = Date.now();
|
|
90
|
+
try {
|
|
91
|
+
const client = await this.getClient();
|
|
92
|
+
const result = await client.query("SELECT version() AS version");
|
|
93
|
+
const version = String(result.rows[0]?.version ?? "PostgreSQL");
|
|
94
|
+
return { success: true, message: "Connection successful", serverVersion: version, durationMs: Date.now() - startedAt };
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
message: error instanceof Error ? error.message : String(error),
|
|
100
|
+
durationMs: Date.now() - startedAt,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
toQueryResult(result, durationMs, maxRows) {
|
|
105
|
+
const fields = (result.fields ?? []).map((field) => field.name);
|
|
106
|
+
const allRows = (result.rows ?? []);
|
|
107
|
+
const limit = maxRows ?? 0;
|
|
108
|
+
const truncated = limit > 0 && allRows.length > limit;
|
|
109
|
+
const rows = truncated ? allRows.slice(0, limit) : allRows;
|
|
110
|
+
const command = result.command;
|
|
111
|
+
const isSelect = command === "SELECT" || command === "SHOW";
|
|
112
|
+
return {
|
|
113
|
+
fields: fields.length > 0 ? fields : rows.length > 0 ? Object.keys(rows[0]) : [],
|
|
114
|
+
rows,
|
|
115
|
+
rowCount: rows.length,
|
|
116
|
+
affectedRows: isSelect ? undefined : result.rowCount ?? undefined,
|
|
117
|
+
command,
|
|
118
|
+
durationMs,
|
|
119
|
+
truncated,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async runQuery(sql, options) {
|
|
123
|
+
const client = await this.getClient();
|
|
124
|
+
const startedAt = Date.now();
|
|
125
|
+
const rawResult = await client.query(sql);
|
|
126
|
+
const result = Array.isArray(rawResult) ? rawResult[rawResult.length - 1] : rawResult;
|
|
127
|
+
return this.toQueryResult(result, Date.now() - startedAt, options?.maxRows);
|
|
128
|
+
}
|
|
129
|
+
async runParameterized(sql, params, options) {
|
|
130
|
+
const client = await this.getClient();
|
|
131
|
+
const startedAt = Date.now();
|
|
132
|
+
const result = await client.query(sql, params);
|
|
133
|
+
return this.toQueryResult(result, Date.now() - startedAt, options?.maxRows);
|
|
134
|
+
}
|
|
135
|
+
placeholder(index) {
|
|
136
|
+
return `$${index}`;
|
|
137
|
+
}
|
|
138
|
+
async listSchemas() {
|
|
139
|
+
const client = await this.getClient();
|
|
140
|
+
const result = await client.query("SELECT schema_name FROM information_schema.schemata ORDER BY schema_name");
|
|
141
|
+
return result.rows.map((row) => {
|
|
142
|
+
const name = String(row.schema_name);
|
|
143
|
+
return { name, isSystem: SYSTEM_SCHEMAS.has(name) || name.startsWith("pg_") };
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async listObjects(options) {
|
|
147
|
+
const client = await this.getClient();
|
|
148
|
+
const schema = options.schema;
|
|
149
|
+
const kinds = options.kinds;
|
|
150
|
+
const objects = [];
|
|
151
|
+
if (!schema) {
|
|
152
|
+
return objects;
|
|
153
|
+
}
|
|
154
|
+
const wantsTable = !kinds || kinds.includes("table");
|
|
155
|
+
const wantsView = !kinds || kinds.includes("view");
|
|
156
|
+
const wantsFunction = !kinds || kinds.includes("function") || kinds.includes("procedure");
|
|
157
|
+
if (wantsTable || wantsView) {
|
|
158
|
+
const tables = await client.query("SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = $1 ORDER BY table_name", [schema]);
|
|
159
|
+
for (const row of tables.rows) {
|
|
160
|
+
const isView = String(row.table_type) === "VIEW";
|
|
161
|
+
if (isView && !wantsView)
|
|
162
|
+
continue;
|
|
163
|
+
if (!isView && !wantsTable)
|
|
164
|
+
continue;
|
|
165
|
+
objects.push({ schema, name: String(row.table_name), kind: isView ? "view" : "table", type: String(row.table_type) });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (wantsFunction) {
|
|
169
|
+
const routines = await client.query("SELECT routine_name, routine_type FROM information_schema.routines WHERE routine_schema = $1 ORDER BY routine_name", [schema]);
|
|
170
|
+
for (const row of routines.rows) {
|
|
171
|
+
const isProcedure = String(row.routine_type) === "PROCEDURE";
|
|
172
|
+
objects.push({ schema, name: String(row.routine_name), kind: isProcedure ? "procedure" : "function", type: String(row.routine_type) });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const search = options.search?.trim().toLowerCase();
|
|
176
|
+
return search ? objects.filter((object) => object.name.toLowerCase().includes(search)) : objects;
|
|
177
|
+
}
|
|
178
|
+
async listColumns(schema, table) {
|
|
179
|
+
const client = await this.getClient();
|
|
180
|
+
const columnsResult = await client.query(`SELECT c.column_name, c.data_type, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.ordinal_position,
|
|
181
|
+
(SELECT pgd.description
|
|
182
|
+
FROM pg_catalog.pg_description pgd
|
|
183
|
+
JOIN pg_catalog.pg_class cls ON cls.oid = pgd.objoid
|
|
184
|
+
JOIN pg_catalog.pg_namespace ns ON ns.oid = cls.relnamespace
|
|
185
|
+
WHERE ns.nspname = c.table_schema AND cls.relname = c.table_name AND pgd.objsubid = c.ordinal_position) AS column_comment
|
|
186
|
+
FROM information_schema.columns c
|
|
187
|
+
WHERE c.table_schema = $1 AND c.table_name = $2
|
|
188
|
+
ORDER BY c.ordinal_position`, [schema, table]);
|
|
189
|
+
const primaryKeyResult = await client.query(`SELECT kcu.column_name
|
|
190
|
+
FROM information_schema.table_constraints tc
|
|
191
|
+
JOIN information_schema.key_column_usage kcu
|
|
192
|
+
ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
193
|
+
WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_schema = $1 AND tc.table_name = $2`, [schema, table]);
|
|
194
|
+
const primaryKeyColumns = new Set(primaryKeyResult.rows.map((row) => String(row.column_name)));
|
|
195
|
+
return columnsResult.rows.map((row) => ({
|
|
196
|
+
name: String(row.column_name),
|
|
197
|
+
dataType: String(row.data_type),
|
|
198
|
+
length: row.character_maximum_length === null ? undefined : Number(row.character_maximum_length),
|
|
199
|
+
scale: row.numeric_scale === null ? undefined : Number(row.numeric_scale),
|
|
200
|
+
nullable: String(row.is_nullable).toUpperCase() === "YES",
|
|
201
|
+
defaultValue: row.column_default === null ? undefined : String(row.column_default),
|
|
202
|
+
isPrimaryKey: primaryKeyColumns.has(String(row.column_name)),
|
|
203
|
+
comment: row.column_comment === null || row.column_comment === undefined ? undefined : String(row.column_comment),
|
|
204
|
+
position: Number(row.ordinal_position),
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
async listIndexes(schema, table) {
|
|
208
|
+
const client = await this.getClient();
|
|
209
|
+
const result = await client.query("SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = $1 AND tablename = $2", [schema, table]);
|
|
210
|
+
return result.rows.map((row) => {
|
|
211
|
+
const name = String(row.indexname);
|
|
212
|
+
const definition = String(row.indexdef);
|
|
213
|
+
const columnMatch = definition.match(/\(([^)]+)\)/);
|
|
214
|
+
const columns = columnMatch ? columnMatch[1].split(",").map((column) => column.trim().replace(/"/g, "")) : [];
|
|
215
|
+
return {
|
|
216
|
+
name,
|
|
217
|
+
columns,
|
|
218
|
+
isUnique: /\bUNIQUE\b/i.test(definition),
|
|
219
|
+
isPrimaryKey: name.endsWith("_pkey"),
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async countRows(schema, table) {
|
|
224
|
+
const client = await this.getClient();
|
|
225
|
+
const result = await client.query(`SELECT COUNT(*) AS count FROM ${(0, db_metadata_1.buildQualifiedName)(this.type, schema, table)}`);
|
|
226
|
+
return Number(result.rows[0]?.count ?? 0);
|
|
227
|
+
}
|
|
228
|
+
async getTableData(options) {
|
|
229
|
+
const qualifiedName = (0, db_metadata_1.buildQualifiedName)(this.type, options.schema, options.table);
|
|
230
|
+
const whereClause = options.where?.trim() ? ` WHERE ${options.where.trim()}` : "";
|
|
231
|
+
const orderClause = options.orderBy?.trim()
|
|
232
|
+
? ` ORDER BY ${(0, db_metadata_1.quoteIdentifier)(this.type, options.orderBy.trim())} ${options.orderDirection === "desc" ? "DESC" : "ASC"}`
|
|
233
|
+
: "";
|
|
234
|
+
const sql = `SELECT * FROM ${qualifiedName}${whereClause}${orderClause} LIMIT ${options.limit} OFFSET ${options.offset}`;
|
|
235
|
+
return this.runQuery(sql, { maxRows: options.limit });
|
|
236
|
+
}
|
|
237
|
+
quoteIdentifier(identifier) {
|
|
238
|
+
return (0, db_metadata_1.quoteIdentifier)(this.type, identifier);
|
|
239
|
+
}
|
|
240
|
+
buildQualifiedName(schema, name) {
|
|
241
|
+
return (0, db_metadata_1.buildQualifiedName)(this.type, schema, name);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.PostgresAdapter = PostgresAdapter;
|
|
245
|
+
//# sourceMappingURL=db-postgres-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-postgres-adapter.js","sourceRoot":"","sources":["../../../src/core/db/db-postgres-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TDatabaseType, TSavedQuery } from "./db-types";
|
|
2
|
+
export type TSaveQueryInput = {
|
|
3
|
+
id?: string;
|
|
4
|
+
name: string;
|
|
5
|
+
sql: string;
|
|
6
|
+
connectionType?: TDatabaseType;
|
|
7
|
+
connectionId?: string;
|
|
8
|
+
tags?: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare function listSavedQueries(): Promise<TSavedQuery[]>;
|
|
11
|
+
export declare function getSavedQuery(id: string): Promise<TSavedQuery | undefined>;
|
|
12
|
+
export declare function saveQuery(input: TSaveQueryInput): Promise<TSavedQuery>;
|
|
13
|
+
export declare function renameSavedQuery(id: string, name: string): Promise<TSavedQuery>;
|
|
14
|
+
export declare function deleteSavedQuery(id: string): Promise<boolean>;
|
|
15
|
+
export declare function exportSavedQueryToSql(id: string, targetDirectory: string): Promise<string>;
|
|
16
|
+
export declare function importSqlFile(filePath: string, options?: {
|
|
17
|
+
name?: string;
|
|
18
|
+
tags?: string[];
|
|
19
|
+
}): Promise<TSavedQuery>;
|
|
20
|
+
export declare function getQueriesDirectory(): string;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listSavedQueries = listSavedQueries;
|
|
7
|
+
exports.getSavedQuery = getSavedQuery;
|
|
8
|
+
exports.saveQuery = saveQuery;
|
|
9
|
+
exports.renameSavedQuery = renameSavedQuery;
|
|
10
|
+
exports.deleteSavedQuery = deleteSavedQuery;
|
|
11
|
+
exports.exportSavedQueryToSql = exportSavedQueryToSql;
|
|
12
|
+
exports.importSqlFile = importSqlFile;
|
|
13
|
+
exports.getQueriesDirectory = getQueriesDirectory;
|
|
14
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
17
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
|
+
const QUERIES_DIRECTORY = node_path_1.default.join(node_os_1.default.homedir(), ".simplemdg", "db-queries");
|
|
19
|
+
function queryFilePath(id) {
|
|
20
|
+
return node_path_1.default.join(QUERIES_DIRECTORY, `${id}.json`);
|
|
21
|
+
}
|
|
22
|
+
function sanitizeFileBaseName(name) {
|
|
23
|
+
return name.replace(/[^a-z0-9-_]+/gi, "-").replace(/^-+|-+$/g, "").toLowerCase() || "query";
|
|
24
|
+
}
|
|
25
|
+
async function listSavedQueries() {
|
|
26
|
+
if (!(await fs_extra_1.default.pathExists(QUERIES_DIRECTORY))) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const entries = await fs_extra_1.default.readdir(QUERIES_DIRECTORY);
|
|
30
|
+
const queries = [];
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (!entry.endsWith(".json")) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const parsed = await fs_extra_1.default.readJson(node_path_1.default.join(QUERIES_DIRECTORY, entry)).catch(() => undefined);
|
|
36
|
+
if (parsed?.id && typeof parsed.sql === "string") {
|
|
37
|
+
queries.push(parsed);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return queries.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
41
|
+
}
|
|
42
|
+
async function getSavedQuery(id) {
|
|
43
|
+
const filePath = queryFilePath(id);
|
|
44
|
+
if (!(await fs_extra_1.default.pathExists(filePath))) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return await fs_extra_1.default.readJson(filePath).catch(() => undefined);
|
|
48
|
+
}
|
|
49
|
+
async function saveQuery(input) {
|
|
50
|
+
await fs_extra_1.default.ensureDir(QUERIES_DIRECTORY);
|
|
51
|
+
const now = new Date().toISOString();
|
|
52
|
+
const existing = input.id ? await getSavedQuery(input.id) : undefined;
|
|
53
|
+
const query = {
|
|
54
|
+
id: existing?.id ?? input.id ?? node_crypto_1.default.randomUUID(),
|
|
55
|
+
name: input.name.trim() || "Untitled query",
|
|
56
|
+
sql: input.sql,
|
|
57
|
+
connectionType: input.connectionType ?? existing?.connectionType,
|
|
58
|
+
connectionId: input.connectionId ?? existing?.connectionId,
|
|
59
|
+
tags: input.tags ?? existing?.tags ?? [],
|
|
60
|
+
createdAt: existing?.createdAt ?? now,
|
|
61
|
+
updatedAt: now,
|
|
62
|
+
};
|
|
63
|
+
await fs_extra_1.default.writeJson(queryFilePath(query.id), query, { spaces: 2 });
|
|
64
|
+
return query;
|
|
65
|
+
}
|
|
66
|
+
async function renameSavedQuery(id, name) {
|
|
67
|
+
const query = await getSavedQuery(id);
|
|
68
|
+
if (!query) {
|
|
69
|
+
throw new Error(`Saved query not found: ${id}`);
|
|
70
|
+
}
|
|
71
|
+
query.name = name.trim() || query.name;
|
|
72
|
+
query.updatedAt = new Date().toISOString();
|
|
73
|
+
await fs_extra_1.default.writeJson(queryFilePath(id), query, { spaces: 2 });
|
|
74
|
+
return query;
|
|
75
|
+
}
|
|
76
|
+
async function deleteSavedQuery(id) {
|
|
77
|
+
const filePath = queryFilePath(id);
|
|
78
|
+
if (!(await fs_extra_1.default.pathExists(filePath))) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
await fs_extra_1.default.remove(filePath);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
async function exportSavedQueryToSql(id, targetDirectory) {
|
|
85
|
+
const query = await getSavedQuery(id);
|
|
86
|
+
if (!query) {
|
|
87
|
+
throw new Error(`Saved query not found: ${id}`);
|
|
88
|
+
}
|
|
89
|
+
await fs_extra_1.default.ensureDir(targetDirectory);
|
|
90
|
+
const targetPath = node_path_1.default.join(targetDirectory, `${sanitizeFileBaseName(query.name)}.sql`);
|
|
91
|
+
await fs_extra_1.default.writeFile(targetPath, query.sql, "utf8");
|
|
92
|
+
return targetPath;
|
|
93
|
+
}
|
|
94
|
+
async function importSqlFile(filePath, options) {
|
|
95
|
+
const resolvedPath = node_path_1.default.resolve(filePath);
|
|
96
|
+
if (!(await fs_extra_1.default.pathExists(resolvedPath))) {
|
|
97
|
+
throw new Error(`SQL file not found: ${resolvedPath}`);
|
|
98
|
+
}
|
|
99
|
+
const sql = await fs_extra_1.default.readFile(resolvedPath, "utf8");
|
|
100
|
+
const name = options?.name?.trim() || node_path_1.default.basename(resolvedPath, node_path_1.default.extname(resolvedPath));
|
|
101
|
+
return saveQuery({ name, sql, tags: options?.tags });
|
|
102
|
+
}
|
|
103
|
+
function getQueriesDirectory() {
|
|
104
|
+
return QUERIES_DIRECTORY;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=db-query-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-query-files.js","sourceRoot":"","sources":["../../../src/core/db/db-query-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TQueryHistoryItem } from "./db-types";
|
|
2
|
+
export declare function appendQueryHistory(item: Omit<TQueryHistoryItem, "id" | "timestamp">): Promise<TQueryHistoryItem>;
|
|
3
|
+
export declare function listQueryHistory(limit?: number): Promise<TQueryHistoryItem[]>;
|
|
4
|
+
export declare function clearQueryHistory(): Promise<void>;
|
|
5
|
+
export declare function getHistoryFilePath(): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.appendQueryHistory = appendQueryHistory;
|
|
7
|
+
exports.listQueryHistory = listQueryHistory;
|
|
8
|
+
exports.clearQueryHistory = clearQueryHistory;
|
|
9
|
+
exports.getHistoryFilePath = getHistoryFilePath;
|
|
10
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
13
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
14
|
+
const CACHE_DIRECTORY = node_path_1.default.join(node_os_1.default.homedir(), ".simplemdg");
|
|
15
|
+
const HISTORY_FILE_PATH = node_path_1.default.join(CACHE_DIRECTORY, "db-query-history.json");
|
|
16
|
+
const MAX_HISTORY_ITEMS = 300;
|
|
17
|
+
async function readHistoryFile() {
|
|
18
|
+
if (!(await fs_extra_1.default.pathExists(HISTORY_FILE_PATH))) {
|
|
19
|
+
return { items: [] };
|
|
20
|
+
}
|
|
21
|
+
const parsed = await fs_extra_1.default.readJson(HISTORY_FILE_PATH).catch(() => ({ items: [] }));
|
|
22
|
+
return { items: Array.isArray(parsed.items) ? parsed.items : [] };
|
|
23
|
+
}
|
|
24
|
+
async function writeHistoryFile(file) {
|
|
25
|
+
await fs_extra_1.default.ensureDir(CACHE_DIRECTORY);
|
|
26
|
+
await fs_extra_1.default.writeJson(HISTORY_FILE_PATH, file, { spaces: 2 });
|
|
27
|
+
}
|
|
28
|
+
async function appendQueryHistory(item) {
|
|
29
|
+
const file = await readHistoryFile();
|
|
30
|
+
const entry = {
|
|
31
|
+
...item,
|
|
32
|
+
id: node_crypto_1.default.randomUUID(),
|
|
33
|
+
timestamp: new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
file.items = [entry, ...file.items].slice(0, MAX_HISTORY_ITEMS);
|
|
36
|
+
await writeHistoryFile(file);
|
|
37
|
+
return entry;
|
|
38
|
+
}
|
|
39
|
+
async function listQueryHistory(limit = 100) {
|
|
40
|
+
const file = await readHistoryFile();
|
|
41
|
+
return file.items.slice(0, limit);
|
|
42
|
+
}
|
|
43
|
+
async function clearQueryHistory() {
|
|
44
|
+
await writeHistoryFile({ items: [] });
|
|
45
|
+
}
|
|
46
|
+
function getHistoryFilePath() {
|
|
47
|
+
return HISTORY_FILE_PATH;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=db-query-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-query-history.js","sourceRoot":"","sources":["../../../src/core/db/db-query-history.ts"],"names":[],"mappings":";;;;;AA4BA,gDAWC;AAED,4CAGC;AAED,8CAEC;AAED,gDAEC;AApDD,sDAAyB;AACzB,0DAA6B;AAC7B,8DAAiC;AACjC,wDAA0B;AAG1B,MAAM,eAAe,GAAG,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC9D,MAAM,iBAAiB,GAAG,mBAAI,CAAC,IAAI,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;AAC9E,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAM9B,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAA0B,CAAC;IAC1G,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAkB;IAChD,MAAM,kBAAE,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACpC,MAAM,kBAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,IAAiD;IACxF,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IACrC,MAAM,KAAK,GAAsB;QAC/B,GAAG,IAAI;QACP,EAAE,EAAE,qBAAM,CAAC,UAAU,EAAE;QACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAChE,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,KAAK,GAAG,GAAG;IAChD,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAEM,KAAK,UAAU,iBAAiB;IACrC,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,kBAAkB;IAChC,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
|