alepha 0.20.2 → 0.20.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 +0 -1
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.browser.js +49 -0
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.js +49 -0
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +2 -61
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +4 -4
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +1 -10
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.browser.js +37 -0
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +12 -68
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +57 -4
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/users/index.browser.js +6 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +148 -227
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +60 -14
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +2 -1
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/bucket/index.d.ts +77 -107
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +153 -5
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +12 -2
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +26 -0
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +11 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +11 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +7 -5
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -3
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +637 -11660
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +707 -532
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +4 -8
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +20 -16
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +51 -77
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +65 -15
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +10 -13
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +30 -12
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.js +1 -1
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +27 -3
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +8 -11
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -3
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -3
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.d.ts +69 -10
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +135 -13
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/smtp/index.js +130 -16
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +30 -2
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +35 -12
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js +32 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +238 -31
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +198 -67
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +2 -362
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +18 -409
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +41 -194
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +27 -422
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +17 -20
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +1 -5
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +17 -20
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.d.ts +102 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +65 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +6 -0
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +7 -7
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +7 -1
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +6 -0
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.js +22 -17
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +98 -4
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +58 -5
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +122 -6
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/{chunk-DBEY4PJZ.js → chunk-6Ep1yQYe.js} +1 -1
- package/dist/react/testing/index.js +1 -1
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +195 -1
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +64 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/react/websocket/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -2
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +1 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +1 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +2 -2
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +24 -10
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js +10 -3
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +1 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +47 -9
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.js +19 -1
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +4 -5
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/websocket/index.browser.js +32 -5
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +3 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +42 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +685 -274
- package/src/api/files/__tests__/FileController.spec.ts +1 -1
- package/src/api/jobs/__tests__/$job.spec.ts +5 -1
- package/src/api/parameters/services/ParameterProvider.ts +21 -4
- package/src/api/users/__tests__/SessionService.spec.ts +99 -0
- package/src/api/users/__tests__/UserJobs.spec.ts +67 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +15 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/jobs/UserJobs.ts +44 -17
- package/src/api/users/providers/RealmProvider.ts +4 -0
- package/src/api/users/schemas/userQuerySchema.ts +0 -1
- package/src/api/users/services/SessionService.ts +27 -0
- package/src/api/users/services/UserService.ts +1 -5
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
- package/src/api/verifications/services/VerificationService.ts +1 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +74 -0
- package/src/bucket/index.ts +19 -2
- package/src/bucket/primitives/$bucket.ts +9 -1
- package/src/bucket/providers/CloudflareR2Provider.ts +2 -137
- package/src/bucket/providers/NodeS3BucketProvider.ts +218 -0
- package/src/cache/core/index.ts +29 -0
- package/src/cache/core/primitives/$cache.ts +14 -1
- package/src/cli/config/defineConfig.ts +13 -15
- package/src/cli/core/__tests__/init.spec.ts +214 -7
- package/src/cli/core/commands/init.ts +12 -0
- package/src/cli/core/services/PackageManagerUtils.ts +23 -6
- package/src/cli/core/services/ProjectScaffolder.ts +315 -33
- package/src/cli/core/tasks/BuildCloudflareTask.ts +5 -0
- package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
- package/src/cli/core/tasks/BuildServerTask.ts +8 -0
- package/src/cli/core/templates/agentMd.ts +2 -10
- package/src/cli/core/templates/apiIndexTs.ts +23 -1
- package/src/cli/core/templates/componentsJsonTs.ts +39 -0
- package/src/cli/core/templates/mainCss.ts +1 -0
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
- package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
- package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
- package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
- package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
- package/src/cli/core/templates/webAppRouterTs.ts +104 -1
- package/src/cli/core/templates/webIndexTs.ts +23 -1
- package/src/cli/devtools/index.ts +12 -26
- package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
- package/src/cli/platform/index.ts +15 -24
- package/src/cli/vendor/atoms/vendorOptions.ts +1 -1
- package/src/cli/vendor/index.ts +14 -23
- package/src/command/providers/CliProvider.ts +1 -1
- package/src/core/Alepha.ts +11 -1
- package/src/core/helpers/ref.ts +18 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/interfaces/Service.ts +3 -1
- package/src/core/providers/SchemaValidator.ts +9 -1
- package/src/core/providers/TypeProvider.ts +2 -3
- package/src/datetime/REFACTORING.md +118 -0
- package/src/datetime/providers/DateTimeProvider.ts +203 -24
- package/src/lock/core/index.ts +31 -0
- package/src/lock/core/primitives/$lock.ts +14 -1
- package/src/logger/services/Logger.ts +1 -1
- package/src/mcp/__tests__/$resource.spec.ts +1 -1
- package/src/mcp/__tests__/$tool.spec.ts +1 -1
- package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
- package/src/mcp/__tests__/jsonrpc.spec.ts +1 -1
- package/src/mcp/helpers/jsonrpc.ts +26 -1
- package/src/mcp/index.ts +10 -5
- package/src/mcp/interfaces/McpTypes.ts +83 -6
- package/src/mcp/primitives/$prompt.ts +18 -1
- package/src/mcp/primitives/$resource.ts +18 -1
- package/src/mcp/primitives/$tool.ts +83 -7
- package/src/mcp/providers/McpServerProvider.ts +74 -16
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +226 -0
- package/src/orm/REFACTORING.md +330 -0
- package/src/orm/__tests__/$repository-tests.ts +1 -0
- package/src/orm/__tests__/orm-next-tests.ts +2 -67
- package/src/orm/__tests__/orm-next.spec.ts +0 -21
- package/src/orm/core/index.shared.ts +0 -2
- package/src/orm/core/index.ts +1 -2
- package/src/orm/core/primitives/$repository.ts +3 -6
- package/src/orm/core/primitives/$transactional.ts +11 -0
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
- package/src/orm/core/schemas/updateSchema.ts +1 -1
- package/src/orm/core/services/ModelBuilder.ts +1 -13
- package/src/orm/core/services/PgRelationManager.ts +4 -2
- package/src/orm/core/services/Repository.ts +1 -42
- package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
- package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +86 -0
- package/src/react/core/hooks/useQuery.ts +153 -0
- package/src/react/core/index.ts +1 -0
- package/src/react/form/services/FormModel.ts +15 -6
- package/src/react/form/services/parseField.ts +8 -0
- package/src/react/i18n/providers/I18nProvider.ts +8 -2
- package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
- package/src/react/router/__tests__/$page.spec.tsx +0 -16
- package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
- package/src/react/router/__tests__/ssr.spec.tsx +339 -0
- package/src/react/router/primitives/$page.ts +28 -4
- package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
- package/src/react/router/providers/ReactPageProvider.ts +27 -9
- package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
- package/src/react/router/providers/ReactServerProvider.ts +1 -0
- package/src/react/ui/atoms/uiThemeListAtom.ts +36 -0
- package/src/react/ui/index.ts +6 -0
- package/src/react/ui/services/SchemaControl.ts +209 -0
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/primitives/$basicAuth.ts +1 -1
- package/src/security/primitives/$issuer.ts +6 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +75 -0
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +306 -0
- package/src/server/core/errors/ValidationError.ts +13 -1
- package/src/server/core/interfaces/ServerRequest.ts +1 -0
- package/src/server/core/primitives/$action.ts +16 -5
- package/src/server/core/providers/ServerProvider.ts +1 -1
- package/src/server/core/providers/ServerRouterProvider.ts +28 -6
- package/src/server/core/services/HttpClient.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +6 -8
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +10 -4
- package/src/websocket/services/WebSocketClient.ts +11 -5
- package/src/mcp/transports/SseMcpTransport.ts +0 -182
- package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
- package/src/orm/core/helpers/parseQueryString.ts +0 -502
- package/src/orm/core/primitives/$view.ts +0 -88
package/dist/orm/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./chunk-o8xxKEmq.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { $atom, $context, $env, $hook, $inject, $mode, $module, $state, Alepha, AlephaError, KIND, Primitive,
|
|
3
|
+
import { $atom, $context, $env, $hook, $inject, $mode, $module, $state, Alepha, AlephaError, KIND, Primitive, SchemaValidator, createMiddleware, createPagination, createPrimitive, pageQuerySchema, pageSchema, pageSchema as pageSchema$1, t } from "alepha";
|
|
4
4
|
import { AlephaDateTime, DateTimeProvider } from "alepha/datetime";
|
|
5
5
|
import { mkdir, stat } from "node:fs/promises";
|
|
6
6
|
import { $logger } from "alepha/logger";
|
|
@@ -10,7 +10,11 @@ import { alias, customType } from "drizzle-orm/pg-core";
|
|
|
10
10
|
import { dirname } from "node:path";
|
|
11
11
|
import { randomUUID } from "node:crypto";
|
|
12
12
|
import * as pg from "drizzle-orm/sqlite-core";
|
|
13
|
-
import { check, foreignKey, index, sqliteTable,
|
|
13
|
+
import { check, foreignKey, index, sqliteTable, unique, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
14
|
+
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
|
15
|
+
import { BetterSQLiteSession } from "drizzle-orm/better-sqlite3/session";
|
|
16
|
+
import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core/db";
|
|
17
|
+
import { SQLiteSyncDialect } from "drizzle-orm/sqlite-core/dialect";
|
|
14
18
|
import { currentUserAtom } from "alepha/security";
|
|
15
19
|
import { isSQLWrapper as isSQLWrapper$1 } from "drizzle-orm/sql/sql";
|
|
16
20
|
export * from "drizzle-orm/pg-core";
|
|
@@ -38,6 +42,13 @@ var DbError = class extends AlephaError {
|
|
|
38
42
|
*/
|
|
39
43
|
const databaseEnvSchema = t.object({
|
|
40
44
|
DATABASE_URL: t.optional(t.text()),
|
|
45
|
+
/**
|
|
46
|
+
* Enable or disable push-based schema synchronization (drizzle-kit push).
|
|
47
|
+
*
|
|
48
|
+
* Defaults to `true` in development and test, `false` in production.
|
|
49
|
+
* Set to `false` in development to skip automatic schema sync
|
|
50
|
+
* (e.g. when managing migrations manually).
|
|
51
|
+
*/
|
|
41
52
|
DATABASE_SYNC: t.optional(t.boolean())
|
|
42
53
|
});
|
|
43
54
|
//#endregion
|
|
@@ -353,9 +364,6 @@ var DatabaseProvider = class {
|
|
|
353
364
|
this.entityPrimitives.push(entity);
|
|
354
365
|
this.builder.buildTable(entity, this);
|
|
355
366
|
}
|
|
356
|
-
registerView(view) {
|
|
357
|
-
this.builder.buildView(view, this);
|
|
358
|
-
}
|
|
359
367
|
registerSequence(sequence) {
|
|
360
368
|
this.sequencePrimitives.push(sequence);
|
|
361
369
|
this.builder.buildSequence(sequence, this);
|
|
@@ -522,7 +530,7 @@ const updateSchema = (schema) => {
|
|
|
522
530
|
for (const key in schema.properties) {
|
|
523
531
|
const prop = schema.properties[key];
|
|
524
532
|
if (PG_GENERATED in prop) continue;
|
|
525
|
-
if (t.schema.isOptional(prop)) newProperties[key] = t.optional(t.union([prop, t.
|
|
533
|
+
if (t.schema.isOptional(prop)) newProperties[key] = t.optional(t.union([prop, t.null()]));
|
|
526
534
|
else newProperties[key] = prop;
|
|
527
535
|
}
|
|
528
536
|
return t.object(newProperties, "options" in schema && typeof schema.options === "object" ? { ...schema.options } : {});
|
|
@@ -612,58 +620,6 @@ var SequencePrimitive = class extends Primitive {
|
|
|
612
620
|
};
|
|
613
621
|
$sequence[KIND] = SequencePrimitive;
|
|
614
622
|
//#endregion
|
|
615
|
-
//#region ../../src/orm/core/primitives/$view.ts
|
|
616
|
-
/**
|
|
617
|
-
* Creates a database view primitive from a TypeBox schema and SQL query.
|
|
618
|
-
*
|
|
619
|
-
* Views are read-only: Repository blocks all write operations.
|
|
620
|
-
*
|
|
621
|
-
* @example
|
|
622
|
-
* ```ts
|
|
623
|
-
* import { t } from "alepha";
|
|
624
|
-
* import { $view } from "alepha/orm";
|
|
625
|
-
* import { sql } from "drizzle-orm";
|
|
626
|
-
*
|
|
627
|
-
* const userSummary = $view({
|
|
628
|
-
* name: "user_summary",
|
|
629
|
-
* schema: t.object({
|
|
630
|
-
* id: t.uuid(),
|
|
631
|
-
* fullName: t.text(),
|
|
632
|
-
* orderCount: t.integer(),
|
|
633
|
-
* }),
|
|
634
|
-
* query: sql`SELECT u.id, u.first_name || ' ' || u.last_name AS full_name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id`,
|
|
635
|
-
* });
|
|
636
|
-
*
|
|
637
|
-
* // Materialized view (PostgreSQL only)
|
|
638
|
-
* const monthlyStats = $view({
|
|
639
|
-
* name: "monthly_stats",
|
|
640
|
-
* schema: t.object({ ... }),
|
|
641
|
-
* query: sql`...`,
|
|
642
|
-
* materialized: true,
|
|
643
|
-
* });
|
|
644
|
-
* ```
|
|
645
|
-
*/
|
|
646
|
-
const $view = (options) => {
|
|
647
|
-
return new ViewPrimitive(options);
|
|
648
|
-
};
|
|
649
|
-
var ViewPrimitive = class {
|
|
650
|
-
options;
|
|
651
|
-
isView = true;
|
|
652
|
-
constructor(options) {
|
|
653
|
-
this.options = options;
|
|
654
|
-
}
|
|
655
|
-
get name() {
|
|
656
|
-
return this.options.name;
|
|
657
|
-
}
|
|
658
|
-
get schema() {
|
|
659
|
-
return this.options.schema;
|
|
660
|
-
}
|
|
661
|
-
get materialized() {
|
|
662
|
-
return this.options.materialized ?? false;
|
|
663
|
-
}
|
|
664
|
-
};
|
|
665
|
-
$view[KIND] = ViewPrimitive;
|
|
666
|
-
//#endregion
|
|
667
623
|
//#region ../../src/orm/core/services/ModelBuilder.ts
|
|
668
624
|
/**
|
|
669
625
|
* Abstract base class for transforming Alepha Primitives (Entity, Sequence, etc...)
|
|
@@ -729,7 +685,7 @@ var ModelBuilder = class {
|
|
|
729
685
|
const fkName = fkDef.name || `${entity.name}_${columnNames.join("_")}_fk`;
|
|
730
686
|
const foreignColumns = fkDef.foreignColumns.map((colRef) => {
|
|
731
687
|
const entityCol = colRef();
|
|
732
|
-
if (!entityCol
|
|
688
|
+
if (!entityCol?.entity || !entityCol.name) throw new AlephaError(`Invalid foreign column reference in ${entity.name}`);
|
|
733
689
|
if (tableResolver) {
|
|
734
690
|
const foreignTable = tableResolver(entityCol.entity.name);
|
|
735
691
|
if (!foreignTable) throw new AlephaError(`Foreign table ${entityCol.entity.name} not found for ${entity.name}`);
|
|
@@ -776,13 +732,6 @@ var SqliteModelBuilder = class extends ModelBuilder {
|
|
|
776
732
|
const table = sqliteTable(tableName, this.schemaToSqliteColumns(tableName, entity.schema, options.enums, options.tables), this.getTableConfig(entity, options.tables));
|
|
777
733
|
options.tables.set(tableName, table);
|
|
778
734
|
}
|
|
779
|
-
buildView(view, options) {
|
|
780
|
-
const viewName = view.name;
|
|
781
|
-
if (options.tables.has(viewName)) return;
|
|
782
|
-
if (view.materialized) throw new AlephaError("SQLite does not support materialized views");
|
|
783
|
-
const drizzleView = sqliteView(viewName, this.schemaToSqliteColumns(viewName, view.schema, /* @__PURE__ */ new Map(), options.tables)).existing();
|
|
784
|
-
options.tables.set(viewName, drizzleView);
|
|
785
|
-
}
|
|
786
735
|
buildSequence(sequence, options) {
|
|
787
736
|
throw new AlephaError("SQLite does not support sequences");
|
|
788
737
|
}
|
|
@@ -826,10 +775,8 @@ var SqliteModelBuilder = class extends ModelBuilder {
|
|
|
826
775
|
col = col.generatedAlwaysAs(gen.expression, { mode: gen.mode ?? "virtual" });
|
|
827
776
|
}
|
|
828
777
|
if (schema.required?.includes(key)) col = col.notNull();
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
[key]: col
|
|
832
|
-
};
|
|
778
|
+
columns[key] = col;
|
|
779
|
+
return columns;
|
|
833
780
|
}, {});
|
|
834
781
|
};
|
|
835
782
|
mapFieldToSqliteColumn = (tableName, fieldName, value, enums) => {
|
|
@@ -1183,7 +1130,7 @@ var NodeSqliteProvider = class NodeSqliteProvider extends DatabaseProvider {
|
|
|
1183
1130
|
onStart = $hook({
|
|
1184
1131
|
on: "start",
|
|
1185
1132
|
handler: async () => {
|
|
1186
|
-
const { DatabaseSync } =
|
|
1133
|
+
const { DatabaseSync } = await import("node:sqlite");
|
|
1187
1134
|
const filepath = this.url.replace("sqlite://", "").replace("sqlite:", "");
|
|
1188
1135
|
if (filepath !== ":memory:" && filepath !== "") {
|
|
1189
1136
|
const dir = dirname(filepath);
|
|
@@ -1288,18 +1235,14 @@ var NodeSqliteProvider = class NodeSqliteProvider extends DatabaseProvider {
|
|
|
1288
1235
|
*/
|
|
1289
1236
|
initDrizzle() {
|
|
1290
1237
|
this.shimDatabaseSync();
|
|
1291
|
-
const require = createRequire(import.meta.url);
|
|
1292
|
-
const { BetterSQLiteSession } = require("drizzle-orm/better-sqlite3/session");
|
|
1293
|
-
const { SQLiteSyncDialect } = require("drizzle-orm/sqlite-core/dialect");
|
|
1294
|
-
const { BaseSQLiteDatabase } = require("drizzle-orm/sqlite-core/db");
|
|
1295
1238
|
const dialect = new SQLiteSyncDialect();
|
|
1296
|
-
|
|
1239
|
+
const session = new BetterSQLiteSession(this.sqlite, dialect, void 0, { logger: { logQuery: (query, params) => {
|
|
1297
1240
|
this.log.trace(query, { params });
|
|
1298
|
-
} } })
|
|
1241
|
+
} } });
|
|
1242
|
+
this.drizzleDb = new BaseSQLiteDatabase("sync", dialect, session, void 0);
|
|
1299
1243
|
this.log.debug("Using node:sqlite with sync driver");
|
|
1300
1244
|
}
|
|
1301
1245
|
async executeMigrations(migrationsFolder) {
|
|
1302
|
-
const { migrate } = createRequire(import.meta.url)("drizzle-orm/better-sqlite3/migrator");
|
|
1303
1246
|
migrate(this.drizzleDb, { migrationsFolder });
|
|
1304
1247
|
}
|
|
1305
1248
|
};
|
|
@@ -1630,6 +1573,7 @@ var DbCacheProvider = class {
|
|
|
1630
1573
|
//#endregion
|
|
1631
1574
|
//#region ../../src/orm/core/services/PgRelationManager.ts
|
|
1632
1575
|
var PgRelationManager = class {
|
|
1576
|
+
schemaValidator = $inject(SchemaValidator);
|
|
1633
1577
|
/**
|
|
1634
1578
|
* Recursively build joins for the query builder based on the relations map
|
|
1635
1579
|
*/
|
|
@@ -1676,7 +1620,7 @@ var PgRelationManager = class {
|
|
|
1676
1620
|
* Build a schema that includes all join properties recursively
|
|
1677
1621
|
*/
|
|
1678
1622
|
buildSchemaWithJoins(baseSchema, joins, parentPath) {
|
|
1679
|
-
const schema =
|
|
1623
|
+
const schema = this.schemaValidator.clone(baseSchema);
|
|
1680
1624
|
const joinsAtThisLevel = joins.filter((j) => j.parent === parentPath);
|
|
1681
1625
|
for (const join of joinsAtThisLevel) {
|
|
1682
1626
|
const joinPath = parentPath ? `${parentPath}.${join.key}` : join.key;
|
|
@@ -1951,8 +1895,7 @@ var Repository = class Repository {
|
|
|
1951
1895
|
constructor(entity, provider = DatabaseProvider) {
|
|
1952
1896
|
this.entity = entity;
|
|
1953
1897
|
this.provider = this.alepha.inject(provider);
|
|
1954
|
-
|
|
1955
|
-
else this.provider.registerEntity(entity);
|
|
1898
|
+
this.provider.registerEntity(entity);
|
|
1956
1899
|
}
|
|
1957
1900
|
/**
|
|
1958
1901
|
* Represents the primary key of the table.
|
|
@@ -1977,12 +1920,6 @@ var Repository = class Repository {
|
|
|
1977
1920
|
return this.entity.name;
|
|
1978
1921
|
}
|
|
1979
1922
|
/**
|
|
1980
|
-
* Whether this repository is backed by a view (read-only).
|
|
1981
|
-
*/
|
|
1982
|
-
get isReadOnly() {
|
|
1983
|
-
return this.entity.isView === true;
|
|
1984
|
-
}
|
|
1985
|
-
/**
|
|
1986
1923
|
* Getter for the database connection from the database provider.
|
|
1987
1924
|
*
|
|
1988
1925
|
* Automatically picks up a transaction from `alepha.store` if one was set
|
|
@@ -2258,7 +2195,6 @@ var Repository = class Repository {
|
|
|
2258
2195
|
* @returns The ID of the created entity.
|
|
2259
2196
|
*/
|
|
2260
2197
|
async create(data, opts = {}) {
|
|
2261
|
-
this.assertWritable();
|
|
2262
2198
|
this.stampOrganization(data);
|
|
2263
2199
|
await this.alepha.events.emit("repository:create:before", {
|
|
2264
2200
|
tableName: this.tableName,
|
|
@@ -2287,7 +2223,6 @@ var Repository = class Repository {
|
|
|
2287
2223
|
* @returns The created entities.
|
|
2288
2224
|
*/
|
|
2289
2225
|
async createMany(values, opts = {}) {
|
|
2290
|
-
this.assertWritable();
|
|
2291
2226
|
if (values.length === 0) return [];
|
|
2292
2227
|
for (const value of values) this.stampOrganization(value);
|
|
2293
2228
|
await this.alepha.events.emit("repository:create:before", {
|
|
@@ -2343,7 +2278,6 @@ var Repository = class Repository {
|
|
|
2343
2278
|
* ```
|
|
2344
2279
|
*/
|
|
2345
2280
|
async upsert(data, opts = {}) {
|
|
2346
|
-
this.assertWritable();
|
|
2347
2281
|
this.stampOrganization(data);
|
|
2348
2282
|
await this.alepha.events.emit("repository:create:before", {
|
|
2349
2283
|
tableName: this.tableName,
|
|
@@ -2380,7 +2314,6 @@ var Repository = class Repository {
|
|
|
2380
2314
|
* Find an entity and update it.
|
|
2381
2315
|
*/
|
|
2382
2316
|
async updateOne(where, data, opts = {}) {
|
|
2383
|
-
this.assertWritable();
|
|
2384
2317
|
await this.alepha.events.emit("repository:update:before", {
|
|
2385
2318
|
tableName: this.tableName,
|
|
2386
2319
|
where,
|
|
@@ -2431,7 +2364,6 @@ var Repository = class Repository {
|
|
|
2431
2364
|
* @see {@link DbVersionMismatchError}
|
|
2432
2365
|
*/
|
|
2433
2366
|
async save(entity, opts = {}) {
|
|
2434
|
-
this.assertWritable();
|
|
2435
2367
|
const row = entity;
|
|
2436
2368
|
const id = row[this.id.key];
|
|
2437
2369
|
if (id == null) throw new AlephaError("Cannot save entity without ID - missing primary key in value");
|
|
@@ -2469,7 +2401,6 @@ var Repository = class Repository {
|
|
|
2469
2401
|
* Find many entities and update all of them.
|
|
2470
2402
|
*/
|
|
2471
2403
|
async updateMany(where, data, opts = {}) {
|
|
2472
|
-
this.assertWritable();
|
|
2473
2404
|
await this.alepha.events.emit("repository:update:before", {
|
|
2474
2405
|
tableName: this.tableName,
|
|
2475
2406
|
where,
|
|
@@ -2498,7 +2429,6 @@ var Repository = class Repository {
|
|
|
2498
2429
|
* @returns Array of deleted entity IDs
|
|
2499
2430
|
*/
|
|
2500
2431
|
async deleteMany(where = {}, opts = {}) {
|
|
2501
|
-
this.assertWritable();
|
|
2502
2432
|
const deletedAt = this.deletedAt();
|
|
2503
2433
|
if (deletedAt && !opts.force) return await this.updateMany(where, { [deletedAt.key]: opts.now ?? this.dateTimeProvider.nowISOString() }, opts);
|
|
2504
2434
|
where = this.withOrganization(where);
|
|
@@ -2752,19 +2682,6 @@ var Repository = class Repository {
|
|
|
2752
2682
|
return entity;
|
|
2753
2683
|
}
|
|
2754
2684
|
/**
|
|
2755
|
-
* Throw if this repository is read-only (backed by a view).
|
|
2756
|
-
*/
|
|
2757
|
-
assertWritable() {
|
|
2758
|
-
if (this.isReadOnly) throw new AlephaError(`Cannot write to view '${this.tableName}'. Views are read-only.`);
|
|
2759
|
-
}
|
|
2760
|
-
/**
|
|
2761
|
-
* Refresh a materialized view. PostgreSQL only.
|
|
2762
|
-
*/
|
|
2763
|
-
async refresh() {
|
|
2764
|
-
if (!this.entity.materialized) throw new AlephaError(`Cannot refresh '${this.tableName}'. Only materialized views support refresh.`);
|
|
2765
|
-
await this.provider.execute(`REFRESH MATERIALIZED VIEW ${this.tableName}`);
|
|
2766
|
-
}
|
|
2767
|
-
/**
|
|
2768
2685
|
* Build a cache key from method name and query parameters.
|
|
2769
2686
|
*/
|
|
2770
2687
|
buildCacheKey(method, query) {
|
|
@@ -2905,314 +2822,6 @@ var DbConnectionError = class DbConnectionError extends DbError {
|
|
|
2905
2822
|
}
|
|
2906
2823
|
};
|
|
2907
2824
|
//#endregion
|
|
2908
|
-
//#region ../../src/orm/core/helpers/parseQueryString.ts
|
|
2909
|
-
/**
|
|
2910
|
-
* Parse a string query into a PgQueryWhere object.
|
|
2911
|
-
*
|
|
2912
|
-
* Supported syntax:
|
|
2913
|
-
* - Simple equality: "name=John"
|
|
2914
|
-
* - Wildcard patterns: "name=John*" (startsWith), "name=*John" (endsWith), "name=*John*" (contains)
|
|
2915
|
-
* - Operators: "age>18", "age>=18", "age<65", "age<=65", "status!=active"
|
|
2916
|
-
* - NULL checks: "deletedAt=null", "email!=null"
|
|
2917
|
-
* - IN arrays: "status=[pending,active]"
|
|
2918
|
-
* - AND conditions: "name=John&age>18"
|
|
2919
|
-
* - OR conditions: "name=John|email=john@example.com"
|
|
2920
|
-
* - Nested AND/OR: "(name=John|name=Jane)&age>18"
|
|
2921
|
-
* - JSONB nested: "profile.city=Paris"
|
|
2922
|
-
*
|
|
2923
|
-
* @example
|
|
2924
|
-
* ```ts
|
|
2925
|
-
* // Simple equality
|
|
2926
|
-
* parseQueryString("name=John")
|
|
2927
|
-
* // => { name: { eq: "John" } }
|
|
2928
|
-
*
|
|
2929
|
-
* // Wildcard patterns
|
|
2930
|
-
* parseQueryString("name=John*") // startsWith
|
|
2931
|
-
* // => { name: { startsWith: "John" } }
|
|
2932
|
-
* parseQueryString("name=*Smith") // endsWith
|
|
2933
|
-
* // => { name: { endsWith: "Smith" } }
|
|
2934
|
-
* parseQueryString("name=*oh*") // contains
|
|
2935
|
-
* // => { name: { contains: "oh" } }
|
|
2936
|
-
*
|
|
2937
|
-
* // Multiple conditions
|
|
2938
|
-
* parseQueryString("name=John&age>18")
|
|
2939
|
-
* // => { and: [{ name: { eq: "John" } }, { age: { gt: 18 } }] }
|
|
2940
|
-
*
|
|
2941
|
-
* // OR conditions
|
|
2942
|
-
* parseQueryString("status=active|status=pending")
|
|
2943
|
-
* // => { or: [{ status: { eq: "active" } }, { status: { eq: "pending" } }] }
|
|
2944
|
-
*
|
|
2945
|
-
* // Complex nested
|
|
2946
|
-
* parseQueryString("(name=John|name=Jane)&age>18&status!=archived")
|
|
2947
|
-
* // => { and: [
|
|
2948
|
-
* // { or: [{ name: { eq: "John" } }, { name: { eq: "Jane" } }] },
|
|
2949
|
-
* // { age: { gt: 18 } },
|
|
2950
|
-
* // { status: { ne: "archived" } }
|
|
2951
|
-
* // ] }
|
|
2952
|
-
*
|
|
2953
|
-
* // JSONB nested query
|
|
2954
|
-
* parseQueryString("profile.city=Paris&profile.age>25")
|
|
2955
|
-
* // => { profile: { city: { eq: "Paris" }, age: { gt: 25 } } }
|
|
2956
|
-
* ```
|
|
2957
|
-
*/
|
|
2958
|
-
function parseQueryString(query) {
|
|
2959
|
-
if (!query || query.trim() === "") return {};
|
|
2960
|
-
return new QueryStringParser(query).parse();
|
|
2961
|
-
}
|
|
2962
|
-
var QueryStringParser = class {
|
|
2963
|
-
pos = 0;
|
|
2964
|
-
query;
|
|
2965
|
-
constructor(query) {
|
|
2966
|
-
this.query = query.trim();
|
|
2967
|
-
}
|
|
2968
|
-
parse() {
|
|
2969
|
-
return this.parseExpression();
|
|
2970
|
-
}
|
|
2971
|
-
parseExpression() {
|
|
2972
|
-
return this.parseOr();
|
|
2973
|
-
}
|
|
2974
|
-
parseOr() {
|
|
2975
|
-
const left = this.parseAnd();
|
|
2976
|
-
if (this.peek() === "|") {
|
|
2977
|
-
const conditions = [left];
|
|
2978
|
-
while (this.peek() === "|") {
|
|
2979
|
-
this.consume("|");
|
|
2980
|
-
conditions.push(this.parseAnd());
|
|
2981
|
-
}
|
|
2982
|
-
return { or: conditions };
|
|
2983
|
-
}
|
|
2984
|
-
return left;
|
|
2985
|
-
}
|
|
2986
|
-
parseAnd() {
|
|
2987
|
-
const left = this.parsePrimary();
|
|
2988
|
-
if (this.peek() === "&") {
|
|
2989
|
-
const conditions = [left];
|
|
2990
|
-
while (this.peek() === "&") {
|
|
2991
|
-
this.consume("&");
|
|
2992
|
-
conditions.push(this.parsePrimary());
|
|
2993
|
-
}
|
|
2994
|
-
return { and: conditions };
|
|
2995
|
-
}
|
|
2996
|
-
return left;
|
|
2997
|
-
}
|
|
2998
|
-
parsePrimary() {
|
|
2999
|
-
this.skipWhitespace();
|
|
3000
|
-
if (this.peek() === "(") {
|
|
3001
|
-
this.consume("(");
|
|
3002
|
-
const expr = this.parseExpression();
|
|
3003
|
-
this.consume(")");
|
|
3004
|
-
return expr;
|
|
3005
|
-
}
|
|
3006
|
-
return this.parseCondition();
|
|
3007
|
-
}
|
|
3008
|
-
parseCondition() {
|
|
3009
|
-
const field = this.parseFieldPath();
|
|
3010
|
-
this.skipWhitespace();
|
|
3011
|
-
const operator = this.parseOperator();
|
|
3012
|
-
this.skipWhitespace();
|
|
3013
|
-
const value = this.parseValue();
|
|
3014
|
-
if (value === "") throw new AlephaError(`Expected value for field '${field.join(".")}'`);
|
|
3015
|
-
return this.buildCondition(field, operator, value);
|
|
3016
|
-
}
|
|
3017
|
-
parseFieldPath() {
|
|
3018
|
-
const path = [];
|
|
3019
|
-
let current = "";
|
|
3020
|
-
while (this.pos < this.query.length) {
|
|
3021
|
-
const ch = this.query[this.pos];
|
|
3022
|
-
if (ch === "." && current) {
|
|
3023
|
-
path.push(current);
|
|
3024
|
-
current = "";
|
|
3025
|
-
this.pos++;
|
|
3026
|
-
continue;
|
|
3027
|
-
}
|
|
3028
|
-
if (ch === "=" || ch === "!" || ch === ">" || ch === "<" || ch === " ") break;
|
|
3029
|
-
current += ch;
|
|
3030
|
-
this.pos++;
|
|
3031
|
-
}
|
|
3032
|
-
if (current) path.push(current);
|
|
3033
|
-
return path;
|
|
3034
|
-
}
|
|
3035
|
-
parseOperator() {
|
|
3036
|
-
this.skipWhitespace();
|
|
3037
|
-
const remaining = this.query.slice(this.pos);
|
|
3038
|
-
if (remaining.startsWith(">=")) {
|
|
3039
|
-
this.pos += 2;
|
|
3040
|
-
return ">=";
|
|
3041
|
-
}
|
|
3042
|
-
if (remaining.startsWith("<=")) {
|
|
3043
|
-
this.pos += 2;
|
|
3044
|
-
return "<=";
|
|
3045
|
-
}
|
|
3046
|
-
if (remaining.startsWith("!=")) {
|
|
3047
|
-
this.pos += 2;
|
|
3048
|
-
return "!=";
|
|
3049
|
-
}
|
|
3050
|
-
const ch = this.query[this.pos];
|
|
3051
|
-
if (ch === "=" || ch === ">" || ch === "<") {
|
|
3052
|
-
this.pos++;
|
|
3053
|
-
return ch;
|
|
3054
|
-
}
|
|
3055
|
-
throw new AlephaError(`Expected operator at position ${this.pos}`);
|
|
3056
|
-
}
|
|
3057
|
-
parseValue() {
|
|
3058
|
-
this.skipWhitespace();
|
|
3059
|
-
if (this.query.slice(this.pos, this.pos + 4).toLowerCase() === "null") {
|
|
3060
|
-
this.pos += 4;
|
|
3061
|
-
return null;
|
|
3062
|
-
}
|
|
3063
|
-
if (this.query[this.pos] === "[") return this.parseArray();
|
|
3064
|
-
if (this.query[this.pos] === "\"" || this.query[this.pos] === "'") return this.parseQuotedString();
|
|
3065
|
-
let value = "";
|
|
3066
|
-
while (this.pos < this.query.length) {
|
|
3067
|
-
const ch = this.query[this.pos];
|
|
3068
|
-
if (ch === "&" || ch === "|" || ch === ")") break;
|
|
3069
|
-
value += ch;
|
|
3070
|
-
this.pos++;
|
|
3071
|
-
}
|
|
3072
|
-
return this.coerceValue(value.trim());
|
|
3073
|
-
}
|
|
3074
|
-
parseArray() {
|
|
3075
|
-
this.consume("[");
|
|
3076
|
-
const values = [];
|
|
3077
|
-
while (this.pos < this.query.length && this.query[this.pos] !== "]") {
|
|
3078
|
-
this.skipWhitespace();
|
|
3079
|
-
if (this.query[this.pos] === "\"" || this.query[this.pos] === "'") values.push(this.parseQuotedString());
|
|
3080
|
-
else {
|
|
3081
|
-
let value = "";
|
|
3082
|
-
while (this.pos < this.query.length && this.query[this.pos] !== "," && this.query[this.pos] !== "]") {
|
|
3083
|
-
value += this.query[this.pos];
|
|
3084
|
-
this.pos++;
|
|
3085
|
-
}
|
|
3086
|
-
values.push(this.coerceValue(value.trim()));
|
|
3087
|
-
}
|
|
3088
|
-
this.skipWhitespace();
|
|
3089
|
-
if (this.query[this.pos] === ",") this.pos++;
|
|
3090
|
-
}
|
|
3091
|
-
this.consume("]");
|
|
3092
|
-
return values;
|
|
3093
|
-
}
|
|
3094
|
-
parseQuotedString() {
|
|
3095
|
-
const quote = this.query[this.pos];
|
|
3096
|
-
this.pos++;
|
|
3097
|
-
let value = "";
|
|
3098
|
-
let escaped = false;
|
|
3099
|
-
while (this.pos < this.query.length) {
|
|
3100
|
-
const ch = this.query[this.pos];
|
|
3101
|
-
if (escaped) {
|
|
3102
|
-
value += ch;
|
|
3103
|
-
escaped = false;
|
|
3104
|
-
this.pos++;
|
|
3105
|
-
continue;
|
|
3106
|
-
}
|
|
3107
|
-
if (ch === "\\") {
|
|
3108
|
-
escaped = true;
|
|
3109
|
-
this.pos++;
|
|
3110
|
-
continue;
|
|
3111
|
-
}
|
|
3112
|
-
if (ch === quote) {
|
|
3113
|
-
this.pos++;
|
|
3114
|
-
break;
|
|
3115
|
-
}
|
|
3116
|
-
value += ch;
|
|
3117
|
-
this.pos++;
|
|
3118
|
-
}
|
|
3119
|
-
return value;
|
|
3120
|
-
}
|
|
3121
|
-
coerceValue(value) {
|
|
3122
|
-
if (/^-?\d+$/.test(value)) return parseInt(value, 10);
|
|
3123
|
-
if (/^-?\d+\.\d+$/.test(value)) return parseFloat(value);
|
|
3124
|
-
if (value.toLowerCase() === "true") return true;
|
|
3125
|
-
if (value.toLowerCase() === "false") return false;
|
|
3126
|
-
return value;
|
|
3127
|
-
}
|
|
3128
|
-
buildCondition(path, operator, value) {
|
|
3129
|
-
let filterOp;
|
|
3130
|
-
if (operator === "=") if (value === null) filterOp = { isNull: true };
|
|
3131
|
-
else if (Array.isArray(value)) filterOp = { inArray: value };
|
|
3132
|
-
else if (typeof value === "string" && value.includes("*")) {
|
|
3133
|
-
const startsWithAsterisk = value.startsWith("*");
|
|
3134
|
-
const endsWithAsterisk = value.endsWith("*");
|
|
3135
|
-
const cleanValue = value.replace(/^\*|\*$/g, "");
|
|
3136
|
-
if (startsWithAsterisk && endsWithAsterisk) filterOp = { contains: cleanValue };
|
|
3137
|
-
else if (startsWithAsterisk) filterOp = { endsWith: cleanValue };
|
|
3138
|
-
else if (endsWithAsterisk) filterOp = { startsWith: cleanValue };
|
|
3139
|
-
else filterOp = { eq: value };
|
|
3140
|
-
} else filterOp = { eq: value };
|
|
3141
|
-
else if (operator === "!=") if (value === null) filterOp = { isNotNull: true };
|
|
3142
|
-
else filterOp = { ne: value };
|
|
3143
|
-
else if (operator === ">") filterOp = { gt: value };
|
|
3144
|
-
else if (operator === ">=") filterOp = { gte: value };
|
|
3145
|
-
else if (operator === "<") filterOp = { lt: value };
|
|
3146
|
-
else if (operator === "<=") filterOp = { lte: value };
|
|
3147
|
-
else throw new AlephaError(`Unsupported operator: ${operator}`);
|
|
3148
|
-
if (path.length === 1) return { [path[0]]: filterOp };
|
|
3149
|
-
let result = filterOp;
|
|
3150
|
-
for (let i = path.length - 1; i >= 0; i--) result = { [path[i]]: result };
|
|
3151
|
-
return result;
|
|
3152
|
-
}
|
|
3153
|
-
peek() {
|
|
3154
|
-
this.skipWhitespace();
|
|
3155
|
-
return this.query[this.pos] || "";
|
|
3156
|
-
}
|
|
3157
|
-
consume(expected) {
|
|
3158
|
-
this.skipWhitespace();
|
|
3159
|
-
if (this.query[this.pos] !== expected) throw new AlephaError(`Expected '${expected}' at position ${this.pos}, got '${this.query[this.pos]}'`);
|
|
3160
|
-
this.pos++;
|
|
3161
|
-
}
|
|
3162
|
-
skipWhitespace() {
|
|
3163
|
-
while (this.pos < this.query.length && /\s/.test(this.query[this.pos])) this.pos++;
|
|
3164
|
-
}
|
|
3165
|
-
};
|
|
3166
|
-
/**
|
|
3167
|
-
* Helper function to build query strings programmatically
|
|
3168
|
-
*
|
|
3169
|
-
* @example
|
|
3170
|
-
* ```ts
|
|
3171
|
-
* buildQueryString({
|
|
3172
|
-
* and: [
|
|
3173
|
-
* { name: "eq:John" },
|
|
3174
|
-
* { age: "gt:18" }
|
|
3175
|
-
* ]
|
|
3176
|
-
* })
|
|
3177
|
-
* // => "name=John&age>18"
|
|
3178
|
-
* ```
|
|
3179
|
-
*/
|
|
3180
|
-
function buildQueryString(where) {
|
|
3181
|
-
if (!where || typeof where !== "object") return "";
|
|
3182
|
-
if ("and" in where && Array.isArray(where.and)) return where.and.map((w) => buildQueryString(w)).join("&");
|
|
3183
|
-
if ("or" in where && Array.isArray(where.or)) {
|
|
3184
|
-
const parts = where.or.map((w) => buildQueryString(w));
|
|
3185
|
-
return parts.length > 1 ? `(${parts.join("|")})` : parts[0];
|
|
3186
|
-
}
|
|
3187
|
-
if ("not" in where) return "";
|
|
3188
|
-
const parts = [];
|
|
3189
|
-
for (const [field, condition] of Object.entries(where)) {
|
|
3190
|
-
if (typeof condition !== "object" || condition === null) {
|
|
3191
|
-
parts.push(`${field}=${condition}`);
|
|
3192
|
-
continue;
|
|
3193
|
-
}
|
|
3194
|
-
if ("eq" in condition) parts.push(`${field}=${condition.eq}`);
|
|
3195
|
-
else if ("ne" in condition) parts.push(`${field}!=${condition.ne}`);
|
|
3196
|
-
else if ("gt" in condition) parts.push(`${field}>${condition.gt}`);
|
|
3197
|
-
else if ("gte" in condition) parts.push(`${field}>=${condition.gte}`);
|
|
3198
|
-
else if ("lt" in condition) parts.push(`${field}<${condition.lt}`);
|
|
3199
|
-
else if ("lte" in condition) parts.push(`${field}<=${condition.lte}`);
|
|
3200
|
-
else if ("contains" in condition) parts.push(`${field}=*${condition.contains}*`);
|
|
3201
|
-
else if ("startsWith" in condition) parts.push(`${field}=${condition.startsWith}*`);
|
|
3202
|
-
else if ("endsWith" in condition) parts.push(`${field}=*${condition.endsWith}`);
|
|
3203
|
-
else if ("isNull" in condition && condition.isNull) parts.push(`${field}=null`);
|
|
3204
|
-
else if ("isNotNull" in condition && condition.isNotNull) parts.push(`${field}!=null`);
|
|
3205
|
-
else if ("inArray" in condition && Array.isArray(condition.inArray)) {
|
|
3206
|
-
const values = condition.inArray.map((v) => typeof v === "string" ? `"${v}"` : v);
|
|
3207
|
-
parts.push(`${field}=[${values.join(",")}]`);
|
|
3208
|
-
} else {
|
|
3209
|
-
const nested = buildQueryString(condition);
|
|
3210
|
-
if (nested) parts.push(`${field}.${nested}`);
|
|
3211
|
-
}
|
|
3212
|
-
}
|
|
3213
|
-
return parts.join("&");
|
|
3214
|
-
}
|
|
3215
|
-
//#endregion
|
|
3216
2825
|
//#region ../../src/orm/core/providers/DatabaseTypeProvider.ts
|
|
3217
2826
|
var DatabaseTypeProvider = class {
|
|
3218
2827
|
attr = pgAttr;
|
|
@@ -3321,7 +2930,7 @@ const legacyIdSchema = pgAttr(pgAttr(pgAttr(t.integer(), PG_PRIMARY_KEY), PG_SER
|
|
|
3321
2930
|
//#endregion
|
|
3322
2931
|
//#region ../../src/orm/core/primitives/$repository.ts
|
|
3323
2932
|
/**
|
|
3324
|
-
* Get the repository for the given entity
|
|
2933
|
+
* Get the repository for the given entity.
|
|
3325
2934
|
*/
|
|
3326
2935
|
const $repository = (entity) => {
|
|
3327
2936
|
const { alepha } = $context();
|
|
@@ -3423,11 +3032,7 @@ const schema = (name, document) => customType({
|
|
|
3423
3032
|
const SqliteProvider = NodeSqliteProvider;
|
|
3424
3033
|
const AlephaOrm = $module({
|
|
3425
3034
|
name: "alepha.orm",
|
|
3426
|
-
primitives: [
|
|
3427
|
-
$sequence,
|
|
3428
|
-
$entity,
|
|
3429
|
-
$view
|
|
3430
|
-
],
|
|
3035
|
+
primitives: [$sequence, $entity],
|
|
3431
3036
|
imports: [AlephaDateTime],
|
|
3432
3037
|
services: [
|
|
3433
3038
|
SqliteModelBuilder,
|
|
@@ -3460,6 +3065,6 @@ const AlephaOrm = $module({
|
|
|
3460
3065
|
}
|
|
3461
3066
|
});
|
|
3462
3067
|
//#endregion
|
|
3463
|
-
export { $entity, $repository, $seed, $sequence, $transactional,
|
|
3068
|
+
export { $entity, $repository, $seed, $sequence, $transactional, AlephaOrm, BunSqliteProvider, CloudflareD1Provider, DatabaseProvider, DatabaseTypeProvider, DbCacheProvider, DbColumnNotFoundError, DbConflictError, DbConnectionError, DbDeadlockError, DbEntityNotFoundError, DbError, DbForeignKeyError, DbMigrationError, DbMigrationMode, DbNotNullError, DbTableNotFoundError, DbVersionMismatchError, DrizzleKitProvider, EntityPrimitive, ModelBuilder, NodeSqliteProvider, PG_CREATED_AT, PG_DEFAULT, PG_DELETED_AT, PG_ENUM, PG_GENERATED, PG_IDENTITY, PG_ORGANIZATION, PG_PRIMARY_KEY, PG_REF, PG_SERIAL, PG_UPDATED_AT, PG_VERSION, Repository, RepositoryProvider, SequencePrimitive, SqliteProvider, bunSqliteOptions, databaseEnvSchema, db, drizzle, getAttrFields, insertSchema, legacyIdSchema, nodeSqliteOptions, pageQuerySchema, pageSchema, pgAttr, schema, sql, updateSchema };
|
|
3464
3069
|
|
|
3465
3070
|
//# sourceMappingURL=index.js.map
|