@rdlabo/workers-mysql 0.1.0-beta.pr48.sha371f5792ce8a
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/LICENSE +21 -0
- package/README.md +102 -0
- package/bin/db-baseline.mjs +4 -0
- package/dist/baseline-cli.d.ts +2 -0
- package/dist/baseline-cli.js +47 -0
- package/dist/columns.d.ts +38 -0
- package/dist/columns.js +38 -0
- package/dist/connection.d.ts +76 -0
- package/dist/connection.js +67 -0
- package/dist/database.d.ts +249 -0
- package/dist/database.js +196 -0
- package/dist/drizzle.d.ts +6 -0
- package/dist/drizzle.js +5 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +10 -0
- package/dist/jst.d.ts +43 -0
- package/dist/jst.js +59 -0
- package/dist/migrate.d.ts +51 -0
- package/dist/migrate.js +109 -0
- package/dist/migrations.d.ts +5 -0
- package/dist/migrations.js +3 -0
- package/dist/orm-config.d.ts +134 -0
- package/dist/orm-config.js +127 -0
- package/dist/retry.d.ts +28 -0
- package/dist/retry.js +56 -0
- package/dist/testing/db.d.ts +106 -0
- package/dist/testing/db.js +95 -0
- package/dist/testing/fakes.d.ts +13 -0
- package/dist/testing/fakes.js +25 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.js +2 -0
- package/dist/write-result.d.ts +39 -0
- package/dist/write-result.js +34 -0
- package/docs/api.md +72 -0
- package/docs/drizzle.md +41 -0
- package/docs/migration.md +28 -0
- package/docs/runtime.md +72 -0
- package/docs/tooling.md +51 -0
- package/package.json +92 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migration
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Migration
|
|
6
|
+
|
|
7
|
+
The database utilities are standalone from kit `0.12.0`. Install `@rdlabo/workers-mysql` directly;
|
|
8
|
+
keep `@rdlabo/workers-hono-kit` only if using its Hono integration. `mysql2` is included, while
|
|
9
|
+
`drizzle-orm` remains an optional peer for `/drizzle` and `/testing`. TypeScript consumers need
|
|
10
|
+
the Node declarations described in the [README](../README.md).
|
|
11
|
+
|
|
12
|
+
| Previous import | New import |
|
|
13
|
+
| -------------------------------------- | ---------------------------------- |
|
|
14
|
+
| Kit root `createContainerRuntime` | `@rdlabo/workers-hono-kit/mysql` |
|
|
15
|
+
| Kit root `retryWhenDeadlock` | `@rdlabo/workers-mysql` |
|
|
16
|
+
| Kit `/db` runtime and JST wire helpers | `@rdlabo/workers-mysql` |
|
|
17
|
+
| Kit `/db` column/configuration helpers | `@rdlabo/workers-mysql/drizzle` |
|
|
18
|
+
| Kit `/db` baseline helpers | `@rdlabo/workers-mysql/migrations` |
|
|
19
|
+
| Kit `/testing` database helpers | `@rdlabo/workers-mysql/testing` |
|
|
20
|
+
|
|
21
|
+
The old `/db` and DB-related `/testing` paths remain available as maintained compatibility
|
|
22
|
+
re-exports with `@deprecated` notices; there is no planned removal. Do not import the legacy
|
|
23
|
+
aggregate `/db` in new Worker code: use the dedicated runtime entry points to keep Node-only
|
|
24
|
+
migration code out of the Worker bundle. Rename `honoDrizzleConfig` to `workersDrizzleConfig` when
|
|
25
|
+
updating configuration.
|
|
26
|
+
|
|
27
|
+
No Hono dependency is required by this database package. The fixed-JST storage contract also
|
|
28
|
+
remains separate from configurable business timezones; see [Drizzle and dates](./drizzle.md).
|
package/docs/runtime.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Runtime
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Runtime
|
|
6
|
+
|
|
7
|
+
Enable `nodejs_compat` in your Worker and install the dependencies described in the
|
|
8
|
+
[README](../README.md). `mysql2` is included; the package does not depend on Hono.
|
|
9
|
+
The application supplies its Hyperdrive bindings, schema, and ORM factory.
|
|
10
|
+
|
|
11
|
+
## Invocation lifetime
|
|
12
|
+
|
|
13
|
+
Create `createHyperdriveDatabase` inside each invocation, not in module-global state. Connections
|
|
14
|
+
open lazily and are reused by that database instance. The runtime cleans up invocation connections;
|
|
15
|
+
its compatibility `dispose()` method is a no-op.
|
|
16
|
+
|
|
17
|
+
This complete Worker example uses one Hyperdrive binding for both roles. Applications with a
|
|
18
|
+
replica can supply a separate binding for `replicaHyperdrive`:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { createHyperdriveDatabase, type HyperdriveLike } from '@rdlabo/workers-mysql';
|
|
22
|
+
import { DRIZZLE_ORM_OPTIONS } from '@rdlabo/workers-mysql/drizzle';
|
|
23
|
+
import { drizzle } from 'drizzle-orm/mysql2';
|
|
24
|
+
|
|
25
|
+
interface Env {
|
|
26
|
+
DB: HyperdriveLike;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
async fetch(_request: Request, env: Env): Promise<Response> {
|
|
31
|
+
const db = createHyperdriveDatabase({
|
|
32
|
+
primaryHyperdrive: env.DB,
|
|
33
|
+
replicaHyperdrive: env.DB,
|
|
34
|
+
createOrm: (connection) => drizzle(connection, DRIZZLE_ORM_OPTIONS),
|
|
35
|
+
});
|
|
36
|
+
const rows = await db.query<Array<{ value: number }>>('SELECT ? AS value', [1]);
|
|
37
|
+
return Response.json(rows);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Read and write paths
|
|
43
|
+
|
|
44
|
+
| Operation | Destination | Result type parameter |
|
|
45
|
+
| --------------------------- | --------------------------- | --------------------------------- |
|
|
46
|
+
| `read<Row>(sql, params?)` | Replica | One row; returns `Row[]` |
|
|
47
|
+
| `query<Rows>(sql, params?)` | Primary SELECT | Whole result, for example `Row[]` |
|
|
48
|
+
| `readTransaction(fn)` | Primary consistent snapshot | Callback result |
|
|
49
|
+
| `write(fn)` | Primary ORM | Awaited callback result |
|
|
50
|
+
| `transaction(fn)` | Primary transaction | Awaited callback result |
|
|
51
|
+
|
|
52
|
+
Use `query` for reads that cannot tolerate replica lag. Query caching, if enabled on a Hyperdrive
|
|
53
|
+
binding, is a separate configuration concern. Use parameter placeholders, not interpolated SQL.
|
|
54
|
+
|
|
55
|
+
`readTransaction` passes `{ orm, query }` on one read-only snapshot. Its calls are serialized on a
|
|
56
|
+
dedicated connection; do not call it recursively inside its callback.
|
|
57
|
+
|
|
58
|
+
## Retry boundaries
|
|
59
|
+
|
|
60
|
+
Database operations retry deadlocks. Return/await the write builder or promise from callbacks.
|
|
61
|
+
The whole transaction callback can run again: keep email, payments, and other external side effects
|
|
62
|
+
outside it. Do not add another `retryWhenDeadlock` wrapper around an already-retrying operation.
|
|
63
|
+
|
|
64
|
+
Hyperdrive SELECTs and read-only transactions can additionally repeat once on a fresh connection
|
|
65
|
+
after a fatal connection error. Writes and write transactions are not replayed for connection loss:
|
|
66
|
+
the outcome may be unknown. Handle application idempotency before retrying such a request.
|
|
67
|
+
|
|
68
|
+
`createMysqlDatabase({ orm, replica })` and `databaseFrom(orm, replica)` wrap existing handles;
|
|
69
|
+
their caller owns connection cleanup. They expose `Database`, not the extra Hyperdrive primary-read
|
|
70
|
+
methods. For Hono containers, use `@rdlabo/workers-hono-kit/mysql` (kit `0.12.0` or later).
|
|
71
|
+
|
|
72
|
+
See [Drizzle and dates](./drizzle.md) for connection defaults and [API](./api.md) for exports.
|
package/docs/tooling.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migrations and testing
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Migrations and testing
|
|
6
|
+
|
|
7
|
+
These helpers are for Node.js tooling, not Worker request bundles. Import them from their dedicated
|
|
8
|
+
entry points. The consumer owns migrations, credentials, test fixtures, and database provisioning.
|
|
9
|
+
|
|
10
|
+
## Drizzle configuration
|
|
11
|
+
|
|
12
|
+
`workersDrizzleConfig` from `/drizzle` builds a MySQL Drizzle Kit configuration with snake-case
|
|
13
|
+
casing. Supply your `database`, `schema`, and `out` paths explicitly.
|
|
14
|
+
`workersDrizzleConfig` automatically reads `DB_SECRET`: when set, its connection details override
|
|
15
|
+
even explicitly supplied `database`, host, port, user, and password options, as well as `DB_*`
|
|
16
|
+
environment variables. Before running migrations, verify the secret's target; specifying a local
|
|
17
|
+
`database` option alone does not restrict the connection to that database.
|
|
18
|
+
`resolveDbSecret()` reads `DB_SECRET` JSON (`host`, `username`, `password`, `dbname`, optional
|
|
19
|
+
`port`). It returns `undefined` if unset and throws for invalid input rather than silently falling
|
|
20
|
+
back. Never commit or log database secrets.
|
|
21
|
+
|
|
22
|
+
## Existing-database baseline
|
|
23
|
+
|
|
24
|
+
`baselineMigrations({ db, migrationsFolder })` from `/migrations` records the first migration as
|
|
25
|
+
applied **without executing its schema SQL**. It does not verify that the existing schema matches
|
|
26
|
+
that SQL. Compare them, back up the target, and confirm credentials before invoking it.
|
|
27
|
+
|
|
28
|
+
For a fresh database, run the normal Drizzle migrator, not baseline. Baseline refuses an empty
|
|
29
|
+
database or unexpected migration history and is a no-op if the baseline marker already exists.
|
|
30
|
+
|
|
31
|
+
The installed CLI is `workers-mysql-db-baseline --migrations ./drizzle`. It uses `DB_SECRET` or
|
|
32
|
+
`DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, and `DB_NAME`. This command writes migration
|
|
33
|
+
metadata; it is not a dry run. `/baseline-cli` exports `runBaselineCli` for tooling integrations.
|
|
34
|
+
|
|
35
|
+
## Local tests
|
|
36
|
+
|
|
37
|
+
`createTestDb({ dbName, migrationsFolder, connection })` from `/testing` returns fixture helpers.
|
|
38
|
+
Use an isolated disposable database and explicit local connection settings:
|
|
39
|
+
|
|
40
|
+
- `resetSchema()` **drops and recreates the database**, then applies migrations.
|
|
41
|
+
- `truncateAll(pool)` deletes table contents, excluding migration bookkeeping.
|
|
42
|
+
- `seed(pool, table, row)` inserts a fixture.
|
|
43
|
+
- `createTestPool()` creates a pool; close it with `pool.end()` after testing.
|
|
44
|
+
- `mysqlReachable()` probes connectivity, not schema correctness.
|
|
45
|
+
|
|
46
|
+
Never point these helpers at shared or production data. Distinct test runs should use distinct
|
|
47
|
+
database names. `createPoolDatabase({ pool, orm })` uses one pool for reads/writes and closes it
|
|
48
|
+
on `dispose()`. `createNoopDatabase()` returns empty reads and throws on unexpected writes or
|
|
49
|
+
transactions; it is a stub, not an acceptance test against MySQL.
|
|
50
|
+
|
|
51
|
+
See [API](./api.md) for the available types.
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rdlabo/workers-mysql",
|
|
3
|
+
"version": "0.1.0-beta.pr48.sha371f5792ce8a",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public",
|
|
7
|
+
"registry": "https://registry.npmjs.org/"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"description": "MySQL and Hyperdrive utilities for Cloudflare Workers",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/rdlabo-dev/workers-hono-kit.git",
|
|
15
|
+
"directory": "packages/mysql"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/rdlabo-dev/workers-hono-kit/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/rdlabo-dev/workers-hono-kit/tree/main/packages/mysql#readme",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"bin",
|
|
24
|
+
"docs"
|
|
25
|
+
],
|
|
26
|
+
"bin": {
|
|
27
|
+
"workers-mysql-db-baseline": "./bin/db-baseline.mjs"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./drizzle": {
|
|
36
|
+
"types": "./dist/drizzle.d.ts",
|
|
37
|
+
"import": "./dist/drizzle.js",
|
|
38
|
+
"default": "./dist/drizzle.js"
|
|
39
|
+
},
|
|
40
|
+
"./migrations": {
|
|
41
|
+
"types": "./dist/migrations.d.ts",
|
|
42
|
+
"import": "./dist/migrations.js",
|
|
43
|
+
"default": "./dist/migrations.js"
|
|
44
|
+
},
|
|
45
|
+
"./baseline-cli": {
|
|
46
|
+
"types": "./dist/baseline-cli.d.ts",
|
|
47
|
+
"import": "./dist/baseline-cli.js",
|
|
48
|
+
"default": "./dist/baseline-cli.js"
|
|
49
|
+
},
|
|
50
|
+
"./testing": {
|
|
51
|
+
"types": "./dist/testing/index.d.ts",
|
|
52
|
+
"import": "./dist/testing/index.js",
|
|
53
|
+
"default": "./dist/testing/index.js"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsc -p tsconfig.build.json",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:package": "node scripts/package-smoke.mjs",
|
|
61
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
62
|
+
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
63
|
+
"format": "prettier --write .",
|
|
64
|
+
"format:check": "prettier --check .",
|
|
65
|
+
"prepack": "npm run build"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=20.0.0"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"mysql2": "^3.24.3"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"@types/node": ">=20.19.43",
|
|
75
|
+
"drizzle-orm": "^0.45.2"
|
|
76
|
+
},
|
|
77
|
+
"peerDependenciesMeta": {
|
|
78
|
+
"drizzle-orm": {
|
|
79
|
+
"optional": true
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"devDependencies": {
|
|
83
|
+
"@hono/eslint-config": "^2.1.0",
|
|
84
|
+
"@rdlabo/workers-timezone": "0.1.0-beta.pr48.sha371f5792ce8a",
|
|
85
|
+
"drizzle-orm": "^0.45.2",
|
|
86
|
+
"eslint": "^9.39.4",
|
|
87
|
+
"prettier": "^3.8.4",
|
|
88
|
+
"typescript": "~5.6.2",
|
|
89
|
+
"typescript-eslint": "^8.61.1",
|
|
90
|
+
"vitest": "^2.1.0"
|
|
91
|
+
}
|
|
92
|
+
}
|