exisjs 0.5.9 → 0.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +4 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/oauth/core.d.ts +96 -0
- package/dist/auth/oauth/core.d.ts.map +1 -0
- package/dist/auth/oauth/core.js +203 -0
- package/dist/auth/oauth/core.js.map +1 -0
- package/dist/auth/oauth/index.d.ts +45 -0
- package/dist/auth/oauth/index.d.ts.map +1 -0
- package/dist/auth/oauth/index.js +64 -0
- package/dist/auth/oauth/index.js.map +1 -0
- package/dist/auth/oauth/middleware.d.ts +63 -0
- package/dist/auth/oauth/middleware.d.ts.map +1 -0
- package/dist/auth/oauth/middleware.js +164 -0
- package/dist/auth/oauth/middleware.js.map +1 -0
- package/dist/auth/oauth/providers/custom.d.ts +41 -0
- package/dist/auth/oauth/providers/custom.d.ts.map +1 -0
- package/dist/auth/oauth/providers/custom.js +204 -0
- package/dist/auth/oauth/providers/custom.js.map +1 -0
- package/dist/auth/oauth/providers/discord.d.ts +23 -0
- package/dist/auth/oauth/providers/discord.d.ts.map +1 -0
- package/dist/auth/oauth/providers/discord.js +130 -0
- package/dist/auth/oauth/providers/discord.js.map +1 -0
- package/dist/auth/oauth/providers/facebook.d.ts +28 -0
- package/dist/auth/oauth/providers/facebook.d.ts.map +1 -0
- package/dist/auth/oauth/providers/facebook.js +124 -0
- package/dist/auth/oauth/providers/facebook.js.map +1 -0
- package/dist/auth/oauth/providers/github.d.ts +25 -0
- package/dist/auth/oauth/providers/github.d.ts.map +1 -0
- package/dist/auth/oauth/providers/github.js +132 -0
- package/dist/auth/oauth/providers/github.js.map +1 -0
- package/dist/auth/oauth/providers/google.d.ts +23 -0
- package/dist/auth/oauth/providers/google.d.ts.map +1 -0
- package/dist/auth/oauth/providers/google.js +134 -0
- package/dist/auth/oauth/providers/google.js.map +1 -0
- package/dist/auth/oauth/providers/microsoft.d.ts +28 -0
- package/dist/auth/oauth/providers/microsoft.d.ts.map +1 -0
- package/dist/auth/oauth/providers/microsoft.js +136 -0
- package/dist/auth/oauth/providers/microsoft.js.map +1 -0
- package/dist/auth/oauth/types.d.ts +158 -0
- package/dist/auth/oauth/types.d.ts.map +1 -0
- package/dist/auth/oauth/types.js +4 -0
- package/dist/auth/oauth/types.js.map +1 -0
- package/dist/auth/session.d.ts +4 -1
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +33 -5
- package/dist/auth/session.js.map +1 -1
- package/dist/cache/store.d.ts +11 -3
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +87 -19
- package/dist/cache/store.js.map +1 -1
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +4 -6
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/database/adapters/mongodb.d.ts +58 -0
- package/dist/database/adapters/mongodb.d.ts.map +1 -0
- package/dist/database/adapters/mongodb.js +264 -0
- package/dist/database/adapters/mongodb.js.map +1 -0
- package/dist/database/adapters/mysql.d.ts +27 -0
- package/dist/database/adapters/mysql.d.ts.map +1 -0
- package/dist/database/adapters/mysql.js +188 -0
- package/dist/database/adapters/mysql.js.map +1 -0
- package/dist/database/adapters/postgres.d.ts +28 -0
- package/dist/database/adapters/postgres.d.ts.map +1 -0
- package/dist/database/adapters/postgres.js +174 -0
- package/dist/database/adapters/postgres.js.map +1 -0
- package/dist/database/adapters/sqlite.d.ts +27 -0
- package/dist/database/adapters/sqlite.d.ts.map +1 -0
- package/dist/database/adapters/sqlite.js +149 -0
- package/dist/database/adapters/sqlite.js.map +1 -0
- package/dist/database/index.d.ts +42 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +58 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/manager.d.ts +114 -0
- package/dist/database/manager.d.ts.map +1 -0
- package/dist/database/manager.js +269 -0
- package/dist/database/manager.js.map +1 -0
- package/dist/database/migration.d.ts +57 -0
- package/dist/database/migration.d.ts.map +1 -0
- package/dist/database/migration.js +329 -0
- package/dist/database/migration.js.map +1 -0
- package/dist/database/query-builder.d.ts +89 -0
- package/dist/database/query-builder.d.ts.map +1 -0
- package/dist/database/query-builder.js +353 -0
- package/dist/database/query-builder.js.map +1 -0
- package/dist/database/types.d.ts +184 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +4 -0
- package/dist/database/types.js.map +1 -0
- package/dist/docs/ARCHITECTURE.md +349 -0
- package/dist/docs/BENCHMARKS.md +36 -0
- package/dist/docs/README.md +34 -0
- package/dist/docs/content/README.md +44 -0
- package/dist/docs/content/adapters.mdx +199 -0
- package/dist/docs/content/cache.mdx +239 -0
- package/dist/docs/content/circuit-breaker.mdx +130 -0
- package/dist/docs/content/cli/commands.mdx +214 -0
- package/dist/docs/content/cli/overview.mdx +92 -0
- package/dist/docs/content/cli/usage.mdx +61 -0
- package/dist/docs/content/config.mdx +214 -0
- package/dist/docs/content/controllers.mdx +241 -0
- package/dist/docs/content/cron.mdx +109 -0
- package/dist/docs/content/database.mdx +209 -0
- package/dist/docs/content/dataloader.mdx +170 -0
- package/dist/docs/content/decorators.mdx +204 -0
- package/dist/docs/content/errors.mdx +344 -0
- package/dist/docs/content/gateways.mdx +376 -0
- package/dist/docs/content/installation.mdx +210 -0
- package/dist/docs/content/introduction.mdx +96 -0
- package/dist/docs/content/middleware.mdx +441 -0
- package/dist/docs/content/modules.mdx +144 -0
- package/dist/docs/content/oauth.mdx +179 -0
- package/dist/docs/content/providers.mdx +147 -0
- package/dist/docs/content/queues.mdx +177 -0
- package/dist/docs/content/requests.mdx +293 -0
- package/dist/docs/content/responses.mdx +271 -0
- package/dist/docs/content/routing.mdx +541 -0
- package/dist/docs/content/rpc.mdx +146 -0
- package/dist/docs/content/security.mdx +294 -0
- package/dist/docs/content/sse.mdx +159 -0
- package/dist/docs/content/structure.mdx +116 -0
- package/dist/docs/content/testing.mdx +139 -0
- package/dist/docs/content/validation.mdx +249 -0
- package/dist/docs/content/websockets.mdx +289 -0
- package/dist/docs/integrations/README.md +23 -0
- package/dist/docs/integrations/jwt.mdx +151 -0
- package/dist/docs/integrations/mongo.mdx +183 -0
- package/dist/docs/integrations/observability.mdx +125 -0
- package/dist/docs/integrations/openai.mdx +108 -0
- package/dist/docs/integrations/postgres.mdx +190 -0
- package/dist/docs/integrations/posthog.mdx +122 -0
- package/dist/docs/integrations/redis.mdx +141 -0
- package/dist/docs/integrations/resend.mdx +117 -0
- package/dist/docs/integrations/s3.mdx +122 -0
- package/dist/docs/integrations/swagger.mdx +113 -0
- package/dist/docs/reference/README.md +3 -0
- package/dist/docs/reference/adapters.mdx +130 -0
- package/dist/docs/reference/auth.mdx +183 -0
- package/dist/docs/reference/cache.mdx +132 -0
- package/dist/docs/reference/circuit-breaker.mdx +71 -0
- package/dist/docs/reference/config.mdx +118 -0
- package/dist/docs/reference/context.mdx +168 -0
- package/dist/docs/reference/dataloader.mdx +91 -0
- package/dist/docs/reference/decorators.mdx +293 -0
- package/dist/docs/reference/di.mdx +123 -0
- package/dist/docs/reference/error.mdx +170 -0
- package/dist/docs/reference/exis.mdx +124 -0
- package/dist/docs/reference/middleware.mdx +304 -0
- package/dist/docs/reference/plugin.mdx +113 -0
- package/dist/docs/reference/queue.mdx +155 -0
- package/dist/docs/reference/router.mdx +248 -0
- package/dist/docs/reference/sanitize.mdx +130 -0
- package/dist/docs/reference/storage.mdx +116 -0
- package/dist/docs/reference/swagger.mdx +132 -0
- package/dist/docs/reference/testing.mdx +145 -0
- package/dist/docs/reference/validator.mdx +186 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/backpressure.d.ts.map +1 -1
- package/dist/middleware/backpressure.js +21 -12
- package/dist/middleware/backpressure.js.map +1 -1
- package/dist/middleware/cache.d.ts +6 -0
- package/dist/middleware/cache.d.ts.map +1 -1
- package/dist/middleware/cache.js +84 -28
- package/dist/middleware/cache.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +4 -1
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +29 -4
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/ip-filter.d.ts.map +1 -1
- package/dist/middleware/ip-filter.js +16 -0
- package/dist/middleware/ip-filter.js.map +1 -1
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +29 -12
- package/dist/middleware/rate-limit.js.map +1 -1
- package/dist/queue/drivers/MemoryDriver.d.ts +6 -3
- package/dist/queue/drivers/MemoryDriver.d.ts.map +1 -1
- package/dist/queue/drivers/MemoryDriver.js +76 -23
- package/dist/queue/drivers/MemoryDriver.js.map +1 -1
- package/dist/server/bootstrapper.d.ts +3 -0
- package/dist/server/bootstrapper.d.ts.map +1 -1
- package/dist/server/bootstrapper.js +56 -8
- package/dist/server/bootstrapper.js.map +1 -1
- package/dist/server/bun-adapter.d.ts +2 -0
- package/dist/server/bun-adapter.d.ts.map +1 -1
- package/dist/server/bun-adapter.js +23 -12
- package/dist/server/bun-adapter.js.map +1 -1
- package/dist/server/request-handler.d.ts +0 -2
- package/dist/server/request-handler.d.ts.map +1 -1
- package/dist/server/request-handler.js +2 -24
- package/dist/server/request-handler.js.map +1 -1
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +24 -11
- package/dist/server/request.js.map +1 -1
- package/dist/server/uws-adapter.d.ts +80 -0
- package/dist/server/uws-adapter.d.ts.map +1 -0
- package/dist/server/uws-adapter.js +357 -0
- package/dist/server/uws-adapter.js.map +1 -0
- package/dist/server/ws-orchestrator.d.ts +1 -0
- package/dist/server/ws-orchestrator.d.ts.map +1 -1
- package/dist/server/ws-orchestrator.js +83 -0
- package/dist/server/ws-orchestrator.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/validator/tex.d.ts +21 -16
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js.map +1 -1
- package/package.json +11 -3
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PostgreSQL Database Adapter.
|
|
4
|
+
*
|
|
5
|
+
* Uses the `postgres` (postgres.js) npm package for high-performance connection pooling,
|
|
6
|
+
* parameterized queries, and transaction support.
|
|
7
|
+
*
|
|
8
|
+
* Peer Dependencies required:
|
|
9
|
+
* npm install postgres
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PostgresAdapter = void 0;
|
|
13
|
+
class PostgresAdapter {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.dialect = 'postgres';
|
|
16
|
+
this.client = null;
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
let postgres;
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
postgres = require('postgres');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error('Missing dependency. Please run: npm install postgres');
|
|
27
|
+
}
|
|
28
|
+
const url = this.config.url || this.buildConnectionUrl();
|
|
29
|
+
const poolConfig = this.config.pool || {};
|
|
30
|
+
this.client = postgres(url, {
|
|
31
|
+
max: poolConfig.max ?? 10,
|
|
32
|
+
idle_timeout: poolConfig.idleTimeoutMs
|
|
33
|
+
? poolConfig.idleTimeoutMs / 1000
|
|
34
|
+
: 30,
|
|
35
|
+
connect_timeout: this.config.connectTimeoutMs
|
|
36
|
+
? this.config.connectTimeoutMs / 1000
|
|
37
|
+
: 5,
|
|
38
|
+
ssl: this.config.ssl === true
|
|
39
|
+
? { rejectUnauthorized: process.env.NODE_ENV === 'production' }
|
|
40
|
+
: typeof this.config.ssl === 'object'
|
|
41
|
+
? this.config.ssl
|
|
42
|
+
: undefined,
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
44
|
+
onnotice: () => { }, // Suppress notices
|
|
45
|
+
});
|
|
46
|
+
// Test the connection
|
|
47
|
+
await this.client `SELECT 1`;
|
|
48
|
+
this.log('PostgreSQL connection established');
|
|
49
|
+
}
|
|
50
|
+
async disconnect() {
|
|
51
|
+
if (this.client) {
|
|
52
|
+
await this.client.end();
|
|
53
|
+
this.client = null;
|
|
54
|
+
this.log('PostgreSQL connection closed');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async query(sql, params = []) {
|
|
58
|
+
this.ensureConnected();
|
|
59
|
+
this.logQuery(sql, params);
|
|
60
|
+
const result = await this.client.unsafe(sql, params);
|
|
61
|
+
const fields = result.columns
|
|
62
|
+
? result.columns.map((col) => ({
|
|
63
|
+
name: col.name,
|
|
64
|
+
dataType: col.type?.toString(),
|
|
65
|
+
tableId: col.table,
|
|
66
|
+
}))
|
|
67
|
+
: [];
|
|
68
|
+
return {
|
|
69
|
+
rows: Array.from(result),
|
|
70
|
+
rowCount: result.length,
|
|
71
|
+
fields,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async execute(sql, params = []) {
|
|
75
|
+
this.ensureConnected();
|
|
76
|
+
this.logQuery(sql, params);
|
|
77
|
+
const result = await this.client.unsafe(sql, params);
|
|
78
|
+
return {
|
|
79
|
+
affectedRows: result.count ?? 0,
|
|
80
|
+
insertId: result[0]?.id,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async transaction(fn) {
|
|
84
|
+
this.ensureConnected();
|
|
85
|
+
return this.client.begin(async (sql) => {
|
|
86
|
+
const tx = {
|
|
87
|
+
query: async (queryStr, params = []) => {
|
|
88
|
+
this.logQuery(queryStr, params);
|
|
89
|
+
const result = await sql.unsafe(queryStr, params);
|
|
90
|
+
const fields = result.columns
|
|
91
|
+
? result.columns.map((col) => ({
|
|
92
|
+
name: col.name,
|
|
93
|
+
dataType: col.type?.toString(),
|
|
94
|
+
tableId: col.table,
|
|
95
|
+
}))
|
|
96
|
+
: [];
|
|
97
|
+
return {
|
|
98
|
+
rows: Array.from(result),
|
|
99
|
+
rowCount: result.length,
|
|
100
|
+
fields,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
execute: async (queryStr, params = []) => {
|
|
104
|
+
this.logQuery(queryStr, params);
|
|
105
|
+
const result = await sql.unsafe(queryStr, params);
|
|
106
|
+
return {
|
|
107
|
+
affectedRows: result.count ?? 0,
|
|
108
|
+
insertId: result[0]?.id,
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
savepoint: async (name) => {
|
|
112
|
+
await sql.unsafe(`SAVEPOINT ${name}`);
|
|
113
|
+
},
|
|
114
|
+
rollbackTo: async (name) => {
|
|
115
|
+
await sql.unsafe(`ROLLBACK TO SAVEPOINT ${name}`);
|
|
116
|
+
},
|
|
117
|
+
commit: async () => {
|
|
118
|
+
// postgres.js handles commit automatically when the callback resolves
|
|
119
|
+
},
|
|
120
|
+
rollback: async () => {
|
|
121
|
+
throw new Error('ROLLBACK');
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
return fn(tx);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async isHealthy() {
|
|
128
|
+
try {
|
|
129
|
+
this.ensureConnected();
|
|
130
|
+
await this.client `SELECT 1`;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
getRawClient() {
|
|
138
|
+
return this.client;
|
|
139
|
+
}
|
|
140
|
+
// ─── Private Helpers ───────────────────────────────────────────────────────
|
|
141
|
+
ensureConnected() {
|
|
142
|
+
if (!this.client) {
|
|
143
|
+
throw new Error('PostgreSQL adapter is not connected. Call connect() first.');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
buildConnectionUrl() {
|
|
147
|
+
const { host, port, database, username, password } = this.config;
|
|
148
|
+
if (!host || !database) {
|
|
149
|
+
throw new Error('PostgreSQL requires either a `url` or `host` + `database` in the config.');
|
|
150
|
+
}
|
|
151
|
+
const auth = username
|
|
152
|
+
? password
|
|
153
|
+
? `${encodeURIComponent(username)}:${encodeURIComponent(password)}@`
|
|
154
|
+
: `${encodeURIComponent(username)}@`
|
|
155
|
+
: '';
|
|
156
|
+
return `postgres://${auth}${host}:${port || 5432}/${database}`;
|
|
157
|
+
}
|
|
158
|
+
logQuery(sql, params) {
|
|
159
|
+
if (!this.config.logging)
|
|
160
|
+
return;
|
|
161
|
+
if (typeof this.config.logging === 'function') {
|
|
162
|
+
this.config.logging(sql, params);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
log(message) {
|
|
166
|
+
if (!this.config.logging)
|
|
167
|
+
return;
|
|
168
|
+
if (typeof this.config.logging === 'function') {
|
|
169
|
+
this.config.logging(message);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.PostgresAdapter = PostgresAdapter;
|
|
174
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/database/adapters/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Database Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Uses the `better-sqlite3` npm package for high-performance synchronous
|
|
5
|
+
* SQLite operations, wrapped in an async interface for consistency.
|
|
6
|
+
*
|
|
7
|
+
* Peer Dependencies required:
|
|
8
|
+
* npm install better-sqlite3
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseAdapter, DatabaseConfig, QueryResult, ExecuteResult, Transaction } from '../types';
|
|
11
|
+
export declare class SqliteAdapter implements DatabaseAdapter {
|
|
12
|
+
readonly dialect: "sqlite";
|
|
13
|
+
private db;
|
|
14
|
+
private config;
|
|
15
|
+
constructor(config: DatabaseConfig);
|
|
16
|
+
connect(): Promise<void>;
|
|
17
|
+
disconnect(): Promise<void>;
|
|
18
|
+
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
19
|
+
execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
|
|
20
|
+
transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T>;
|
|
21
|
+
isHealthy(): Promise<boolean>;
|
|
22
|
+
getRawClient(): unknown;
|
|
23
|
+
private ensureConnected;
|
|
24
|
+
private logQuery;
|
|
25
|
+
private log;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,aAAa,EACb,WAAW,EAEZ,MAAM,UAAU,CAAA;AAEjB,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,OAAO,EAAG,QAAQ,CAAS;IAEpC,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,cAAc;IAI5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,GACrB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAqBpB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAepE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoD/D,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAUnC,YAAY,IAAI,OAAO;IAMvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,GAAG;CAMZ"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQLite Database Adapter.
|
|
4
|
+
*
|
|
5
|
+
* Uses the `better-sqlite3` npm package for high-performance synchronous
|
|
6
|
+
* SQLite operations, wrapped in an async interface for consistency.
|
|
7
|
+
*
|
|
8
|
+
* Peer Dependencies required:
|
|
9
|
+
* npm install better-sqlite3
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SqliteAdapter = void 0;
|
|
13
|
+
class SqliteAdapter {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.dialect = 'sqlite';
|
|
16
|
+
this.db = null;
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
let Database;
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
Database = require('better-sqlite3');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error('Missing dependency. Please run: npm install better-sqlite3');
|
|
27
|
+
}
|
|
28
|
+
const filename = this.config.filename || this.config.database || ':memory:';
|
|
29
|
+
this.db = new Database(filename, {
|
|
30
|
+
timeout: this.config.connectTimeoutMs ?? 5000,
|
|
31
|
+
});
|
|
32
|
+
// Enable WAL mode for better concurrency
|
|
33
|
+
this.db.pragma('journal_mode = WAL');
|
|
34
|
+
// Enable foreign keys
|
|
35
|
+
this.db.pragma('foreign_keys = ON');
|
|
36
|
+
this.log(`SQLite connection established (${filename})`);
|
|
37
|
+
}
|
|
38
|
+
async disconnect() {
|
|
39
|
+
if (this.db) {
|
|
40
|
+
this.db.close();
|
|
41
|
+
this.db = null;
|
|
42
|
+
this.log('SQLite connection closed');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async query(sql, params = []) {
|
|
46
|
+
this.ensureConnected();
|
|
47
|
+
this.logQuery(sql, params);
|
|
48
|
+
const stmt = this.db.prepare(sql);
|
|
49
|
+
const rows = stmt.all(...params);
|
|
50
|
+
const fields = stmt.columns
|
|
51
|
+
? stmt.columns().map((col) => ({
|
|
52
|
+
name: col.name,
|
|
53
|
+
dataType: col.type || undefined,
|
|
54
|
+
}))
|
|
55
|
+
: [];
|
|
56
|
+
return {
|
|
57
|
+
rows,
|
|
58
|
+
rowCount: rows.length,
|
|
59
|
+
fields,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async execute(sql, params = []) {
|
|
63
|
+
this.ensureConnected();
|
|
64
|
+
this.logQuery(sql, params);
|
|
65
|
+
const stmt = this.db.prepare(sql);
|
|
66
|
+
const result = stmt.run(...params);
|
|
67
|
+
return {
|
|
68
|
+
affectedRows: result.changes,
|
|
69
|
+
insertId: result.lastInsertRowid
|
|
70
|
+
? Number(result.lastInsertRowid)
|
|
71
|
+
: undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async transaction(fn) {
|
|
75
|
+
this.ensureConnected();
|
|
76
|
+
// better-sqlite3 has synchronous transactions, but we wrap for async consistency
|
|
77
|
+
const tx = {
|
|
78
|
+
query: async (queryStr, params = []) => {
|
|
79
|
+
return this.query(queryStr, params);
|
|
80
|
+
},
|
|
81
|
+
execute: async (queryStr, params = []) => {
|
|
82
|
+
return this.execute(queryStr, params);
|
|
83
|
+
},
|
|
84
|
+
savepoint: async (name) => {
|
|
85
|
+
this.db.exec(`SAVEPOINT ${name}`);
|
|
86
|
+
},
|
|
87
|
+
rollbackTo: async (name) => {
|
|
88
|
+
this.db.exec(`ROLLBACK TO SAVEPOINT ${name}`);
|
|
89
|
+
},
|
|
90
|
+
commit: async () => {
|
|
91
|
+
// Handled by the wrapping transaction
|
|
92
|
+
},
|
|
93
|
+
rollback: async () => {
|
|
94
|
+
throw new Error('ROLLBACK');
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
// Use better-sqlite3's transaction wrapper for atomic execution
|
|
98
|
+
try {
|
|
99
|
+
this.db.exec('BEGIN');
|
|
100
|
+
const result = await fn(tx);
|
|
101
|
+
this.db.exec('COMMIT');
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
try {
|
|
106
|
+
this.db.exec('ROLLBACK');
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Already rolled back
|
|
110
|
+
}
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async isHealthy() {
|
|
115
|
+
try {
|
|
116
|
+
this.ensureConnected();
|
|
117
|
+
this.db.prepare('SELECT 1').get();
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
getRawClient() {
|
|
125
|
+
return this.db;
|
|
126
|
+
}
|
|
127
|
+
// ─── Private Helpers ───────────────────────────────────────────────────────
|
|
128
|
+
ensureConnected() {
|
|
129
|
+
if (!this.db) {
|
|
130
|
+
throw new Error('SQLite adapter is not connected. Call connect() first.');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
logQuery(sql, params) {
|
|
134
|
+
if (!this.config.logging)
|
|
135
|
+
return;
|
|
136
|
+
if (typeof this.config.logging === 'function') {
|
|
137
|
+
this.config.logging(sql, params);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
log(message) {
|
|
141
|
+
if (!this.config.logging)
|
|
142
|
+
return;
|
|
143
|
+
if (typeof this.config.logging === 'function') {
|
|
144
|
+
this.config.logging(message);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.SqliteAdapter = SqliteAdapter;
|
|
149
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/database/adapters/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExisJS Database Layer
|
|
3
|
+
*
|
|
4
|
+
* A unified database abstraction providing connection pooling, query building,
|
|
5
|
+
* transactions, migrations, and multi-dialect support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createDatabase, db } from 'exisjs/database'
|
|
10
|
+
*
|
|
11
|
+
* const database = createDatabase({
|
|
12
|
+
* dialect: 'postgres',
|
|
13
|
+
* url: process.env.DATABASE_URL,
|
|
14
|
+
* })
|
|
15
|
+
* await database.connect()
|
|
16
|
+
*
|
|
17
|
+
* // Raw queries
|
|
18
|
+
* const users = await db.query<User>('SELECT * FROM users WHERE role = $1', ['admin'])
|
|
19
|
+
*
|
|
20
|
+
* // Query builder
|
|
21
|
+
* const admins = await db.table('users').where('role', '=', 'admin').rows()
|
|
22
|
+
*
|
|
23
|
+
* // Transactions
|
|
24
|
+
* await db.transaction(async (tx) => {
|
|
25
|
+
* await tx.execute('INSERT INTO orders ...', [...])
|
|
26
|
+
* await tx.execute('UPDATE inventory ...', [...])
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* // Migrations
|
|
30
|
+
* const migrator = db.getMigrator({ directory: './migrations' })
|
|
31
|
+
* await migrator.up()
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export { DatabaseManager, createDatabase, db, setDefaultDatabase, } from './manager';
|
|
35
|
+
export { QueryBuilder } from './query-builder';
|
|
36
|
+
export { Migrator } from './migration';
|
|
37
|
+
export { PostgresAdapter } from './adapters/postgres';
|
|
38
|
+
export { MysqlAdapter } from './adapters/mysql';
|
|
39
|
+
export { SqliteAdapter } from './adapters/sqlite';
|
|
40
|
+
export { MongodbAdapter } from './adapters/mongodb';
|
|
41
|
+
export type { DatabaseDialect, DatabaseConfig, DatabaseAdapter, DatabaseSslConfig, PoolConfig, QueryResult, ExecuteResult, Transaction, FieldInfo, Migration, MigrationConfig, MigrationRecord, WhereOperator, OrderDirection, JoinType, } from './types';
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,EACL,eAAe,EACf,cAAc,EACd,EAAE,EACF,kBAAkB,GACnB,MAAM,WAAW,CAAA;AAGlB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGtC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,EACT,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,GACT,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ExisJS Database Layer
|
|
4
|
+
*
|
|
5
|
+
* A unified database abstraction providing connection pooling, query building,
|
|
6
|
+
* transactions, migrations, and multi-dialect support.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createDatabase, db } from 'exisjs/database'
|
|
11
|
+
*
|
|
12
|
+
* const database = createDatabase({
|
|
13
|
+
* dialect: 'postgres',
|
|
14
|
+
* url: process.env.DATABASE_URL,
|
|
15
|
+
* })
|
|
16
|
+
* await database.connect()
|
|
17
|
+
*
|
|
18
|
+
* // Raw queries
|
|
19
|
+
* const users = await db.query<User>('SELECT * FROM users WHERE role = $1', ['admin'])
|
|
20
|
+
*
|
|
21
|
+
* // Query builder
|
|
22
|
+
* const admins = await db.table('users').where('role', '=', 'admin').rows()
|
|
23
|
+
*
|
|
24
|
+
* // Transactions
|
|
25
|
+
* await db.transaction(async (tx) => {
|
|
26
|
+
* await tx.execute('INSERT INTO orders ...', [...])
|
|
27
|
+
* await tx.execute('UPDATE inventory ...', [...])
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* // Migrations
|
|
31
|
+
* const migrator = db.getMigrator({ directory: './migrations' })
|
|
32
|
+
* await migrator.up()
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MongodbAdapter = exports.SqliteAdapter = exports.MysqlAdapter = exports.PostgresAdapter = exports.Migrator = exports.QueryBuilder = exports.setDefaultDatabase = exports.db = exports.createDatabase = exports.DatabaseManager = void 0;
|
|
37
|
+
// ─── Core ────────────────────────────────────────────────────────────────────
|
|
38
|
+
var manager_1 = require("./manager");
|
|
39
|
+
Object.defineProperty(exports, "DatabaseManager", { enumerable: true, get: function () { return manager_1.DatabaseManager; } });
|
|
40
|
+
Object.defineProperty(exports, "createDatabase", { enumerable: true, get: function () { return manager_1.createDatabase; } });
|
|
41
|
+
Object.defineProperty(exports, "db", { enumerable: true, get: function () { return manager_1.db; } });
|
|
42
|
+
Object.defineProperty(exports, "setDefaultDatabase", { enumerable: true, get: function () { return manager_1.setDefaultDatabase; } });
|
|
43
|
+
// ─── Query Builder ───────────────────────────────────────────────────────────
|
|
44
|
+
var query_builder_1 = require("./query-builder");
|
|
45
|
+
Object.defineProperty(exports, "QueryBuilder", { enumerable: true, get: function () { return query_builder_1.QueryBuilder; } });
|
|
46
|
+
// ─── Migration ───────────────────────────────────────────────────────────────
|
|
47
|
+
var migration_1 = require("./migration");
|
|
48
|
+
Object.defineProperty(exports, "Migrator", { enumerable: true, get: function () { return migration_1.Migrator; } });
|
|
49
|
+
// ─── Adapters ────────────────────────────────────────────────────────────────
|
|
50
|
+
var postgres_1 = require("./adapters/postgres");
|
|
51
|
+
Object.defineProperty(exports, "PostgresAdapter", { enumerable: true, get: function () { return postgres_1.PostgresAdapter; } });
|
|
52
|
+
var mysql_1 = require("./adapters/mysql");
|
|
53
|
+
Object.defineProperty(exports, "MysqlAdapter", { enumerable: true, get: function () { return mysql_1.MysqlAdapter; } });
|
|
54
|
+
var sqlite_1 = require("./adapters/sqlite");
|
|
55
|
+
Object.defineProperty(exports, "SqliteAdapter", { enumerable: true, get: function () { return sqlite_1.SqliteAdapter; } });
|
|
56
|
+
var mongodb_1 = require("./adapters/mongodb");
|
|
57
|
+
Object.defineProperty(exports, "MongodbAdapter", { enumerable: true, get: function () { return mongodb_1.MongodbAdapter; } });
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;;;AAEH,gFAAgF;AAChF,qCAKkB;AAJhB,0GAAA,eAAe,OAAA;AACf,yGAAA,cAAc,OAAA;AACd,6FAAA,EAAE,OAAA;AACF,6GAAA,kBAAkB,OAAA;AAGpB,gFAAgF;AAChF,iDAA8C;AAArC,6GAAA,YAAY,OAAA;AAErB,gFAAgF;AAChF,yCAAsC;AAA7B,qGAAA,QAAQ,OAAA;AAEjB,gFAAgF;AAChF,gDAAqD;AAA5C,2GAAA,eAAe,OAAA;AACxB,0CAA+C;AAAtC,qGAAA,YAAY,OAAA;AACrB,4CAAiD;AAAxC,uGAAA,aAAa,OAAA;AACtB,8CAAmD;AAA1C,yGAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Manager.
|
|
3
|
+
*
|
|
4
|
+
* The central orchestrator for all database connections. Manages named connections,
|
|
5
|
+
* provides lifecycle integration with the ExisJS app (auto-disconnect on shutdown),
|
|
6
|
+
* and exposes the query builder, raw query execution, and migration system.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { db, createDatabase } from 'exisjs/database'
|
|
10
|
+
*
|
|
11
|
+
* // Quick setup
|
|
12
|
+
* const database = createDatabase({ dialect: 'postgres', url: process.env.DATABASE_URL })
|
|
13
|
+
* await database.connect()
|
|
14
|
+
*
|
|
15
|
+
* // Query
|
|
16
|
+
* const users = await database.query<User>('SELECT * FROM users')
|
|
17
|
+
* const admins = await database.table('users').where('role', '=', 'admin').rows()
|
|
18
|
+
*/
|
|
19
|
+
import type { DatabaseAdapter, DatabaseConfig, DatabaseDialect, QueryResult, ExecuteResult, Transaction, MigrationConfig } from './types';
|
|
20
|
+
import { QueryBuilder } from './query-builder';
|
|
21
|
+
import { Migrator } from './migration';
|
|
22
|
+
export declare class DatabaseManager {
|
|
23
|
+
private connections;
|
|
24
|
+
private configs;
|
|
25
|
+
private defaultName;
|
|
26
|
+
private migrator;
|
|
27
|
+
/**
|
|
28
|
+
* Add a named database connection.
|
|
29
|
+
* The first connection added becomes the default.
|
|
30
|
+
*/
|
|
31
|
+
addConnection(config: DatabaseConfig, name?: string): this;
|
|
32
|
+
/**
|
|
33
|
+
* Connect all registered connections (or a specific named connection).
|
|
34
|
+
*/
|
|
35
|
+
connect(name?: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Disconnect all connections (or a specific named connection).
|
|
38
|
+
*/
|
|
39
|
+
disconnect(name?: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Execute a SELECT query on the default (or named) connection.
|
|
42
|
+
*/
|
|
43
|
+
query<T = Record<string, unknown>>(sql: string, params?: unknown[], connectionName?: string): Promise<QueryResult<T>>;
|
|
44
|
+
/**
|
|
45
|
+
* Execute an INSERT, UPDATE, or DELETE on the default (or named) connection.
|
|
46
|
+
*/
|
|
47
|
+
execute(sql: string, params?: unknown[], connectionName?: string): Promise<ExecuteResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Execute a series of operations within an atomic transaction.
|
|
50
|
+
*/
|
|
51
|
+
transaction<T>(fn: (tx: Transaction) => Promise<T>, connectionName?: string): Promise<T>;
|
|
52
|
+
/**
|
|
53
|
+
* Start building a query for a table (chainable query builder).
|
|
54
|
+
*/
|
|
55
|
+
table<T = Record<string, unknown>>(tableName: string, connectionName?: string): QueryBuilder<T>;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a connection is healthy.
|
|
58
|
+
*/
|
|
59
|
+
isHealthy(connectionName?: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Check health of all connections.
|
|
62
|
+
*/
|
|
63
|
+
healthCheck(): Promise<Record<string, boolean>>;
|
|
64
|
+
/**
|
|
65
|
+
* Get the raw adapter for a connection (for advanced use cases).
|
|
66
|
+
*/
|
|
67
|
+
getAdapter(name?: string): DatabaseAdapter;
|
|
68
|
+
/**
|
|
69
|
+
* Get the raw underlying client for a connection.
|
|
70
|
+
*/
|
|
71
|
+
getRawClient(name?: string): unknown;
|
|
72
|
+
/**
|
|
73
|
+
* Get the dialect of a connection.
|
|
74
|
+
*/
|
|
75
|
+
getDialect(name?: string): DatabaseDialect;
|
|
76
|
+
/**
|
|
77
|
+
* Get the migration system for the default connection.
|
|
78
|
+
*/
|
|
79
|
+
getMigrator(config?: MigrationConfig, connectionName?: string): Migrator;
|
|
80
|
+
private shutdownRegistered;
|
|
81
|
+
private registerShutdownHook;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a new DatabaseManager with the given configuration.
|
|
85
|
+
* This is the recommended way to set up a database connection.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const db = createDatabase({
|
|
90
|
+
* dialect: 'postgres',
|
|
91
|
+
* url: process.env.DATABASE_URL,
|
|
92
|
+
* })
|
|
93
|
+
* await db.connect()
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function createDatabase(config: DatabaseConfig): DatabaseManager;
|
|
97
|
+
/**
|
|
98
|
+
* Lazy-initialized global database proxy.
|
|
99
|
+
* Forwards all calls to the default DatabaseManager.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import { db } from 'exisjs/database'
|
|
104
|
+
*
|
|
105
|
+
* // After createDatabase() has been called elsewhere:
|
|
106
|
+
* const users = await db.query('SELECT * FROM users')
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare const db: DatabaseManager;
|
|
110
|
+
/**
|
|
111
|
+
* Set or replace the default DatabaseManager.
|
|
112
|
+
*/
|
|
113
|
+
export declare function setDefaultDatabase(manager: DatabaseManager): void;
|
|
114
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/database/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,WAAW,EACX,aAAa,EACb,WAAW,EACX,eAAe,EAChB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAkCtC,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAwB;IAExC;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ1D;;OAEG;IACG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3C;;OAEG;IACG,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB9C;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,OAAO,EAAE,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAK1B;;OAEG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,OAAO,EAAE,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,CAAC;IAKzB;;OAEG;IACG,WAAW,CAAC,CAAC,EACjB,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,CAAC,CAAC;IAKb;;OAEG;IACH,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,YAAY,CAAC,CAAC,CAAC;IAKlB;;OAEG;IACG,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM1D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAYrD;;OAEG;IACH,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe;IAW1C;;OAEG;IACH,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO;IAIpC;;OAEG;IACH,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe;IAI1C;;OAEG;IACH,WAAW,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,QAAQ;IAUxE,OAAO,CAAC,kBAAkB,CAAQ;IAElC,OAAO,CAAC,oBAAoB;CAiB7B;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,EAAE,EAAE,eAUf,CAAA;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEjE"}
|