@aurios/mizzle 1.1.2 → 1.1.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/.turbo/turbo-build.log +37 -0
- package/LICENSE +21 -0
- package/README.md +57 -57
- package/dist/chunk-AQVECMXP.js +1 -0
- package/dist/chunk-DU7UPWBW.js +1 -0
- package/dist/chunk-GPYZK4WY.js +1 -0
- package/dist/chunk-NPPZW6VT.js +1 -0
- package/dist/chunk-TOYV2M4M.js +1 -0
- package/dist/chunk-UM3YF5EC.js +1 -0
- package/dist/columns.d.ts +1 -0
- package/dist/columns.js +1 -0
- package/dist/db-zHIHBm1E.d.ts +815 -0
- package/dist/db.d.ts +3 -0
- package/dist/db.js +1 -0
- package/dist/diff.d.ts +18 -0
- package/dist/diff.js +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +1 -0
- package/dist/introspection.d.ts +7 -0
- package/dist/introspection.js +1 -0
- package/dist/operators-BVreW0ky.d.ts +719 -0
- package/dist/snapshot.d.ts +24 -0
- package/dist/snapshot.js +1 -0
- package/dist/table.d.ts +1 -0
- package/dist/table.js +1 -0
- package/dist/transaction-RE7LXTGV.js +1 -0
- package/package.json +82 -66
- package/src/builders/base.ts +53 -56
- package/src/builders/batch-get.ts +63 -58
- package/src/builders/batch-write.ts +81 -78
- package/src/builders/delete.ts +46 -53
- package/src/builders/insert.ts +158 -150
- package/src/builders/query-promise.ts +26 -35
- package/src/builders/relational-builder.ts +214 -191
- package/src/builders/select.ts +250 -237
- package/src/builders/transaction.ts +170 -152
- package/src/builders/update.ts +197 -192
- package/src/columns/binary-set.ts +29 -38
- package/src/columns/binary.ts +25 -35
- package/src/columns/boolean.ts +25 -30
- package/src/columns/date.ts +57 -64
- package/src/columns/index.ts +15 -15
- package/src/columns/json.ts +39 -48
- package/src/columns/list.ts +26 -36
- package/src/columns/map.ts +26 -34
- package/src/columns/number-set.ts +29 -38
- package/src/columns/number.ts +33 -40
- package/src/columns/string-set.ts +38 -47
- package/src/columns/string.ts +37 -49
- package/src/columns/uuid.ts +26 -33
- package/src/core/client.ts +9 -9
- package/src/core/column-builder.ts +194 -220
- package/src/core/column.ts +127 -135
- package/src/core/diff.ts +40 -34
- package/src/core/errors.ts +20 -17
- package/src/core/introspection.ts +62 -58
- package/src/core/operations.ts +17 -23
- package/src/core/parser.ts +82 -89
- package/src/core/relations.ts +164 -154
- package/src/core/retry.ts +52 -52
- package/src/core/snapshot.ts +131 -130
- package/src/core/strategies.ts +222 -218
- package/src/core/table.ts +189 -202
- package/src/core/validation.ts +52 -52
- package/src/db.ts +211 -209
- package/src/expressions/actions.ts +26 -26
- package/src/expressions/builder.ts +62 -54
- package/src/expressions/operators.ts +48 -48
- package/src/expressions/update-builder.ts +78 -76
- package/src/index.ts +1 -1
- package/src/indexes.ts +8 -8
- package/test/batch-resilience.test.ts +138 -0
- package/test/builders/delete.test.ts +100 -0
- package/test/builders/insert.test.ts +216 -0
- package/test/builders/relational-types.test.ts +55 -0
- package/test/builders/relational.integration.test.ts +291 -0
- package/test/builders/relational.test.ts +66 -0
- package/test/builders/select.test.ts +411 -0
- package/test/builders/transaction-errors.test.ts +46 -0
- package/test/builders/transaction-execution.test.ts +99 -0
- package/test/builders/transaction-proxy.test.ts +41 -0
- package/test/builders/update-expression.test.ts +106 -0
- package/test/builders/update.test.ts +179 -0
- package/test/core/diff.test.ts +152 -0
- package/test/core/expressions.test.ts +64 -0
- package/test/core/introspection.test.ts +47 -0
- package/test/core/parser.test.ts +69 -0
- package/test/core/snapshot-gen.test.ts +155 -0
- package/test/core/snapshot.test.ts +52 -0
- package/test/date-column.test.ts +159 -0
- package/test/fluent-writes.integration.test.ts +148 -0
- package/test/integration-retry.test.ts +77 -0
- package/test/integration.test.ts +105 -0
- package/test/item-size-error.test.ts +16 -0
- package/test/item-size-validation.test.ts +82 -0
- package/test/item-size.test.ts +47 -0
- package/test/iterator-pagination.integration.test.ts +132 -0
- package/test/jsdoc-builders.test.ts +55 -0
- package/test/jsdoc-schema.test.ts +107 -0
- package/test/json-column.test.ts +51 -0
- package/test/metadata.test.ts +54 -0
- package/test/mizzle-package.test.ts +20 -0
- package/test/relational-centralized.test.ts +83 -0
- package/test/relational-definition.test.ts +75 -0
- package/test/relational-init.test.ts +30 -0
- package/test/relational-proxy.test.ts +52 -0
- package/test/relations.test.ts +45 -0
- package/test/resilience-config.test.ts +34 -0
- package/test/retry-handler.test.ts +63 -0
- package/test/transaction.integration.test.ts +153 -0
- package/test/unified-select.integration.test.ts +153 -0
- package/test/unified-update.integration.test.ts +139 -0
- package/test/update.integration.test.ts +132 -0
- package/tsconfig.json +12 -8
- package/tsup.config.ts +11 -11
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import { dynamoTable, dynamoEntity } from "@aurios/mizzle/table";
|
|
3
|
+
import { string, uuid, number, stringSet } from "@aurios/mizzle/columns";
|
|
4
|
+
import { prefixKey, staticKey } from "@aurios/mizzle";
|
|
5
|
+
import { DynamoDBClient, CreateTableCommand, DeleteTableCommand, DescribeTableCommand } from "@aws-sdk/client-dynamodb";
|
|
6
|
+
import { mizzle } from "@aurios/mizzle/db";
|
|
7
|
+
import { eq, and } from "@aurios/mizzle/expressions/operators";
|
|
8
|
+
|
|
9
|
+
const client = new DynamoDBClient({
|
|
10
|
+
endpoint: "http://localhost:8000",
|
|
11
|
+
region: "us-east-1",
|
|
12
|
+
credentials: {
|
|
13
|
+
accessKeyId: "local",
|
|
14
|
+
secretAccessKey: "local",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("Unified Update Integration", () => {
|
|
19
|
+
const tableName = "UnifiedUpdateTable";
|
|
20
|
+
const table = dynamoTable(tableName, {
|
|
21
|
+
pk: string("pk"),
|
|
22
|
+
sk: string("sk"),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const user = dynamoEntity(
|
|
26
|
+
table,
|
|
27
|
+
"User",
|
|
28
|
+
{
|
|
29
|
+
id: uuid(),
|
|
30
|
+
name: string(),
|
|
31
|
+
age: number(),
|
|
32
|
+
tags: stringSet(),
|
|
33
|
+
},
|
|
34
|
+
(cols) => ({
|
|
35
|
+
pk: prefixKey("USER#", cols.id),
|
|
36
|
+
sk: staticKey("METADATA"),
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
beforeAll(async () => {
|
|
41
|
+
try {
|
|
42
|
+
await client.send(
|
|
43
|
+
new CreateTableCommand({
|
|
44
|
+
TableName: tableName,
|
|
45
|
+
KeySchema: [
|
|
46
|
+
{ AttributeName: "pk", KeyType: "HASH" },
|
|
47
|
+
{ AttributeName: "sk", KeyType: "RANGE" },
|
|
48
|
+
],
|
|
49
|
+
AttributeDefinitions: [
|
|
50
|
+
{ AttributeName: "pk", AttributeType: "S" },
|
|
51
|
+
{ AttributeName: "sk", AttributeType: "S" },
|
|
52
|
+
],
|
|
53
|
+
ProvisionedThroughput: {
|
|
54
|
+
ReadCapacityUnits: 5,
|
|
55
|
+
WriteCapacityUnits: 5,
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
} catch {
|
|
60
|
+
/* ignore */
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
afterAll(async () => {
|
|
65
|
+
try {
|
|
66
|
+
await client.send(new DeleteTableCommand({ TableName: tableName }));
|
|
67
|
+
} catch {
|
|
68
|
+
/* ignore */
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should support all unified update operations", async () => {
|
|
73
|
+
const db = mizzle(client);
|
|
74
|
+
|
|
75
|
+
// 1. Setup
|
|
76
|
+
const newUser = await db
|
|
77
|
+
.insert(user)
|
|
78
|
+
.values({
|
|
79
|
+
name: "Unified Alice",
|
|
80
|
+
age: 30,
|
|
81
|
+
tags: new Set(["initial"]),
|
|
82
|
+
})
|
|
83
|
+
.returning()
|
|
84
|
+
.execute();
|
|
85
|
+
|
|
86
|
+
// 2. SET multiple fields
|
|
87
|
+
await db
|
|
88
|
+
.update(user)
|
|
89
|
+
.set({ name: "Unified Alice Smith", age: 31 })
|
|
90
|
+
.where(eq(user.id, newUser.id))
|
|
91
|
+
.execute();
|
|
92
|
+
|
|
93
|
+
// 3. ADD to numeric field
|
|
94
|
+
await db.update(user).add({ age: 1 }).where(eq(user.id, newUser.id)).execute();
|
|
95
|
+
|
|
96
|
+
// 4. ADD to set field
|
|
97
|
+
await db
|
|
98
|
+
.update(user)
|
|
99
|
+
.add({ tags: new Set(["added"]) })
|
|
100
|
+
.where(eq(user.id, newUser.id))
|
|
101
|
+
.execute();
|
|
102
|
+
|
|
103
|
+
// 5. REMOVE field
|
|
104
|
+
await db.update(user).remove("name").where(eq(user.id, newUser.id)).execute();
|
|
105
|
+
|
|
106
|
+
// 6. DELETE from set
|
|
107
|
+
await db
|
|
108
|
+
.update(user)
|
|
109
|
+
.delete({ tags: new Set(["initial"]) })
|
|
110
|
+
.where(eq(user.id, newUser.id))
|
|
111
|
+
.execute();
|
|
112
|
+
|
|
113
|
+
// 7. Conditional update (should only update if age is 32)
|
|
114
|
+
// Current implementation might ignore the age condition if it's not part of the key
|
|
115
|
+
await db
|
|
116
|
+
.update(user)
|
|
117
|
+
.set({ name: "Conditional Alice" })
|
|
118
|
+
.where(and(eq(user.id, newUser.id), eq(user.age, 32)))
|
|
119
|
+
.execute();
|
|
120
|
+
|
|
121
|
+
// 8. Conditional update that should fail (age is not 40)
|
|
122
|
+
try {
|
|
123
|
+
await db
|
|
124
|
+
.update(user)
|
|
125
|
+
.set({ name: "Should Not Happen" })
|
|
126
|
+
.where(and(eq(user.id, newUser.id), eq(user.age, 40)))
|
|
127
|
+
.execute();
|
|
128
|
+
} catch {
|
|
129
|
+
// Expected to fail if ConditionExpression is implemented
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Verification
|
|
133
|
+
const final = await db.select().from(user).where(eq(user.id, newUser.id));
|
|
134
|
+
expect(final[0]!.name).toBe("Conditional Alice");
|
|
135
|
+
expect(final[0]!.age).toBe(32);
|
|
136
|
+
expect(final[0]!.tags).toContain("added");
|
|
137
|
+
expect(final[0]!.tags).not.toContain("initial");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import { dynamoTable, dynamoEntity } from "@aurios/mizzle/table";
|
|
3
|
+
import { string, uuid, number, list } from "@aurios/mizzle/columns";
|
|
4
|
+
import { prefixKey, staticKey } from "@aurios/mizzle";
|
|
5
|
+
import { DynamoDBClient, CreateTableCommand, DeleteTableCommand, DescribeTableCommand } from "@aws-sdk/client-dynamodb";
|
|
6
|
+
import { mizzle } from "@aurios/mizzle/db";
|
|
7
|
+
import { eq } from "@aurios/mizzle/expressions/operators";
|
|
8
|
+
|
|
9
|
+
const client = new DynamoDBClient({
|
|
10
|
+
endpoint: "http://localhost:8000",
|
|
11
|
+
region: "us-east-1",
|
|
12
|
+
credentials: {
|
|
13
|
+
accessKeyId: "local",
|
|
14
|
+
secretAccessKey: "local",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("Update Integration", () => {
|
|
19
|
+
const tableName = "UpdateIntegrationTable";
|
|
20
|
+
const table = dynamoTable(tableName, {
|
|
21
|
+
pk: string("pk"),
|
|
22
|
+
sk: string("sk"),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const user = dynamoEntity(
|
|
26
|
+
table,
|
|
27
|
+
"User",
|
|
28
|
+
{
|
|
29
|
+
id: uuid(),
|
|
30
|
+
name: string(),
|
|
31
|
+
age: number(),
|
|
32
|
+
roles: list(),
|
|
33
|
+
},
|
|
34
|
+
(cols) => ({
|
|
35
|
+
pk: prefixKey("USER#", cols.id),
|
|
36
|
+
sk: staticKey("METADATA"),
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
beforeAll(async () => {
|
|
41
|
+
try {
|
|
42
|
+
await client.send(
|
|
43
|
+
new CreateTableCommand({
|
|
44
|
+
TableName: tableName,
|
|
45
|
+
KeySchema: [
|
|
46
|
+
{ AttributeName: "pk", KeyType: "HASH" },
|
|
47
|
+
{ AttributeName: "sk", KeyType: "RANGE" },
|
|
48
|
+
],
|
|
49
|
+
AttributeDefinitions: [
|
|
50
|
+
{ AttributeName: "pk", AttributeType: "S" },
|
|
51
|
+
{ AttributeName: "sk", AttributeType: "S" },
|
|
52
|
+
],
|
|
53
|
+
ProvisionedThroughput: {
|
|
54
|
+
ReadCapacityUnits: 5,
|
|
55
|
+
WriteCapacityUnits: 5,
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
} catch {
|
|
60
|
+
/* ignore */
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
afterAll(async () => {
|
|
65
|
+
try {
|
|
66
|
+
await client.send(new DeleteTableCommand({ TableName: tableName }));
|
|
67
|
+
} catch {
|
|
68
|
+
/* ignore */
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should perform a full update lifecycle", async () => {
|
|
73
|
+
const db = mizzle(client);
|
|
74
|
+
|
|
75
|
+
// 1. Setup - Insert a user
|
|
76
|
+
const newUser = await db
|
|
77
|
+
.insert(user)
|
|
78
|
+
.values({
|
|
79
|
+
name: "Alice",
|
|
80
|
+
age: 25,
|
|
81
|
+
roles: ["user"],
|
|
82
|
+
})
|
|
83
|
+
.returning()
|
|
84
|
+
.execute();
|
|
85
|
+
|
|
86
|
+
expect(newUser.id).toBeDefined();
|
|
87
|
+
|
|
88
|
+
// 2. SET
|
|
89
|
+
const setRes = await db
|
|
90
|
+
.update(user)
|
|
91
|
+
.set({ name: "Alice Smith" })
|
|
92
|
+
.where(eq(user.id, newUser.id))
|
|
93
|
+
.returning("ALL_NEW")
|
|
94
|
+
.execute();
|
|
95
|
+
|
|
96
|
+
const res1 = setRes as Record<string, unknown>;
|
|
97
|
+
expect(res1.name).toBe("Alice Smith");
|
|
98
|
+
expect(res1.age).toBe(25);
|
|
99
|
+
|
|
100
|
+
// 3. ADD
|
|
101
|
+
const addRes = await db
|
|
102
|
+
.update(user)
|
|
103
|
+
.add({ age: 5 })
|
|
104
|
+
.where(eq(user.id, newUser.id))
|
|
105
|
+
.returning("UPDATED_NEW")
|
|
106
|
+
.execute();
|
|
107
|
+
|
|
108
|
+
const res2 = addRes as Record<string, unknown>;
|
|
109
|
+
expect(res2.age).toBe(30);
|
|
110
|
+
|
|
111
|
+
// 4. REMOVE
|
|
112
|
+
const removeRes = await db
|
|
113
|
+
.update(user)
|
|
114
|
+
.remove("roles")
|
|
115
|
+
.where(eq(user.id, newUser.id))
|
|
116
|
+
.returning("ALL_NEW")
|
|
117
|
+
.execute();
|
|
118
|
+
|
|
119
|
+
const res3 = removeRes as Record<string, unknown>;
|
|
120
|
+
expect(res3.roles).toBeUndefined();
|
|
121
|
+
expect(res3.name).toBe("Alice Smith");
|
|
122
|
+
|
|
123
|
+
// 5. Verification - Select
|
|
124
|
+
const final = await db.select().from(user).where(eq(user.id, newUser.id));
|
|
125
|
+
expect(final[0]!).toMatchObject({
|
|
126
|
+
id: newUser.id,
|
|
127
|
+
name: "Alice Smith",
|
|
128
|
+
age: 30,
|
|
129
|
+
});
|
|
130
|
+
expect(final[0]!.roles).toBeUndefined();
|
|
131
|
+
});
|
|
132
|
+
});
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
"extends": "@repo/typescript-config/base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"paths": {
|
|
6
|
+
"@repo/shared": [
|
|
7
|
+
"./../shared/src/index.ts"
|
|
8
|
+
]
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"src"
|
|
13
|
+
]
|
|
10
14
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
entry: {
|
|
5
|
-
index:
|
|
6
|
-
columns:
|
|
7
|
-
table:
|
|
8
|
-
snapshot:
|
|
9
|
-
diff:
|
|
10
|
-
introspection:
|
|
11
|
-
db:
|
|
5
|
+
index: "src/index.ts",
|
|
6
|
+
columns: "src/columns/index.ts",
|
|
7
|
+
table: "src/core/table.ts",
|
|
8
|
+
snapshot: "src/core/snapshot.ts",
|
|
9
|
+
diff: "src/core/diff.ts",
|
|
10
|
+
introspection: "src/core/introspection.ts",
|
|
11
|
+
db: "src/db.ts",
|
|
12
12
|
},
|
|
13
|
-
format:
|
|
13
|
+
format: "esm",
|
|
14
14
|
dts: true,
|
|
15
15
|
clean: true,
|
|
16
|
-
noExternal: [
|
|
17
|
-
external: [/^@aws-sdk\//,
|
|
16
|
+
noExternal: ["@repo/shared"],
|
|
17
|
+
external: [/^@aws-sdk\//, "uuid"],
|
|
18
18
|
minify: true,
|
|
19
19
|
splitting: true,
|
|
20
20
|
});
|