alepha 0.10.1 → 0.10.3
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 +131 -34
- package/batch.d.ts +1 -1
- package/bucket.d.ts +1 -1
- package/cache/redis.d.ts +1 -1
- package/cache.d.ts +1 -1
- package/command.d.ts +1 -1
- package/core.d.ts +20 -11
- package/datetime.d.ts +1 -1
- package/email.d.ts +6 -6
- package/lock/redis.d.ts +1 -1
- package/lock.d.ts +1 -1
- package/logger.d.ts +1 -1
- package/package.json +44 -44
- package/postgres.d.ts +64 -376
- package/queue/redis.d.ts +1 -1
- package/queue.d.ts +1 -1
- package/react/auth.d.ts +1 -1
- package/react/form.d.ts +2 -2
- package/react/head.d.ts +1 -1
- package/react/i18n.d.ts +1 -1
- package/react.d.ts +33 -28
- package/redis.d.ts +1 -1
- package/scheduler.d.ts +1 -1
- package/security.d.ts +8 -7
- package/server/cache.d.ts +1 -1
- package/server/compress.d.ts +1 -1
- package/server/cookies.d.ts +3 -13
- package/server/cors.d.ts +1 -1
- package/server/health.d.ts +1 -1
- package/server/helmet.d.ts +1 -1
- package/server/links.d.ts +34 -34
- package/server/metrics.d.ts +1 -1
- package/server/multipart.d.ts +1 -1
- package/server/proxy.d.ts +1 -1
- package/server/security.d.ts +1 -1
- package/server/static.d.ts +1 -1
- package/server/swagger.d.ts +14 -1
- package/server.d.ts +35 -390
- package/topic/redis.d.ts +1 -1
- package/topic.d.ts +1 -1
package/postgres.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _alepha_core1 from "alepha";
|
|
2
2
|
import { Alepha, AlephaError, Descriptor, KIND, Service, Static, TArray, TBigInt, TBoolean, TInteger, TKeysToIndexer, TNull, TNumber, TNumberOptions, TObject, TObjectOptions, TOptional, TOptionalAdd, TPick, TRecord, TSchema as TSchema$1, TString, TStringOptions, TUnion } from "alepha";
|
|
3
|
-
import * as
|
|
3
|
+
import * as drizzle_orm6 from "drizzle-orm";
|
|
4
4
|
import { BuildColumns, BuildExtraConfigColumns, SQL, SQLWrapper, TableConfig, sql } from "drizzle-orm";
|
|
5
5
|
import * as pg$1 from "drizzle-orm/pg-core";
|
|
6
6
|
import { AnyPgColumn, LockConfig, LockStrength, PgColumn, PgColumnBuilderBase, PgDatabase, PgInsertValue, PgSequenceOptions, PgTableExtraConfigValue, PgTableWithColumns, PgTransaction, PgTransactionConfig, SelectedFields, TableConfig as TableConfig$1, UpdateDeleteAction } from "drizzle-orm/pg-core";
|
|
@@ -91,6 +91,7 @@ declare const insertSchema: <T extends TObject>(obj: T) => TObjectInsert<T>;
|
|
|
91
91
|
* After: { name?: string | null; age: number; }
|
|
92
92
|
*/
|
|
93
93
|
type TObjectUpdate<T extends TObject> = TObject<{ [K in keyof T["properties"]]: T["properties"][K] extends TOptional<infer U> ? TOptional<TUnion<[U, TNull]>> : T["properties"][K] }>;
|
|
94
|
+
declare const updateSchema: <T extends TObject>(schema: T) => TObjectUpdate<T>;
|
|
94
95
|
//#endregion
|
|
95
96
|
//#region src/helpers/schemaToPgColumns.d.ts
|
|
96
97
|
/**
|
|
@@ -104,14 +105,14 @@ declare const schemaToPgColumns: <T extends TObject>(schema: T) => FromSchema<T>
|
|
|
104
105
|
* @param value The value of the field.
|
|
105
106
|
* @returns The PG column.
|
|
106
107
|
*/
|
|
107
|
-
declare const mapFieldToColumn: (name: string, value: TSchema$1) => pg$1.PgSerialBuilderInitial<string> | pg$1.PgIntegerBuilderInitial<string> |
|
|
108
|
+
declare const mapFieldToColumn: (name: string, value: TSchema$1) => pg$1.PgSerialBuilderInitial<string> | pg$1.PgIntegerBuilderInitial<string> | drizzle_orm6.IsIdentity<pg$1.PgBigInt64BuilderInitial<"">, "byDefault"> | drizzle_orm6.IsIdentity<pg$1.PgBigInt64BuilderInitial<"">, "always"> | pg$1.PgBigInt53BuilderInitial<string> | pg$1.PgNumericBuilderInitial<string> | pg$1.PgTimestampBuilderInitial<string> | pg$1.PgUUIDBuilderInitial<string> | pg$1.PgCustomColumnBuilder<{
|
|
108
109
|
name: string;
|
|
109
110
|
dataType: "custom";
|
|
110
111
|
columnType: "PgCustomColumn";
|
|
111
112
|
data: Buffer<ArrayBufferLike>;
|
|
112
113
|
driverParam: unknown;
|
|
113
114
|
enumValues: undefined;
|
|
114
|
-
}> | pg$1.PgTimestampStringBuilderInitial<string> | pg$1.PgDateStringBuilderInitial<string> | pg$1.PgTextBuilderInitial<string, [string, ...string[]]> | pg$1.PgBooleanBuilderInitial<string> |
|
|
115
|
+
}> | pg$1.PgTimestampStringBuilderInitial<string> | pg$1.PgDateStringBuilderInitial<string> | pg$1.PgTextBuilderInitial<string, [string, ...string[]]> | pg$1.PgBooleanBuilderInitial<string> | drizzle_orm6.$Type<pg$1.PgCustomColumnBuilder<{
|
|
115
116
|
name: string;
|
|
116
117
|
dataType: "custom";
|
|
117
118
|
columnType: "PgCustomColumn";
|
|
@@ -126,14 +127,14 @@ declare const mapFieldToColumn: (name: string, value: TSchema$1) => pg$1.PgSeria
|
|
|
126
127
|
[x: string]: unknown;
|
|
127
128
|
[x: number]: unknown;
|
|
128
129
|
[x: symbol]: unknown;
|
|
129
|
-
}> |
|
|
130
|
+
}> | drizzle_orm6.$Type<pg$1.PgCustomColumnBuilder<{
|
|
130
131
|
name: string;
|
|
131
132
|
dataType: "custom";
|
|
132
133
|
columnType: "PgCustomColumn";
|
|
133
134
|
data: Record<string, unknown>;
|
|
134
135
|
driverParam: string;
|
|
135
136
|
enumValues: undefined;
|
|
136
|
-
}>, Record<string, unknown>> |
|
|
137
|
+
}>, Record<string, unknown>> | drizzle_orm6.$Type<pg$1.PgCustomColumnBuilder<{
|
|
137
138
|
name: string;
|
|
138
139
|
dataType: "custom";
|
|
139
140
|
columnType: "PgCustomColumn";
|
|
@@ -1195,12 +1196,30 @@ type PgQueryWhere<T extends object> = { [Key in keyof T]?: FilterOperators<T[Key
|
|
|
1195
1196
|
};
|
|
1196
1197
|
//#endregion
|
|
1197
1198
|
//#region src/interfaces/PgQuery.d.ts
|
|
1199
|
+
/**
|
|
1200
|
+
* Order direction for sorting
|
|
1201
|
+
*/
|
|
1202
|
+
type OrderDirection = "asc" | "desc";
|
|
1203
|
+
/**
|
|
1204
|
+
* Single order by clause with column and direction
|
|
1205
|
+
*/
|
|
1206
|
+
interface OrderByClause<T> {
|
|
1207
|
+
column: keyof T;
|
|
1208
|
+
direction?: OrderDirection;
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Order by parameter - supports 3 modes:
|
|
1212
|
+
* 1. String: orderBy: "name" (defaults to ASC)
|
|
1213
|
+
* 2. Single object: orderBy: { column: "name", direction: "desc" }
|
|
1214
|
+
* 3. Array: orderBy: [{ column: "name", direction: "asc" }, { column: "age", direction: "desc" }]
|
|
1215
|
+
*/
|
|
1216
|
+
type OrderBy<T> = keyof T | OrderByClause<T> | Array<OrderByClause<T>>;
|
|
1198
1217
|
interface PgQuery<T extends TObject> {
|
|
1199
1218
|
distinct?: boolean;
|
|
1200
1219
|
where?: PgQueryWhereOrSQL<Static<T>>;
|
|
1201
1220
|
limit?: number;
|
|
1202
1221
|
offset?: number;
|
|
1203
|
-
|
|
1222
|
+
orderBy?: OrderBy<Static<T>>;
|
|
1204
1223
|
groupBy?: (keyof Static<T>)[];
|
|
1205
1224
|
}
|
|
1206
1225
|
type PgQueryResult<T extends TObject, Select extends (keyof Static<T>)[]> = TPick<T, TKeysToIndexer<Select>>;
|
|
@@ -1379,7 +1398,7 @@ type Page<T> = {
|
|
|
1379
1398
|
* filters.searchTerm ? { name: { ilike: `%${filters.searchTerm}%` } } : {}
|
|
1380
1399
|
* ]
|
|
1381
1400
|
* },
|
|
1382
|
-
*
|
|
1401
|
+
* orderBy: [{ column: "createdAt", direction: "desc" }]
|
|
1383
1402
|
* });
|
|
1384
1403
|
*
|
|
1385
1404
|
* return await this.products.paginate({ page, size }, query, { count: true });
|
|
@@ -1504,7 +1523,7 @@ type Page<T> = {
|
|
|
1504
1523
|
* // Automatically excludes soft-deleted records
|
|
1505
1524
|
* return await this.documents.find({
|
|
1506
1525
|
* where: { authorId: { isNotNull: true } },
|
|
1507
|
-
*
|
|
1526
|
+
* orderBy: [{ column: "updatedAt", direction: "desc" }]
|
|
1508
1527
|
* });
|
|
1509
1528
|
* }
|
|
1510
1529
|
*
|
|
@@ -1666,7 +1685,7 @@ declare class RepositoryDescriptor<EntityTableConfig extends TableConfig, Entity
|
|
|
1666
1685
|
/**
|
|
1667
1686
|
* Getter for the database connection from the database provider.
|
|
1668
1687
|
*/
|
|
1669
|
-
protected get db(): PgDatabase<any, Record<string, never>,
|
|
1688
|
+
protected get db(): PgDatabase<any, Record<string, never>, drizzle_orm6.ExtractTablesWithRelations<Record<string, never>>>;
|
|
1670
1689
|
/**
|
|
1671
1690
|
* Execute a SQL query.
|
|
1672
1691
|
*/
|
|
@@ -1691,10 +1710,10 @@ declare class RepositoryDescriptor<EntityTableConfig extends TableConfig, Entity
|
|
|
1691
1710
|
*
|
|
1692
1711
|
* @returns The SELECT query builder.
|
|
1693
1712
|
*/
|
|
1694
|
-
protected select(opts?: StatementOptions): pg$1.PgSelectBase<string, Record<string, PgColumn<
|
|
1713
|
+
protected select(opts?: StatementOptions): pg$1.PgSelectBase<string, Record<string, PgColumn<drizzle_orm6.ColumnBaseConfig<drizzle_orm6.ColumnDataType, string>, {}, {}>>, "single", Record<string, "not-null">, false, never, {
|
|
1695
1714
|
[x: string]: unknown;
|
|
1696
1715
|
}[], {
|
|
1697
|
-
[x: string]: PgColumn<
|
|
1716
|
+
[x: string]: PgColumn<drizzle_orm6.ColumnBaseConfig<drizzle_orm6.ColumnDataType, string>, {}, {}>;
|
|
1698
1717
|
}>;
|
|
1699
1718
|
protected selectDistinct(opts: StatementOptions | undefined, fields: SelectedFields): pg$1.PgSelectBase<string, SelectedFields, "partial", Record<string, "not-null">, false, never, {
|
|
1700
1719
|
[x: string]: unknown;
|
|
@@ -1866,6 +1885,36 @@ declare class RepositoryDescriptor<EntityTableConfig extends TableConfig, Entity
|
|
|
1866
1885
|
* @returns The cleaned row.
|
|
1867
1886
|
*/
|
|
1868
1887
|
protected clean<T extends TObject = EntitySchema>(row: any, schema?: T): Static<T>;
|
|
1888
|
+
/**
|
|
1889
|
+
* Parse pagination sort string to orderBy format.
|
|
1890
|
+
* Format: "firstName,-lastName" -> [{ column: "firstName", direction: "asc" }, { column: "lastName", direction: "desc" }]
|
|
1891
|
+
* - Columns separated by comma
|
|
1892
|
+
* - Prefix with '-' for DESC direction
|
|
1893
|
+
*
|
|
1894
|
+
* @param sort Pagination sort string
|
|
1895
|
+
* @returns OrderBy array or single object
|
|
1896
|
+
*/
|
|
1897
|
+
protected parsePaginationSort(sort: string): Array<{
|
|
1898
|
+
column: string;
|
|
1899
|
+
direction: "asc" | "desc";
|
|
1900
|
+
}> | {
|
|
1901
|
+
column: string;
|
|
1902
|
+
direction: "asc" | "desc";
|
|
1903
|
+
};
|
|
1904
|
+
/**
|
|
1905
|
+
* Normalize orderBy parameter to array format.
|
|
1906
|
+
* Supports 3 modes:
|
|
1907
|
+
* 1. String: "name" -> [{ column: "name", direction: "asc" }]
|
|
1908
|
+
* 2. Object: { column: "name", direction: "desc" } -> [{ column: "name", direction: "desc" }]
|
|
1909
|
+
* 3. Array: [{ column: "name" }, { column: "age", direction: "desc" }] -> normalized array
|
|
1910
|
+
*
|
|
1911
|
+
* @param orderBy The orderBy parameter
|
|
1912
|
+
* @returns Normalized array of order by clauses
|
|
1913
|
+
*/
|
|
1914
|
+
protected normalizeOrderBy(orderBy: any): Array<{
|
|
1915
|
+
column: string;
|
|
1916
|
+
direction: "asc" | "desc";
|
|
1917
|
+
}>;
|
|
1869
1918
|
/**
|
|
1870
1919
|
* Get the where clause for an ID.
|
|
1871
1920
|
*
|
|
@@ -1881,7 +1930,7 @@ declare class RepositoryDescriptor<EntityTableConfig extends TableConfig, Entity
|
|
|
1881
1930
|
*/
|
|
1882
1931
|
protected getPrimaryKey(schema: TObject): {
|
|
1883
1932
|
key: string;
|
|
1884
|
-
col: PgColumn<
|
|
1933
|
+
col: PgColumn<drizzle_orm6.ColumnBaseConfig<drizzle_orm6.ColumnDataType, string>, {}, {}>;
|
|
1885
1934
|
type: TSchema$1;
|
|
1886
1935
|
};
|
|
1887
1936
|
}
|
|
@@ -2287,373 +2336,12 @@ declare class SequenceDescriptor extends Descriptor<SequenceDescriptorOptions> {
|
|
|
2287
2336
|
* It integrates seamlessly with the repository pattern and provides built-in handling
|
|
2288
2337
|
* for optimistic locking scenarios with automatic retry on version mismatches.
|
|
2289
2338
|
*
|
|
2290
|
-
* **Key Features**
|
|
2291
|
-
*
|
|
2292
|
-
* - **ACID Compliance**: Full transaction support with commit/rollback functionality
|
|
2293
|
-
* - **Automatic Retry Logic**: Built-in retry for optimistic locking conflicts
|
|
2294
|
-
* - **Type Safety**: Full TypeScript support with generic parameters
|
|
2295
|
-
* - **Isolation Levels**: Configurable transaction isolation levels
|
|
2296
|
-
* - **Error Handling**: Automatic rollback on errors with proper error propagation
|
|
2297
|
-
* - **Repository Integration**: Seamless integration with $repository operations
|
|
2298
|
-
* - **Performance**: Efficient transaction management with connection reuse
|
|
2299
|
-
*
|
|
2300
|
-
* **Use Cases**
|
|
2301
|
-
*
|
|
2302
|
-
* Essential for operations requiring atomicity and consistency:
|
|
2303
|
-
* - Financial transactions and accounting operations
|
|
2304
|
-
* - Complex business workflows with multiple database operations
|
|
2305
|
-
* - Data migrations and bulk operations
|
|
2306
|
-
* - E-commerce order processing with inventory updates
|
|
2307
|
-
* - User registration with related data creation
|
|
2308
|
-
* - Audit trail creation with business operations
|
|
2309
|
-
*
|
|
2310
|
-
* @example
|
|
2311
|
-
* **Basic transaction for financial operations:**
|
|
2312
|
-
* ```ts
|
|
2313
|
-
* import { $transaction } from "alepha/postgres";
|
|
2314
|
-
*
|
|
2315
|
-
* class BankingService {
|
|
2316
|
-
* transfer = $transaction({
|
|
2317
|
-
* handler: async (tx, fromAccountId: string, toAccountId: string, amount: number) => {
|
|
2318
|
-
* // All operations within this transaction are atomic
|
|
2319
|
-
* console.log(`Processing transfer: $${amount} from ${fromAccountId} to ${toAccountId}`);
|
|
2320
|
-
*
|
|
2321
|
-
* // Get current account balances
|
|
2322
|
-
* const fromAccount = await this.accounts.findById(fromAccountId, { tx });
|
|
2323
|
-
* const toAccount = await this.accounts.findById(toAccountId, { tx });
|
|
2324
|
-
*
|
|
2325
|
-
* // Validate sufficient balance
|
|
2326
|
-
* if (fromAccount.balance < amount) {
|
|
2327
|
-
* throw new Error(`Insufficient funds. Balance: $${fromAccount.balance}, Required: $${amount}`);
|
|
2328
|
-
* }
|
|
2329
|
-
*
|
|
2330
|
-
* // Update account balances atomically
|
|
2331
|
-
* const updatedFromAccount = await this.accounts.updateById(
|
|
2332
|
-
* fromAccountId,
|
|
2333
|
-
* { balance: fromAccount.balance - amount },
|
|
2334
|
-
* { tx }
|
|
2335
|
-
* );
|
|
2336
|
-
*
|
|
2337
|
-
* const updatedToAccount = await this.accounts.updateById(
|
|
2338
|
-
* toAccountId,
|
|
2339
|
-
* { balance: toAccount.balance + amount },
|
|
2340
|
-
* { tx }
|
|
2341
|
-
* );
|
|
2342
|
-
*
|
|
2343
|
-
* // Create transaction record
|
|
2344
|
-
* const transactionRecord = await this.transactions.create({
|
|
2345
|
-
* id: generateUUID(),
|
|
2346
|
-
* fromAccountId,
|
|
2347
|
-
* toAccountId,
|
|
2348
|
-
* amount,
|
|
2349
|
-
* type: 'transfer',
|
|
2350
|
-
* status: 'completed',
|
|
2351
|
-
* processedAt: new Date().toISOString()
|
|
2352
|
-
* }, { tx });
|
|
2353
|
-
*
|
|
2354
|
-
* console.log(`Transfer completed successfully: ${transactionRecord.id}`);
|
|
2355
|
-
*
|
|
2356
|
-
* return {
|
|
2357
|
-
* transactionId: transactionRecord.id,
|
|
2358
|
-
* fromBalance: updatedFromAccount.balance,
|
|
2359
|
-
* toBalance: updatedToAccount.balance
|
|
2360
|
-
* };
|
|
2361
|
-
* }
|
|
2362
|
-
* });
|
|
2363
|
-
*
|
|
2364
|
-
* async transferFunds(fromAccountId: string, toAccountId: string, amount: number) {
|
|
2365
|
-
* // This will automatically retry if there's a version mismatch (optimistic locking)
|
|
2366
|
-
* return await this.transfer.run(fromAccountId, toAccountId, amount);
|
|
2367
|
-
* }
|
|
2368
|
-
* }
|
|
2369
|
-
* ```
|
|
2370
|
-
*
|
|
2371
|
-
* @example
|
|
2372
|
-
* **E-commerce order processing with inventory management:**
|
|
2373
|
-
* ```ts
|
|
2374
|
-
* class OrderService {
|
|
2375
|
-
* processOrder = $transaction({
|
|
2376
|
-
* config: {
|
|
2377
|
-
* isolationLevel: 'serializable' // Highest isolation for critical operations
|
|
2378
|
-
* },
|
|
2379
|
-
* handler: async (tx, orderData: {
|
|
2380
|
-
* customerId: string;
|
|
2381
|
-
* items: Array<{ productId: string; quantity: number; price: number }>;
|
|
2382
|
-
* shippingAddress: Address;
|
|
2383
|
-
* paymentMethodId: string;
|
|
2384
|
-
* }) => {
|
|
2385
|
-
* console.log(`Processing order for customer ${orderData.customerId}`);
|
|
2386
|
-
*
|
|
2387
|
-
* let totalAmount = 0;
|
|
2388
|
-
* const orderItems = [];
|
|
2389
|
-
*
|
|
2390
|
-
* // Process each item and update inventory atomically
|
|
2391
|
-
* for (const itemData of orderData.items) {
|
|
2392
|
-
* const product = await this.products.findById(itemData.productId, { tx });
|
|
2393
|
-
*
|
|
2394
|
-
* // Check inventory availability
|
|
2395
|
-
* if (product.stockQuantity < itemData.quantity) {
|
|
2396
|
-
* throw new Error(`Insufficient stock for ${product.name}. Available: ${product.stockQuantity}, Requested: ${itemData.quantity}`);
|
|
2397
|
-
* }
|
|
2398
|
-
*
|
|
2399
|
-
* // Update product inventory with optimistic locking
|
|
2400
|
-
* await this.products.save({
|
|
2401
|
-
* ...product,
|
|
2402
|
-
* stockQuantity: product.stockQuantity - itemData.quantity
|
|
2403
|
-
* }, { tx });
|
|
2404
|
-
*
|
|
2405
|
-
* // Calculate totals
|
|
2406
|
-
* const lineTotal = itemData.price * itemData.quantity;
|
|
2407
|
-
* totalAmount += lineTotal;
|
|
2408
|
-
*
|
|
2409
|
-
* orderItems.push({
|
|
2410
|
-
* id: generateUUID(),
|
|
2411
|
-
* productId: itemData.productId,
|
|
2412
|
-
* quantity: itemData.quantity,
|
|
2413
|
-
* unitPrice: itemData.price,
|
|
2414
|
-
* lineTotal
|
|
2415
|
-
* });
|
|
2416
|
-
* }
|
|
2417
|
-
*
|
|
2418
|
-
* // Create the main order record
|
|
2419
|
-
* const order = await this.orders.create({
|
|
2420
|
-
* id: generateUUID(),
|
|
2421
|
-
* customerId: orderData.customerId,
|
|
2422
|
-
* status: 'pending',
|
|
2423
|
-
* totalAmount,
|
|
2424
|
-
* shippingAddress: orderData.shippingAddress,
|
|
2425
|
-
* createdAt: new Date().toISOString()
|
|
2426
|
-
* }, { tx });
|
|
2427
|
-
*
|
|
2428
|
-
* // Create order items
|
|
2429
|
-
* for (const itemData of orderItems) {
|
|
2430
|
-
* await this.orderItems.create({
|
|
2431
|
-
* ...itemData,
|
|
2432
|
-
* orderId: order.id
|
|
2433
|
-
* }, { tx });
|
|
2434
|
-
* }
|
|
2435
|
-
*
|
|
2436
|
-
* // Process payment
|
|
2437
|
-
* const paymentResult = await this.paymentService.processPayment({
|
|
2438
|
-
* orderId: order.id,
|
|
2439
|
-
* amount: totalAmount,
|
|
2440
|
-
* paymentMethodId: orderData.paymentMethodId,
|
|
2441
|
-
* customerId: orderData.customerId
|
|
2442
|
-
* }, { tx });
|
|
2443
|
-
*
|
|
2444
|
-
* if (!paymentResult.success) {
|
|
2445
|
-
* throw new Error(`Payment failed: ${paymentResult.error}`);
|
|
2446
|
-
* }
|
|
2447
|
-
*
|
|
2448
|
-
* // Update order status
|
|
2449
|
-
* const completedOrder = await this.orders.updateById(
|
|
2450
|
-
* order.id,
|
|
2451
|
-
* {
|
|
2452
|
-
* status: 'paid',
|
|
2453
|
-
* paymentId: paymentResult.paymentId,
|
|
2454
|
-
* paidAt: new Date().toISOString()
|
|
2455
|
-
* },
|
|
2456
|
-
* { tx }
|
|
2457
|
-
* );
|
|
2458
|
-
*
|
|
2459
|
-
* console.log(`Order processed successfully: ${order.id}`);
|
|
2460
|
-
*
|
|
2461
|
-
* return {
|
|
2462
|
-
* orderId: order.id,
|
|
2463
|
-
* totalAmount,
|
|
2464
|
-
* paymentId: paymentResult.paymentId,
|
|
2465
|
-
* itemCount: orderItems.length
|
|
2466
|
-
* };
|
|
2467
|
-
* }
|
|
2468
|
-
* });
|
|
2469
|
-
* }
|
|
2470
|
-
* ```
|
|
2471
|
-
*
|
|
2472
|
-
* @example
|
|
2473
|
-
* **User registration with related data creation:**
|
|
2474
|
-
* ```ts
|
|
2475
|
-
* class UserService {
|
|
2476
|
-
* registerUser = $transaction({
|
|
2477
|
-
* handler: async (tx, registrationData: {
|
|
2478
|
-
* email: string;
|
|
2479
|
-
* password: string;
|
|
2480
|
-
* profile: {
|
|
2481
|
-
* firstName: string;
|
|
2482
|
-
* lastName: string;
|
|
2483
|
-
* dateOfBirth: string;
|
|
2484
|
-
* };
|
|
2485
|
-
* preferences: {
|
|
2486
|
-
* notifications: boolean;
|
|
2487
|
-
* newsletter: boolean;
|
|
2488
|
-
* };
|
|
2489
|
-
* }) => {
|
|
2490
|
-
* console.log(`Registering new user: ${registrationData.email}`);
|
|
2491
|
-
*
|
|
2492
|
-
* // Check if email already exists
|
|
2493
|
-
* const existingUser = await this.users.find(
|
|
2494
|
-
* { where: { email: registrationData.email } },
|
|
2495
|
-
* { tx }
|
|
2496
|
-
* );
|
|
2497
|
-
*
|
|
2498
|
-
* if (existingUser.length > 0) {
|
|
2499
|
-
* throw new Error(`User with email ${registrationData.email} already exists`);
|
|
2500
|
-
* }
|
|
2501
|
-
*
|
|
2502
|
-
* // Hash password
|
|
2503
|
-
* const hashedPassword = await this.hashPassword(registrationData.password);
|
|
2504
|
-
*
|
|
2505
|
-
* // Create user record
|
|
2506
|
-
* const user = await this.users.create({
|
|
2507
|
-
* id: generateUUID(),
|
|
2508
|
-
* email: registrationData.email,
|
|
2509
|
-
* passwordHash: hashedPassword,
|
|
2510
|
-
* isActive: true,
|
|
2511
|
-
* emailVerified: false
|
|
2512
|
-
* }, { tx });
|
|
2513
|
-
*
|
|
2514
|
-
* // Create user profile
|
|
2515
|
-
* const profile = await this.userProfiles.create({
|
|
2516
|
-
* id: generateUUID(),
|
|
2517
|
-
* userId: user.id,
|
|
2518
|
-
* firstName: registrationData.profile.firstName,
|
|
2519
|
-
* lastName: registrationData.profile.lastName,
|
|
2520
|
-
* dateOfBirth: registrationData.profile.dateOfBirth
|
|
2521
|
-
* }, { tx });
|
|
2522
|
-
*
|
|
2523
|
-
* // Create user preferences
|
|
2524
|
-
* const preferences = await this.userPreferences.create({
|
|
2525
|
-
* id: generateUUID(),
|
|
2526
|
-
* userId: user.id,
|
|
2527
|
-
* notifications: registrationData.preferences.notifications,
|
|
2528
|
-
* newsletter: registrationData.preferences.newsletter
|
|
2529
|
-
* }, { tx });
|
|
2530
|
-
*
|
|
2531
|
-
* // Create audit log entry
|
|
2532
|
-
* await this.auditLogs.create({
|
|
2533
|
-
* id: generateUUID(),
|
|
2534
|
-
* userId: user.id,
|
|
2535
|
-
* action: 'user_registered',
|
|
2536
|
-
* details: { email: user.email },
|
|
2537
|
-
* timestamp: new Date().toISOString()
|
|
2538
|
-
* }, { tx });
|
|
2539
|
-
*
|
|
2540
|
-
* console.log(`User registration completed: ${user.id}`);
|
|
2541
|
-
*
|
|
2542
|
-
* return {
|
|
2543
|
-
* userId: user.id,
|
|
2544
|
-
* email: user.email,
|
|
2545
|
-
* profile: {
|
|
2546
|
-
* firstName: profile.firstName,
|
|
2547
|
-
* lastName: profile.lastName
|
|
2548
|
-
* }
|
|
2549
|
-
* };
|
|
2550
|
-
* }
|
|
2551
|
-
* });
|
|
2552
|
-
* }
|
|
2553
|
-
* ```
|
|
2554
|
-
*
|
|
2555
|
-
* @example
|
|
2556
|
-
* **Data migration with progress tracking:**
|
|
2557
|
-
* ```ts
|
|
2558
|
-
* class MigrationService {
|
|
2559
|
-
* migrateUserData = $transaction({
|
|
2560
|
-
* config: {
|
|
2561
|
-
* isolationLevel: 'read_committed',
|
|
2562
|
-
* accessMode: 'read_write'
|
|
2563
|
-
* },
|
|
2564
|
-
* handler: async (tx, batchSize: number = 1000) => {
|
|
2565
|
-
* console.log(`Starting data migration with batch size ${batchSize}`);
|
|
2566
|
-
*
|
|
2567
|
-
* let totalMigrated = 0;
|
|
2568
|
-
* let hasMore = true;
|
|
2569
|
-
* let offset = 0;
|
|
2570
|
-
*
|
|
2571
|
-
* while (hasMore) {
|
|
2572
|
-
* // Get batch of users to migrate
|
|
2573
|
-
* const users = await this.legacyUsers.find({
|
|
2574
|
-
* limit: batchSize,
|
|
2575
|
-
* offset,
|
|
2576
|
-
* sort: { id: 'asc' }
|
|
2577
|
-
* }, { tx });
|
|
2578
|
-
*
|
|
2579
|
-
* if (users.length === 0) {
|
|
2580
|
-
* hasMore = false;
|
|
2581
|
-
* break;
|
|
2582
|
-
* }
|
|
2583
|
-
*
|
|
2584
|
-
* // Process each user in the batch
|
|
2585
|
-
* for (const legacyUser of users) {
|
|
2586
|
-
* try {
|
|
2587
|
-
* // Transform legacy data to new format
|
|
2588
|
-
* const newUser = {
|
|
2589
|
-
* id: generateUUID(),
|
|
2590
|
-
* email: legacyUser.email_address,
|
|
2591
|
-
* firstName: legacyUser.first_name,
|
|
2592
|
-
* lastName: legacyUser.last_name,
|
|
2593
|
-
* createdAt: legacyUser.created_date,
|
|
2594
|
-
* isActive: legacyUser.status === 'active'
|
|
2595
|
-
* };
|
|
2596
|
-
*
|
|
2597
|
-
* // Create new user record
|
|
2598
|
-
* await this.users.create(newUser, { tx });
|
|
2599
|
-
*
|
|
2600
|
-
* // Mark legacy user as migrated
|
|
2601
|
-
* await this.legacyUsers.updateById(
|
|
2602
|
-
* legacyUser.id,
|
|
2603
|
-
* {
|
|
2604
|
-
* migrated: true,
|
|
2605
|
-
* migratedAt: new Date().toISOString(),
|
|
2606
|
-
* newUserId: newUser.id
|
|
2607
|
-
* },
|
|
2608
|
-
* { tx }
|
|
2609
|
-
* );
|
|
2610
|
-
*
|
|
2611
|
-
* totalMigrated++;
|
|
2612
|
-
*
|
|
2613
|
-
* } catch (error) {
|
|
2614
|
-
* console.error(`Failed to migrate user ${legacyUser.id}:`, error.message);
|
|
2615
|
-
*
|
|
2616
|
-
* // Log failed migration
|
|
2617
|
-
* await this.migrationErrors.create({
|
|
2618
|
-
* id: generateUUID(),
|
|
2619
|
-
* legacyUserId: legacyUser.id,
|
|
2620
|
-
* error: error.message,
|
|
2621
|
-
* attemptedAt: new Date().toISOString()
|
|
2622
|
-
* }, { tx });
|
|
2623
|
-
* }
|
|
2624
|
-
* }
|
|
2625
|
-
*
|
|
2626
|
-
* offset += batchSize;
|
|
2627
|
-
* console.log(`Migrated ${totalMigrated} users so far...`);
|
|
2628
|
-
* }
|
|
2629
|
-
*
|
|
2630
|
-
* // Update migration status
|
|
2631
|
-
* await this.migrationStatus.updateById(
|
|
2632
|
-
* 'user_migration',
|
|
2633
|
-
* {
|
|
2634
|
-
* totalMigrated,
|
|
2635
|
-
* completedAt: new Date().toISOString(),
|
|
2636
|
-
* status: 'completed'
|
|
2637
|
-
* },
|
|
2638
|
-
* { tx }
|
|
2639
|
-
* );
|
|
2640
|
-
*
|
|
2641
|
-
* console.log(`Migration completed. Total migrated: ${totalMigrated}`);
|
|
2642
|
-
*
|
|
2643
|
-
* return { totalMigrated };
|
|
2644
|
-
* }
|
|
2645
|
-
* });
|
|
2646
|
-
* }
|
|
2647
|
-
* ```
|
|
2648
|
-
*
|
|
2649
2339
|
* **Important Notes**:
|
|
2650
2340
|
* - All operations within the transaction handler are atomic
|
|
2651
2341
|
* - Automatic retry on `PgVersionMismatchError` for optimistic locking
|
|
2652
2342
|
* - Pass `{ tx }` option to all repository operations within the transaction
|
|
2653
2343
|
* - Transactions are automatically rolled back on any unhandled error
|
|
2654
2344
|
* - Use appropriate isolation levels based on your consistency requirements
|
|
2655
|
-
*
|
|
2656
|
-
* @stability 2
|
|
2657
2345
|
*/
|
|
2658
2346
|
declare const $transaction: <T extends any[], R>(opts: TransactionDescriptorOptions<T, R>) => _alepha_retry0.RetryDescriptorFn<(...args: T) => Promise<R>>;
|
|
2659
2347
|
interface TransactionDescriptorOptions<T extends any[], R> {
|
|
@@ -3006,7 +2694,7 @@ declare const legacyIdSchema: PgAttr<PgAttr<PgAttr<typebox1.TInteger, typeof PG_
|
|
|
3006
2694
|
/**
|
|
3007
2695
|
* Postgres schema type.
|
|
3008
2696
|
*/
|
|
3009
|
-
declare const schema: <TDocument extends TSchema$1>(name: string, document: TDocument) =>
|
|
2697
|
+
declare const schema: <TDocument extends TSchema$1>(name: string, document: TDocument) => drizzle_orm6.$Type<pg$1.PgCustomColumnBuilder<{
|
|
3010
2698
|
name: string;
|
|
3011
2699
|
dataType: "custom";
|
|
3012
2700
|
columnType: "PgCustomColumn";
|
|
@@ -3056,7 +2744,7 @@ declare const schema: <TDocument extends TSchema$1>(name: string, document: TDoc
|
|
|
3056
2744
|
* @see {@link $transaction}
|
|
3057
2745
|
* @module alepha.postgres
|
|
3058
2746
|
*/
|
|
3059
|
-
declare const AlephaPostgres: _alepha_core1.Service<_alepha_core1.Module
|
|
2747
|
+
declare const AlephaPostgres: _alepha_core1.Service<_alepha_core1.Module<{}>>;
|
|
3060
2748
|
//#endregion
|
|
3061
|
-
export { $entity, $repository, $sequence, $transaction, AlephaPostgres, DrizzleKitProvider, Entity, EntityDescriptorOptions, FilterOperators, FromSchema, NodePostgresProvider, NodePostgresProviderOptions, PG_CREATED_AT, PG_DEFAULT, PG_DELETED_AT, PG_IDENTITY, PG_PRIMARY_KEY, PG_REF, PG_SCHEMA, PG_SERIAL, PG_UPDATED_AT, PG_VERSION, Page, PageQuery, PgDefault, PgEntityNotFoundError, PgIdentityOptions, PgPrimaryKey, PgQuery, PgQueryResult, PgQueryWhere, PgQueryWhereOrSQL, PgRef, PgRefOptions, PgSymbolKeys, PgSymbols, PgTableConfig, PgTableWithColumnsAndSchema, PostgresProvider, PostgresTypeProvider, RepositoryDescriptor, RepositoryDescriptorOptions, RepositoryProvider, SQLLike, SequenceDescriptor, SequenceDescriptorOptions, StatementOptions, TObjectInsert, TPage, TransactionContext, TransactionDescriptorOptions, camelToSnakeCase,
|
|
2749
|
+
export { $entity, $repository, $sequence, $transaction, AlephaPostgres, DrizzleKitProvider, Entity, EntityDescriptorOptions, FilterOperators, FromSchema, NodePostgresProvider, NodePostgresProviderOptions, OrderBy, OrderByClause, OrderDirection, PG_CREATED_AT, PG_DEFAULT, PG_DELETED_AT, PG_IDENTITY, PG_PRIMARY_KEY, PG_REF, PG_SCHEMA, PG_SERIAL, PG_UPDATED_AT, PG_VERSION, Page, PageQuery, PgDefault, PgEntityNotFoundError, PgIdentityOptions, PgPrimaryKey, PgQuery, PgQueryResult, PgQueryWhere, PgQueryWhereOrSQL, PgRef, PgRefOptions, PgSymbolKeys, PgSymbols, PgTableConfig, PgTableWithColumnsAndSchema, PostgresProvider, PostgresTypeProvider, RepositoryDescriptor, RepositoryDescriptorOptions, RepositoryProvider, SQLLike, SequenceDescriptor, SequenceDescriptorOptions, StatementOptions, TObjectInsert, TObjectUpdate, TPage, TransactionContext, TransactionDescriptorOptions, camelToSnakeCase, drizzle_orm6 as drizzle, insertSchema, legacyIdSchema, mapFieldToColumn, mapStringToColumn, pageQuerySchema, pageSchema, pg, schema, schemaToPgColumns, sql, updateSchema };
|
|
3062
2750
|
//# sourceMappingURL=index.d.ts.map
|
package/queue/redis.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ declare class RedisQueueProvider implements QueueProvider {
|
|
|
23
23
|
* @see {@link RedisQueueProvider}
|
|
24
24
|
* @module alepha.queue.redis
|
|
25
25
|
*/
|
|
26
|
-
declare const AlephaQueueRedis: _alepha_core0.Service<_alepha_core0.Module
|
|
26
|
+
declare const AlephaQueueRedis: _alepha_core0.Service<_alepha_core0.Module<{}>>;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { AlephaQueueRedis, RedisQueueProvider };
|
|
29
29
|
//# sourceMappingURL=index.d.ts.map
|
package/queue.d.ts
CHANGED
|
@@ -754,7 +754,7 @@ declare class ConsumerDescriptor<T extends TSchema> extends Descriptor<ConsumerD
|
|
|
754
754
|
* @see {@link $consumer}
|
|
755
755
|
* @module alepha.queue
|
|
756
756
|
*/
|
|
757
|
-
declare const AlephaQueue: _alepha_core1.Service<_alepha_core1.Module
|
|
757
|
+
declare const AlephaQueue: _alepha_core1.Service<_alepha_core1.Module<{}>>;
|
|
758
758
|
//#endregion
|
|
759
759
|
export { $consumer, $queue, AlephaQueue, ConsumerDescriptor, ConsumerDescriptorOptions, MemoryQueueProvider, QueueDescriptor, QueueDescriptorOptions, QueueMessage, QueueMessageSchema, QueueProvider };
|
|
760
760
|
//# sourceMappingURL=index.d.ts.map
|
package/react/auth.d.ts
CHANGED
|
@@ -488,7 +488,7 @@ declare module "alepha/react" {
|
|
|
488
488
|
* @see {@link ReactAuthProvider}
|
|
489
489
|
* @module alepha.react.auth
|
|
490
490
|
*/
|
|
491
|
-
declare const AlephaReactAuth: _alepha_core4.Service<_alepha_core4.Module
|
|
491
|
+
declare const AlephaReactAuth: _alepha_core4.Service<_alepha_core4.Module<{}>>;
|
|
492
492
|
//#endregion
|
|
493
493
|
export { $auth, AccessToken, AlephaReactAuth, AuthDescriptor, AuthDescriptorOptions, AuthExternal, AuthInternal, CredentialsOptions, OAuth2Options, OAuth2Profile, OidcOptions, ReactAuth, ReactAuthProvider, SessionExpiredError, useAuth };
|
|
494
494
|
//# sourceMappingURL=index.d.ts.map
|
package/react/form.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ type FormCtrlOptions<T extends TObject> = {
|
|
|
65
65
|
* Optional initial values for the form fields.
|
|
66
66
|
* This can be used to pre-populate the form with existing data.
|
|
67
67
|
*/
|
|
68
|
-
initialValues?: Static<T
|
|
68
|
+
initialValues?: Partial<Static<T>>;
|
|
69
69
|
/**
|
|
70
70
|
* Optional function to create custom field attributes.
|
|
71
71
|
* This can be used to add custom validation, styles, or other attributes.
|
|
@@ -171,7 +171,7 @@ declare module "alepha" {
|
|
|
171
171
|
* @see {@link useForm}
|
|
172
172
|
* @module alepha.react.form
|
|
173
173
|
*/
|
|
174
|
-
declare const AlephaReactForm: _alepha_core0.Service<_alepha_core0.Module
|
|
174
|
+
declare const AlephaReactForm: _alepha_core0.Service<_alepha_core0.Module<{}>>;
|
|
175
175
|
//#endregion
|
|
176
176
|
export { AlephaReactForm, FormCtrlOptions, FormEventLike, FormModel, FormState, FormStateEvent, InputField, InputHTMLAttributesLike, SchemaToInput, UseFormStateReturn, useForm, useFormState };
|
|
177
177
|
//# sourceMappingURL=index.d.ts.map
|
package/react/head.d.ts
CHANGED
|
@@ -114,7 +114,7 @@ declare module "alepha/react" {
|
|
|
114
114
|
* @see {@link ServerHeadProvider}
|
|
115
115
|
* @module alepha.react.head
|
|
116
116
|
*/
|
|
117
|
-
declare const AlephaReactHead: _alepha_core1.Service<_alepha_core1.Module
|
|
117
|
+
declare const AlephaReactHead: _alepha_core1.Service<_alepha_core1.Module<{}>>;
|
|
118
118
|
//#endregion
|
|
119
119
|
export { $head, AlephaReactHead, Head, HeadDescriptor, HeadDescriptorOptions, ServerHeadProvider, SimpleHead, UseHeadOptions, UseHeadReturn, useHead };
|
|
120
120
|
//# sourceMappingURL=index.d.ts.map
|
package/react/i18n.d.ts
CHANGED
|
@@ -109,7 +109,7 @@ declare module "alepha" {
|
|
|
109
109
|
*
|
|
110
110
|
* @module alepha.react.i18n
|
|
111
111
|
*/
|
|
112
|
-
declare const AlephaReactI18n: _alepha_core1.Service<_alepha_core1.Module
|
|
112
|
+
declare const AlephaReactI18n: _alepha_core1.Service<_alepha_core1.Module<{}>>;
|
|
113
113
|
//#endregion
|
|
114
114
|
export { $dictionary, AlephaReactI18n, DictionaryDescriptor, DictionaryDescriptorOptions, I18nProvider, ServiceDictionary, useI18n };
|
|
115
115
|
//# sourceMappingURL=index.d.ts.map
|