@apisr/drizzle-model 0.0.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/DISCLAIMER.md +5 -0
  2. package/TODO.md +8 -61
  3. package/package.json +2 -1
  4. package/src/core/dialect.ts +81 -0
  5. package/src/core/index.ts +24 -0
  6. package/src/core/query/error.ts +15 -0
  7. package/src/core/query/joins.ts +596 -0
  8. package/src/core/query/projection.ts +136 -0
  9. package/src/core/query/where.ts +449 -0
  10. package/src/core/result.ts +297 -0
  11. package/src/core/runtime.ts +612 -0
  12. package/src/core/transform.ts +119 -0
  13. package/src/model/builder.ts +40 -6
  14. package/src/model/config.ts +9 -9
  15. package/src/model/format.ts +20 -8
  16. package/src/model/methods/exclude.ts +1 -7
  17. package/src/model/methods/return.ts +11 -11
  18. package/src/model/methods/select.ts +2 -8
  19. package/src/model/model.ts +10 -16
  20. package/src/model/query/error.ts +1 -0
  21. package/src/model/result.ts +134 -21
  22. package/src/types.ts +38 -0
  23. package/tests/base/count.test.ts +47 -0
  24. package/tests/base/delete.test.ts +90 -0
  25. package/tests/base/find.test.ts +209 -0
  26. package/tests/base/insert.test.ts +152 -0
  27. package/tests/base/safe.test.ts +91 -0
  28. package/tests/base/update.test.ts +88 -0
  29. package/tests/base/upsert.test.ts +121 -0
  30. package/tests/base.ts +21 -0
  31. package/tests/snippets/x-1.ts +22 -0
  32. package/src/model/core/joins.ts +0 -364
  33. package/src/model/core/projection.ts +0 -61
  34. package/src/model/core/runtime.ts +0 -330
  35. package/src/model/core/thenable.ts +0 -94
  36. package/src/model/core/transform.ts +0 -65
  37. package/src/model/core/where.ts +0 -249
  38. package/src/model/core/with.ts +0 -28
  39. package/tests/builder-v2-mysql.type-test.ts +0 -51
  40. package/tests/builder-v2.type-test.ts +0 -336
  41. package/tests/builder.test.ts +0 -63
  42. package/tests/find.test.ts +0 -166
  43. package/tests/insert.test.ts +0 -247
package/DISCLAIMER.md ADDED
@@ -0,0 +1,5 @@
1
+ # DISCLAIMER
2
+
3
+ ### What is still not in package
4
+ - Custom columns (Still not planned)
5
+ - Views (Still not planned)
package/TODO.md CHANGED
@@ -1,64 +1,11 @@
1
- - * Add all essential functions as `update`, `insert`, `delete`, `findMany`, `findFirst`
2
- - Make `route` function (Just duplicate):
3
- ```ts
4
- const [val1, val2] = await userModel.name({
5
- like: "A%"
6
- }).route(
7
- (userModel) => userModel.isVerified(true).findMany(),
8
- (userModel) => userModel.isVerified(false).age({
9
- lte: 18
10
- }).findMany()
11
- // ...args[]
12
- )
13
- ```
14
- - Make built in `paginate` which is pagination function, used as:
15
- ```ts
16
- const userModel = model({
17
- table: userTable,
18
-
19
- // Optional
20
- pagination: {
21
- max: 10
22
- }
23
- })
1
+ # TODO:
24
2
 
25
- const page = 1;
26
-
27
- userModel.name({
28
- like: "A%"
29
- }).userId(userId).paginate(page)
30
- ```
31
- * Make built in `upsert`, as:
3
+ - DONE TYPES => `count()` function to count rows
4
+ - DONE => Fix types. On insert, and add Simplify<> = for more readable queries.
5
+ - DONE TYPES => add `returnFirst()` to return first of `return()`
6
+ - DONE TYPES => add `omit()` as progammic `exclude()`. The main difference is `omit()` is applied after query. `exclude()` is applied on the query.
7
+ - JUST remake a entire core. Manually write code with a few AI changes.
8
+ - DONE TYPES => Add `safe()`:
32
9
  ```ts
33
- userModel.id(123).upsert({
34
- // create obj
35
- }, {
36
- // update obj
37
- }, /* options */)
38
- ```
39
-
40
- * Transactions:
41
- ```ts
42
- userModel.transaction(tx => ...);
43
-
44
- // With other models
45
- userModel.transaction(tx => {
46
- postsModel.db(tx).insert({
47
- userId: 123,
48
- content: ...
49
- })
50
-
51
- // or
52
-
53
- const txPostsModel = postsModel.db(tx);
54
-
55
- txPostsModel.insert({
56
- userId: 123,
57
- content: ...
58
- })
59
-
60
- txPostsModel.userId(123).delete()
61
- });
10
+ const { data: user, error } = userModel.findFirst().safe();
62
11
  ```
63
- - / Soft delete?
64
- - * Dialect based configuration `mysql`, `pgsql` and etc... like `returning()` on pgsql and `$returningId()` on mysql
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apisr/drizzle-model",
3
- "version": "0.0.3",
3
+ "version": "2.0.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "lint": "eslint . --max-warnings 0",
@@ -13,6 +13,7 @@
13
13
  "devDependencies": {
14
14
  "@repo/eslint-config": "*",
15
15
  "@repo/typescript-config": "*",
16
+ "@apisr/logger": "^0.0.3",
16
17
  "@types/bun": "latest",
17
18
  "@types/node": "^22.15.3",
18
19
  "@types/pg": "^8.15.6",
@@ -0,0 +1,81 @@
1
+ import type { ModelDialect } from "../model/dialect.ts";
2
+
3
+ /** Alias for a generic record with string keys. */
4
+ type AnyRecord = Record<string, unknown>;
5
+
6
+ /**
7
+ * Encapsulates dialect-specific logic for different SQL databases.
8
+ *
9
+ * Provides helpers for determining returning-id behaviour and
10
+ * lazily importing the correct Drizzle `alias()` function based on the dialect.
11
+ */
12
+ export class DialectHelper {
13
+ /** The dialect string identifying the target database engine. */
14
+ readonly dialect: ModelDialect;
15
+
16
+ constructor(dialect: ModelDialect) {
17
+ this.dialect = dialect;
18
+ }
19
+
20
+ /**
21
+ * Returns `true` when the dialect only supports `$returningId()`
22
+ * instead of the standard `.returning()` method.
23
+ *
24
+ * Applies to MySQL, SingleStore and CockroachDB.
25
+ */
26
+ isReturningIdOnly(): boolean {
27
+ return (
28
+ this.dialect === "MySQL" ||
29
+ this.dialect === "SingleStore" ||
30
+ this.dialect === "CockroachDB"
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Creates a table alias using the dialect-specific Drizzle module.
36
+ *
37
+ * Dynamically imports the correct `alias` utility so the core
38
+ * does not carry a hard dependency on every dialect.
39
+ *
40
+ * @param table - The Drizzle table object to alias.
41
+ * @param aliasName - The SQL alias name.
42
+ * @returns The aliased table, or the original table if aliasing is unavailable.
43
+ */
44
+ async createTableAlias(
45
+ table: AnyRecord,
46
+ aliasName: string
47
+ ): Promise<AnyRecord> {
48
+ const modulePath = this.getDialectModulePath();
49
+ if (!modulePath) {
50
+ return table;
51
+ }
52
+
53
+ const mod: AnyRecord = await import(modulePath);
54
+ if (typeof mod.alias === "function") {
55
+ return (mod.alias as (t: AnyRecord, name: string) => AnyRecord)(
56
+ table,
57
+ aliasName
58
+ );
59
+ }
60
+
61
+ return table;
62
+ }
63
+
64
+ /**
65
+ * Resolves the Drizzle ORM module path for the current dialect.
66
+ *
67
+ * @returns The import specifier, or `undefined` for unsupported dialects.
68
+ */
69
+ private getDialectModulePath(): string | undefined {
70
+ switch (this.dialect) {
71
+ case "PostgreSQL":
72
+ return "drizzle-orm/pg-core";
73
+ case "MySQL":
74
+ return "drizzle-orm/mysql-core";
75
+ case "SQLite":
76
+ return "drizzle-orm/sqlite-core";
77
+ default:
78
+ return undefined;
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,24 @@
1
+ // Core v2 — public API
2
+ export { DialectHelper } from "./dialect.ts";
3
+ export { QueryError } from "./query/error.ts";
4
+ export {
5
+ JoinExecutor,
6
+ type JoinExecutorConfig,
7
+ type JoinNode,
8
+ } from "./query/joins.ts";
9
+ export {
10
+ ProjectionBuilder,
11
+ type ProjectionResult,
12
+ } from "./query/projection.ts";
13
+ export { WhereCompiler } from "./query/where.ts";
14
+ export {
15
+ type MutateKind,
16
+ MutateResult,
17
+ type MutateState,
18
+ QueryResult,
19
+ type QueryState,
20
+ type SafeResult,
21
+ ThenableResult,
22
+ } from "./result.ts";
23
+ export { ModelRuntime, type ModelRuntimeConfig } from "./runtime.ts";
24
+ export { ResultTransformer } from "./transform.ts";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Represents an error that occurred during query compilation or execution.
3
+ *
4
+ * Extends the native `Error` class so it can be caught independently
5
+ * from generic runtime errors.
6
+ */
7
+ export class QueryError extends Error {
8
+ /** Discriminator for runtime type checks. */
9
+ readonly kind = "QueryError" as const;
10
+
11
+ constructor(message: string, options?: ErrorOptions) {
12
+ super(message, options);
13
+ this.name = "QueryError";
14
+ }
15
+ }