feat: one install and one import per database; server dialects open their pool from a URL; nodeListener answers a throwing context; 0.5.0
This commit is contained in:
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.5.0] - 2026-11-03
|
||||
|
||||
### Added
|
||||
- Every database package exports the whole core, so one install and one import are enough: `import { createREST, nodeListener, postgres } from '@crudy/restloom-postgres'`.
|
||||
- `postgres`, `mysql` and `mssql` take a connection URL or the driver's pool options and open the pool themselves; a pool you already have still works.
|
||||
|
||||
### Changed
|
||||
- `pg`, `mysql2` and `mssql` are dependencies of their packages again, installed with them. `better-sqlite3` stays an optional peer of the SQLite package, which also runs on sql.js in a browser.
|
||||
|
||||
### Fixed
|
||||
- A `nodeListener` context that throws answers the request, with the `RestError` it threw or `500 internal`, instead of stopping the process.
|
||||
|
||||
## [0.4.0] - 2026-11-03
|
||||
|
||||
### Added
|
||||
|
||||
@@ -37,19 +37,19 @@ Your backend stays in charge:
|
||||
| `@crudy/restloom-express` | Express handler |
|
||||
|
||||
```sh
|
||||
npm install @crudy/restloom @crudy/restloom-postgres pg
|
||||
npm install @crudy/restloom-postgres
|
||||
```
|
||||
|
||||
A database package brings the core and its driver, and exports the whole core.
|
||||
|
||||
## Use
|
||||
|
||||
```ts
|
||||
import http from 'node:http';
|
||||
import pg from 'pg';
|
||||
import { createREST, nodeListener } from '@crudy/restloom';
|
||||
import { postgres } from '@crudy/restloom-postgres';
|
||||
import { createREST, nodeListener, postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
const rest = createREST({
|
||||
db: postgres(new pg.Pool()),
|
||||
db: postgres(process.env.DATABASE_URL),
|
||||
expose: { schemas: ['app'] },
|
||||
resources: { todos: { write: true } },
|
||||
});
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import * as pg from '../packages/postgres/dist/index.js';
|
||||
import * as my from '../packages/mysql/dist/index.js';
|
||||
import * as ms from '../packages/mssql/dist/index.js';
|
||||
import * as lite from '../packages/sqlite/dist/index.js';
|
||||
|
||||
// One install and one import: each database package brings the core with it,
|
||||
// and the server databases open their own connection from a URL.
|
||||
test('every database package exports the core', () => {
|
||||
for (const mod of [pg, my, ms, lite]) {
|
||||
assert.equal(typeof mod.createREST, 'function');
|
||||
assert.equal(typeof mod.nodeListener, 'function');
|
||||
assert.equal(typeof mod.RestError, 'function');
|
||||
}
|
||||
});
|
||||
|
||||
test('postgres and mysql open a pool from a URL without connecting yet', async () => {
|
||||
assert.equal(pg.postgres('postgres://user:secret@127.0.0.1:1/app').name, 'postgres');
|
||||
assert.equal(my.mysql('mysql://user:secret@127.0.0.1:1/app').name, 'mysql');
|
||||
});
|
||||
|
||||
test('postgres serves from a URL', { skip: !process.env.RESTLOOM_PG_URL && 'RESTLOOM_PG_URL is not set' }, async () => {
|
||||
const db = pg.postgres(process.env.RESTLOOM_PG_URL);
|
||||
const rows = await db.transaction((tx) => tx.query('SELECT 1 AS one', []), { timeoutMs: 5000, readOnly: true });
|
||||
assert.deepEqual(rows, [{ one: 1 }]);
|
||||
});
|
||||
@@ -9,9 +9,9 @@ import { sqlite } from '../packages/sqlite/dist/index.js';
|
||||
// The table in docs/dialects.md is what readers compare databases by, on the
|
||||
// site too. It must say what each dialect's capabilities say.
|
||||
const DIALECTS = {
|
||||
'@crudy/restloom-postgres': postgres({}),
|
||||
'@crudy/restloom-mysql': mysql({}),
|
||||
'@crudy/restloom-mssql': mssql({}),
|
||||
'@crudy/restloom-postgres': postgres({ connect() {} }),
|
||||
'@crudy/restloom-mysql': mysql({ getConnection() {} }),
|
||||
'@crudy/restloom-mssql': mssql({ request() {} }),
|
||||
'@crudy/restloom-sqlite': sqlite({ pragma() {} }),
|
||||
};
|
||||
|
||||
|
||||
+4
-6
@@ -3,12 +3,10 @@
|
||||
The core answers a plain request object, so it fits any framework:
|
||||
|
||||
```ts
|
||||
import pg from 'pg';
|
||||
import { createREST } from '@crudy/restloom';
|
||||
import { postgres } from '@crudy/restloom-postgres';
|
||||
import { createREST, postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
const rest = createREST({
|
||||
db: postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL })),
|
||||
db: postgres(process.env.DATABASE_URL),
|
||||
expose: { schemas: ['app'] },
|
||||
});
|
||||
|
||||
@@ -22,11 +20,11 @@ The examples below use this `rest`.
|
||||
|
||||
## Node, without a framework
|
||||
|
||||
`nodeListener` from the core serves `node:http` with nothing else installed. It mounts the API under `prefix` and answers `404 not_found` outside it, reads JSON bodies up to 1 MiB (`maxBodyBytes`), and builds each request's context with `context`:
|
||||
`nodeListener` from the core serves `node:http` with nothing else installed. It mounts the API under `prefix` and answers `404 not_found` outside it, reads JSON bodies up to 1 MiB (`maxBodyBytes`), and builds each request's context with `context`. A `context` that throws a `RestError` refuses the request with it; any other error answers `500 internal`:
|
||||
|
||||
```ts
|
||||
import http from 'node:http';
|
||||
import { nodeListener } from '@crudy/restloom';
|
||||
import { nodeListener } from '@crudy/restloom-postgres';
|
||||
|
||||
const api = nodeListener(rest, { prefix: '/api', context: (req) => userFrom(req) });
|
||||
http.createServer(api).listen(3000);
|
||||
|
||||
+10
-8
@@ -9,15 +9,16 @@ A dialect is the package that knows one database: how to read its catalog, how t
|
||||
| `@crudy/restloom-mssql` | SQL Server 2022+ | `JSON_OBJECT`, `STRING_AGG` | `OUTPUT` | no | security policies | scalar and table functions |
|
||||
| `@crudy/restloom-sqlite` | SQLite 3.44+ (better-sqlite3) | `json_object`, `json_group_array` | `RETURNING` | no | no | none |
|
||||
|
||||
The PostgreSQL, MySQL and SQL Server packages bring their driver and open their own connection from a URL. To tune it, pass the driver's pool options instead, or a pool you already have: a `pg` Pool, a `mysql2/promise` Pool or a connected `mssql` ConnectionPool. The SQLite package takes a database object, so it runs on `better-sqlite3` in Node or on sql.js in a browser; install the one you use.
|
||||
|
||||
Every dialect passes the same conformance suite, so a request answers the same rows on each. Regular expressions (`match`, `imatch`) need Postgres or MySQL, and array filters (`ov`, `cs`, `cd`) Postgres array columns; elsewhere they answer `unsupported`. Where else the dialects differ, the sections below say how.
|
||||
|
||||
## Postgres
|
||||
|
||||
```ts
|
||||
import pg from 'pg';
|
||||
import { postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
const db = postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL }));
|
||||
const db = postgres(process.env.DATABASE_URL);
|
||||
```
|
||||
|
||||
- **Transactions:** every request is one transaction, `READ ONLY` for reads, with `SET LOCAL statement_timeout` from `limits.timeoutMs`.
|
||||
@@ -28,10 +29,9 @@ const db = postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL }))
|
||||
## MySQL
|
||||
|
||||
```ts
|
||||
import { createPool } from 'mysql2/promise';
|
||||
import { mysql } from '@crudy/restloom-mysql';
|
||||
|
||||
const db = mysql(createPool({ uri: process.env.DATABASE_URL }));
|
||||
const db = mysql(process.env.DATABASE_URL);
|
||||
```
|
||||
|
||||
- **Schemas:** MySQL's schemas are its databases: `expose: { schemas: ['shop'] }`.
|
||||
@@ -44,10 +44,9 @@ const db = mysql(createPool({ uri: process.env.DATABASE_URL }));
|
||||
## SQL Server
|
||||
|
||||
```ts
|
||||
import sql from 'mssql';
|
||||
import { mssql } from '@crudy/restloom-mssql';
|
||||
|
||||
const db = mssql(await new sql.ConnectionPool(process.env.DATABASE_URL).connect());
|
||||
const db = mssql(process.env.DATABASE_URL);
|
||||
```
|
||||
|
||||
- **Version:** SQL Server 2022 or later, for `JSON_OBJECT`.
|
||||
@@ -59,6 +58,10 @@ const db = mssql(await new sql.ConnectionPool(process.env.DATABASE_URL).connect(
|
||||
|
||||
## SQLite
|
||||
|
||||
```sh
|
||||
npm install @crudy/restloom-sqlite better-sqlite3
|
||||
```
|
||||
|
||||
```ts
|
||||
import Database from 'better-sqlite3';
|
||||
import { sqlite } from '@crudy/restloom-sqlite';
|
||||
@@ -77,7 +80,6 @@ const db = sqlite(new Database('app.db'));
|
||||
Every piece of SQL comes from one overridable method of the dialect's renderer. To change one, subclass it and pass it in:
|
||||
|
||||
```ts
|
||||
import pg from 'pg';
|
||||
import { PostgresRenderer, postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
class Renderer extends PostgresRenderer {
|
||||
@@ -86,7 +88,7 @@ class Renderer extends PostgresRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
const db = postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL }), { renderer: new Renderer() });
|
||||
const db = postgres(process.env.DATABASE_URL, { renderer: new Renderer() });
|
||||
```
|
||||
|
||||
The pieces are listed in [writing a dialect](./writing-a-dialect.md).
|
||||
|
||||
+12
-12
@@ -2,29 +2,29 @@
|
||||
|
||||
## Install
|
||||
|
||||
Install the core, the package for your database, and its driver:
|
||||
Install the package for your database. It brings the core and the database driver with it, except for SQLite, which also needs `better-sqlite3`:
|
||||
|
||||
```sh
|
||||
npm install @crudy/restloom @crudy/restloom-postgres pg
|
||||
npm install @crudy/restloom-postgres
|
||||
```
|
||||
|
||||
| Database | Package | Driver |
|
||||
|---|---|---|
|
||||
| PostgreSQL 13+ | `@crudy/restloom-postgres` | `pg` |
|
||||
| MySQL 8.0+ | `@crudy/restloom-mysql` | `mysql2` |
|
||||
| SQL Server 2022+ | `@crudy/restloom-mssql` | `mssql` |
|
||||
| SQLite 3.44+ | `@crudy/restloom-sqlite` | `better-sqlite3` |
|
||||
| Database | Package |
|
||||
|---|---|
|
||||
| PostgreSQL 13+ | `@crudy/restloom-postgres` |
|
||||
| MySQL 8.0+ | `@crudy/restloom-mysql` |
|
||||
| SQL Server 2022+ | `@crudy/restloom-mssql` |
|
||||
| SQLite 3.44+ | `@crudy/restloom-sqlite` |
|
||||
|
||||
Each of them exports the whole core, so everything is imported from that one package. The examples in these pages use `@crudy/restloom-postgres`; with another database, import from its package instead.
|
||||
|
||||
## Serve a schema
|
||||
|
||||
```ts
|
||||
import http from 'node:http';
|
||||
import pg from 'pg';
|
||||
import { createREST, nodeListener } from '@crudy/restloom';
|
||||
import { postgres } from '@crudy/restloom-postgres';
|
||||
import { createREST, nodeListener, postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
const rest = createREST({
|
||||
db: postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL })),
|
||||
db: postgres(process.env.DATABASE_URL),
|
||||
expose: { schemas: ['app'] },
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -52,7 +52,7 @@ resources: {
|
||||
`sensitive` replaces the whole pattern, for every resource. Start from `DEFAULT_SENSITIVE` to add words rather than lose the defaults:
|
||||
|
||||
```ts
|
||||
import { createREST, DEFAULT_SENSITIVE } from '@crudy/restloom';
|
||||
import { createREST, DEFAULT_SENSITIVE } from '@crudy/restloom-postgres';
|
||||
|
||||
createREST({
|
||||
db, // from a database package, see Dialects
|
||||
@@ -64,7 +64,7 @@ createREST({
|
||||
## Hooks
|
||||
|
||||
```ts
|
||||
import { createREST, RestError } from '@crudy/restloom';
|
||||
import { createREST, RestError } from '@crudy/restloom-postgres';
|
||||
|
||||
createREST({
|
||||
db, // from a database package, see Dialects
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ procedures: {
|
||||
For an API that writes everywhere, set `write` once, beside `expose`:
|
||||
|
||||
```ts
|
||||
import { createREST } from '@crudy/restloom';
|
||||
import { createREST } from '@crudy/restloom-postgres';
|
||||
|
||||
createREST({
|
||||
db, // from a database package, see Dialects
|
||||
|
||||
Generated
+16
-136
@@ -22,7 +22,6 @@
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure-rest/core-client/-/core-client-2.9.0.tgz",
|
||||
"integrity": "sha512-6933vNLqh06RR7rumnrq3UZIeBtRLeBHDPMrieDPIljiCaMMwt0nRw++nd3TOxiohtasNtm29rC+b/9ZVKCOqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -40,7 +39,6 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.2.0.tgz",
|
||||
"integrity": "sha512-fNAjWnA/nZ2jz31kxR/AqRaUT8ewHBw/WuBIosK0moMy1C9e5ValbDfFdIxJzVOOYaYkV/b2F1S4H/aHiqfVQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
@@ -53,7 +51,6 @@
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.11.0.tgz",
|
||||
"integrity": "sha512-IUZydyTUkDnYdstOW9pFOOUQlBjAepK5teihDE3x6yxsPJs/hsAaaYpeGxdxrgtOiJbBKSjKW7MDk7AEhb4LRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -68,7 +65,6 @@
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.11.1.tgz",
|
||||
"integrity": "sha512-2QygG2F76ZpMP2eMztiJvAiFMu71M9rDeU7vO/QKg5Css7MgM4frUOslFjhVjRhbGaCNPtz/S8M6y46/fFKVuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -87,7 +83,6 @@
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
|
||||
"integrity": "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.0.0",
|
||||
@@ -103,7 +98,6 @@
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.7.0.tgz",
|
||||
"integrity": "sha512-7GEAoIsaoBr6KELNRb8nypowCqvk8dnCHFCYg4XD4lOQGY2GqjQg5IhkRjyBFRO18CGSMq05PaNqSOE9GQro3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
@@ -116,7 +110,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-process/-/core-process-1.0.0.tgz",
|
||||
"integrity": "sha512-/shnJ+ooO8WPxDhPEeI/2oRQuubn16gZ6CvlbpWbEswZfzwI9tI/sMAHmF3x1LuQ9yZYXfLW3TjzGMLEC5blKg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
@@ -126,7 +119,6 @@
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.25.0.tgz",
|
||||
"integrity": "sha512-bMs8ekJLjX8wPV+9IPBges1SLPyuDtE9g5gLDWOpxzKcoOFQnpLGkbcT1tdw3FaAmDS1gnPmMmJ6y/T5B96kIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -145,7 +137,6 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.4.0.tgz",
|
||||
"integrity": "sha512-eGwxD0AtncrxeBM4tG8R55Pc3rdX1hNW2WibJAgYpCVA6E93mvvVH+LcssoVjOBrSKWS55yEIHsk0X8ctHmfOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
@@ -158,7 +149,6 @@
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.14.0.tgz",
|
||||
"integrity": "sha512-9n2pWK61veAuN0V20t9lOuoV4CFMdyAZ1ygZzvBGk/pBBJRib/PjL9PLXa/aI2CcPpyHfqVsxxqLCYl6uZlfDw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -173,7 +163,6 @@
|
||||
"version": "4.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.14.1.tgz",
|
||||
"integrity": "sha512-HHuuFrmN1uuF9D5A6aAo5eHzNFNX4Q+P4SksZqDKse5YaJFFy/zDLG3wXHEV2FVGgetZ3QM8jGURNBtnQYf1NQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.0.0",
|
||||
@@ -197,7 +186,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/keyvault-common/-/keyvault-common-2.1.1.tgz",
|
||||
"integrity": "sha512-SxpomJRTBfDTQnuii3w10WnZNQJGPNi15tRPdPUQz7BqyB3yk976knEueS7R0H9kSLtXbP0wJZXRh0EbRTQ0lw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure-rest/core-client": "^2.3.3",
|
||||
@@ -217,7 +205,6 @@
|
||||
"version": "4.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/keyvault-keys/-/keyvault-keys-4.10.2.tgz",
|
||||
"integrity": "sha512-VmUSLbXRAbSzDD8grXHGPaknYs0SKr3yuf6U+d4XMpX4XuVYskNqbTTwXce0zR1LyxfTZm9rWEBcvs3vdYwCmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure-rest/core-client": "^2.3.3",
|
||||
@@ -240,7 +227,6 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.4.0.tgz",
|
||||
"integrity": "sha512-rbAE25KUfjU/s3XHUdJgceoCP5dEOpMx85J04kF+QMdta73XkuG9JGHHinch+XIoKpBdqljin+KqURpJriSzLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typespec/ts-http-runtime": "^0.3.0",
|
||||
@@ -254,7 +240,6 @@
|
||||
"version": "5.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.27.0.tgz",
|
||||
"integrity": "sha512-i2CKKyuCuOZEBZJiAoFK/viYZAP6CRaqqlkeHl3ViteDHOUE/tkI/Slq1cdGnwhkIB+k1OE0g00QGl9O0gAFNQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "16.15.0"
|
||||
@@ -267,7 +252,6 @@
|
||||
"version": "16.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.15.0.tgz",
|
||||
"integrity": "sha512-lwdLb1B9Q5nEhPLVIKe78XH5wFMN15fCiDkY7ylPDSWZuWcD93G3jpJajrKhO3CQld8SLKz0sHiOi24mxdvtsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
@@ -277,7 +261,6 @@
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-7.1.2.tgz",
|
||||
"integrity": "sha512-52hKQLGpEQzwNufIXG1SPVU+wQ3RIe7Rp2+g+VdAmZojCAZ6yCdGEffzQEQ6RnBZGBEs40nl14rWBmfJpCoHsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "16.15.0",
|
||||
@@ -453,7 +436,6 @@
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@js-joda/core/-/core-6.3.2.tgz",
|
||||
"integrity": "sha512-BVsYu84Gut8YTNR1v5/PnifmqXv4SVcfA/hVIM/mXADZfIocip/DfNppBtv+4am5hGH1XuH6FSoU8OHkBvZMeA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@pinojs/redact": {
|
||||
@@ -467,7 +449,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-1.1.0.tgz",
|
||||
"integrity": "sha512-z9ZBWEG+8pIB5V1zYzlRPXx0oRJ5H7coPnMQK8EZOw03UTPI9Umn6viL36f5w+CuqkKsnCM50RVStpjZmR0Bng==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/better-sqlite3": {
|
||||
@@ -549,7 +530,6 @@
|
||||
"version": "24.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz",
|
||||
"integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
@@ -585,7 +565,6 @@
|
||||
"version": "4.0.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.25.tgz",
|
||||
"integrity": "sha512-7GsxL8Wd5X3jh73/qgW7WCnbBvGSdD8U3E4Jiuus3/8I+PN20DtlkJtwFhr/sImXfDDQ2Z03i/9wNiIF3TVSsw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
@@ -616,7 +595,6 @@
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.9.tgz",
|
||||
"integrity": "sha512-edSdeAqkdxBVzA1yL1LrLCml1YjyCVvPMtMqJpbF+6K609tHe8V6sQUzFQSGcYNhcuhOceZtjvN32+mpIth30A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
@@ -631,7 +609,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
@@ -665,7 +642,6 @@
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
|
||||
"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
@@ -758,7 +734,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
|
||||
"integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
@@ -768,7 +743,6 @@
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -876,14 +850,12 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/bundle-name": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.1.tgz",
|
||||
"integrity": "sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"run-applescript": "^7.0.0"
|
||||
@@ -947,7 +919,6 @@
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
@@ -1005,7 +976,6 @@
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
@@ -1049,7 +1019,6 @@
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz",
|
||||
"integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bundle-name": "^4.1.0",
|
||||
@@ -1066,7 +1035,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
|
||||
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -1079,7 +1047,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
|
||||
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -1137,7 +1104,6 @@
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
@@ -1228,7 +1194,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -1238,7 +1203,6 @@
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.x"
|
||||
@@ -1493,7 +1457,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-property": "^1.0.2"
|
||||
@@ -1609,7 +1572,6 @@
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.0",
|
||||
@@ -1623,7 +1585,6 @@
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.2",
|
||||
@@ -1637,7 +1598,6 @@
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
||||
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
@@ -1654,7 +1614,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -1675,7 +1634,6 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ini": {
|
||||
@@ -1699,7 +1657,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
|
||||
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"is-docker": "cli.js"
|
||||
@@ -1715,7 +1672,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
|
||||
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
@@ -1728,7 +1684,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
|
||||
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-docker": "^3.0.0"
|
||||
@@ -1754,14 +1709,12 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-wsl": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
|
||||
"integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-inside-container": "^1.0.0"
|
||||
@@ -1777,7 +1730,6 @@
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz",
|
||||
"integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-schema-ref-resolver": {
|
||||
@@ -1811,7 +1763,6 @@
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
|
||||
"integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jws": "^4.0.1",
|
||||
@@ -1834,7 +1785,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
|
||||
"integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "^1.0.1",
|
||||
@@ -1846,7 +1796,6 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.1",
|
||||
@@ -1894,63 +1843,54 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/lru.min": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.5.tgz",
|
||||
"integrity": "sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"bun": ">=1.0.0",
|
||||
@@ -2060,14 +2000,12 @@
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mssql": {
|
||||
"version": "12.7.10",
|
||||
"resolved": "https://registry.npmjs.org/mssql/-/mssql-12.7.10.tgz",
|
||||
"integrity": "sha512-vTmKBsogfFhd8dMhFjwn2QiPZuUP2/zpqt19L8eEJpQFwRa19bR+n3pFBjRtGdz+YfuC5jgj4YixILSAAF3ovQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tediousjs/connection-string": "^1.0.0",
|
||||
@@ -2087,7 +2025,6 @@
|
||||
"version": "3.24.6",
|
||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.24.6.tgz",
|
||||
"integrity": "sha512-enu73KhbAua2L3dIxjc6qg6ZJ7H3pt1BImZASWNWY5xSsmJ1ZuUPULTDGXgmJbI61vb+nJAG19IZclIq19UidQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"aws-ssl-profiles": "^1.1.2",
|
||||
@@ -2109,7 +2046,6 @@
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz",
|
||||
"integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lru.min": "^1.1.0"
|
||||
@@ -2129,7 +2065,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/native-duplexpair/-/native-duplexpair-1.0.0.tgz",
|
||||
"integrity": "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
@@ -2216,7 +2151,6 @@
|
||||
"version": "11.0.4",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-11.0.4.tgz",
|
||||
"integrity": "sha512-++Zlftm0kVLPmzC06t6epuWmcRMDbI4z5P3NNX979WA/k23+NtSOynEGzsVfZwguKw2mi5umVgnBlJQMwRz4Pg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"default-browser": "^5.5.1",
|
||||
@@ -2258,7 +2192,6 @@
|
||||
"version": "8.23.1",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.23.1.tgz",
|
||||
"integrity": "sha512-aL96AHANtWjPLDOLqnhx+ngp9+UK7ETEU8VJrDCGvsSSi/mGLcWYsS6Herg7lmaBJe4uwrfqsa7gTEFaSizDoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-connection-string": "^2.14.1",
|
||||
@@ -2286,7 +2219,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.1.tgz",
|
||||
"integrity": "sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
@@ -2294,14 +2226,12 @@
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.1.tgz",
|
||||
"integrity": "sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-int8": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
@@ -2311,7 +2241,6 @@
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
|
||||
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"pg": ">=8.0"
|
||||
@@ -2321,14 +2250,12 @@
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.1.tgz",
|
||||
"integrity": "sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-types": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-int8": "1.0.1",
|
||||
@@ -2345,7 +2272,6 @@
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
||||
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"split2": "^4.1.0"
|
||||
@@ -2395,7 +2321,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -2405,7 +2330,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
|
||||
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2415,7 +2339,6 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
||||
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2425,7 +2348,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"xtend": "^4.0.0"
|
||||
@@ -2438,7 +2360,6 @@
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.1.tgz",
|
||||
"integrity": "sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
@@ -2479,7 +2400,6 @@
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
@@ -2692,7 +2612,6 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
|
||||
"integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -2705,7 +2624,6 @@
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2759,7 +2677,6 @@
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/secure-json-parse": {
|
||||
@@ -2783,7 +2700,6 @@
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
|
||||
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -2990,7 +2906,6 @@
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 10.x"
|
||||
@@ -3000,7 +2915,6 @@
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.5.2.tgz",
|
||||
"integrity": "sha512-6CKD38c31SENivxOADeMNLdukOnUxUcflKtzVWzace7Riv1v7cAEym5Cx9Q7gYZ3ezIJI7ZpqecQq8cqNeSSFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"bun": ">=1.0.0",
|
||||
@@ -3026,7 +2940,6 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
@@ -3076,7 +2989,6 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.1.2.tgz",
|
||||
"integrity": "sha512-3RTvqKZcK/17jnJ8rMKFXbyNogywTs1z0gVPPwFsJGX46rkmUHOdIaSQ/aVO1rS7nH+soiXiWk7rvUXxndm8Dg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
@@ -3086,7 +2998,6 @@
|
||||
"version": "20.3.8",
|
||||
"resolved": "https://registry.npmjs.org/tedious/-/tedious-20.3.8.tgz",
|
||||
"integrity": "sha512-ZrJiwyGn340Sa0V0g37Xqj5bvmJ1riYwvEtg7zdm/lpw70f2ZNIQ2fvHmntU5fEOorWDa48Jo1oKYAuUP+rh7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/core-auth": "^1.10.1",
|
||||
@@ -3107,7 +3018,6 @@
|
||||
"version": "6.1.6",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-6.1.6.tgz",
|
||||
"integrity": "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^4.0.0",
|
||||
@@ -3120,7 +3030,6 @@
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -3145,7 +3054,6 @@
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.8.0.tgz",
|
||||
"integrity": "sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"abort-controller": "^3.0.0",
|
||||
@@ -3195,7 +3103,6 @@
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.9.1.tgz",
|
||||
"integrity": "sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==",
|
||||
"dev": true,
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
@@ -3248,7 +3155,6 @@
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
@@ -3289,7 +3195,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-c16PKLIRxBYpR3jSWsdS7SFp0COm5SOQdiFjY818dYFHJbMGuLBszpF07LBWmOS1uzrHa9VGdynsEgoeKy0oOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-wsl": "^3.1.0",
|
||||
@@ -3306,7 +3211,6 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
@@ -3314,7 +3218,7 @@
|
||||
},
|
||||
"packages/core": {
|
||||
"name": "@crudy/restloom",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
@@ -3326,10 +3230,10 @@
|
||||
},
|
||||
"packages/express": {
|
||||
"name": "@crudy/restloom-express",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
@@ -3346,10 +3250,10 @@
|
||||
},
|
||||
"packages/fastify": {
|
||||
"name": "@crudy/restloom-fastify",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
@@ -3365,84 +3269,60 @@
|
||||
},
|
||||
"packages/mssql": {
|
||||
"name": "@crudy/restloom-mssql",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"mssql": "^12.7.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mssql": "^12.0.0",
|
||||
"@types/node": "^24.0.0",
|
||||
"mssql": "12.7.10",
|
||||
"typescript": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mssql": "^12.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"mssql": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/mysql": {
|
||||
"name": "@crudy/restloom-mysql",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"mysql2": "^3.24.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
"mysql2": "^3.24.5",
|
||||
"typescript": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mysql2": "^3.11.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"mysql2": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/postgres": {
|
||||
"name": "@crudy/restloom-postgres",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"pg": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
"@types/pg": "^8.11.0",
|
||||
"pg": "^8.16.0",
|
||||
"typescript": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg": "^8.11.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"pg": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/sqlite": {
|
||||
"name": "@crudy/restloom-sqlite",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.0",
|
||||
|
||||
@@ -32,19 +32,19 @@ Your backend stays in charge:
|
||||
| `@crudy/restloom-express` | Express handler |
|
||||
|
||||
```sh
|
||||
npm install @crudy/restloom @crudy/restloom-postgres pg
|
||||
npm install @crudy/restloom-postgres
|
||||
```
|
||||
|
||||
A database package brings the core and its driver, and exports the whole core.
|
||||
|
||||
## Use
|
||||
|
||||
```ts
|
||||
import http from 'node:http';
|
||||
import pg from 'pg';
|
||||
import { createREST, nodeListener } from '@crudy/restloom';
|
||||
import { postgres } from '@crudy/restloom-postgres';
|
||||
import { createREST, nodeListener, postgres } from '@crudy/restloom-postgres';
|
||||
|
||||
const rest = createREST({
|
||||
db: postgres(new pg.Pool()),
|
||||
db: postgres(process.env.DATABASE_URL),
|
||||
expose: { schemas: ['app'] },
|
||||
resources: { todos: { write: true } },
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "A REST API generated from your database's catalog: discovery, a curl-friendly query grammar, relations of every kind, safe defaults",
|
||||
"keywords": ["rest", "api", "postgrest", "sql", "database", "crud", "generator"],
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
import { RestError } from './errors.js';
|
||||
import type { RestResponse } from './options.js';
|
||||
import type { Rest } from './rest.js';
|
||||
|
||||
export interface NodeListenerOptions<C> {
|
||||
/** Builds the context hooks receive, e.g. the authenticated user. */
|
||||
/** Builds the context hooks receive, e.g. the authenticated user. Throw a RestError to refuse the request. */
|
||||
context?(req: IncomingMessage): C | Promise<C>;
|
||||
/** Path the API is mounted under, e.g. /api. */
|
||||
prefix?: string;
|
||||
@@ -47,6 +48,13 @@ export function nodeListener<C>(rest: Rest<C>, options: NodeListenerOptions<C> =
|
||||
const status = (err as { status?: number }).status ?? 400;
|
||||
return send(res, { status, headers: {}, body: { error: status === 413 ? 'body_too_large' : 'bad_body' } });
|
||||
}
|
||||
let context: C;
|
||||
try {
|
||||
context = (await options.context?.(req)) as C;
|
||||
} catch (err) {
|
||||
const refusal = err instanceof RestError ? err : new RestError(500, 'internal');
|
||||
return send(res, { status: refusal.status, headers: {}, body: { error: refusal.code, ...(refusal.detail ? { message: refusal.detail } : {}) } });
|
||||
}
|
||||
const headers = Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(', ') : v]));
|
||||
send(res, await rest.handle({
|
||||
method: req.method ?? 'GET',
|
||||
@@ -54,7 +62,7 @@ export function nodeListener<C>(rest: Rest<C>, options: NodeListenerOptions<C> =
|
||||
query: url.searchParams,
|
||||
headers,
|
||||
body,
|
||||
context: (await options.context?.(req)) as C,
|
||||
context,
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import http from 'node:http';
|
||||
import { createREST, nodeListener } from '../dist/index.js';
|
||||
import { createREST, nodeListener, RestError } from '../dist/index.js';
|
||||
import { fakeDialect } from './fake-dialect.mjs';
|
||||
|
||||
test('the node listener serves under its prefix and refuses bad bodies', async () => {
|
||||
@@ -24,3 +24,26 @@ test('Prefer: count=exact counts as count=exact does', async () => {
|
||||
const res = await rest.handle({ method: 'GET', path: '/items', query: new URLSearchParams(), headers: { prefer: 'count=exact' }, context: undefined });
|
||||
assert.equal(res.headers['content-range'], '0-0/1');
|
||||
});
|
||||
|
||||
test('a context that throws answers the request instead of stopping the process', async () => {
|
||||
const rest = createREST({ db: fakeDialect(), expose: { schemas: ['app'] } });
|
||||
const server = http.createServer(nodeListener(rest, {
|
||||
context(req) {
|
||||
if (req.headers.authorization === 'bad') throw new RestError(401, 'unauthenticated');
|
||||
if (req.headers.authorization === 'broken') throw new Error('database down');
|
||||
return {};
|
||||
},
|
||||
})).listen(0);
|
||||
const base = `http://127.0.0.1:${server.address().port}`;
|
||||
try {
|
||||
const refused = await fetch(`${base}/items`, { headers: { authorization: 'bad' } });
|
||||
assert.equal(refused.status, 401);
|
||||
assert.deepEqual(await refused.json(), { error: 'unauthenticated' });
|
||||
const broken = await fetch(`${base}/items`, { headers: { authorization: 'broken' } });
|
||||
assert.equal(broken.status, 500);
|
||||
assert.deepEqual(await broken.json(), { error: 'internal' });
|
||||
assert.equal((await fetch(`${base}/items`)).status, 200);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-express",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "Express adapter for restloom",
|
||||
"keywords": [
|
||||
@@ -36,7 +36,7 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": "^5.0.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-fastify",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "Fastify adapter for restloom",
|
||||
"keywords": [
|
||||
@@ -36,7 +36,7 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"fastify": "^5.0.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-mssql",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "SQL Server dialect for restloom",
|
||||
"keywords": [
|
||||
@@ -37,18 +37,12 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mssql": "^12.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"mssql": { "optional": true }
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"mssql": "^12.7.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
"@types/mssql": "^12.0.0",
|
||||
"mssql": "12.7.10",
|
||||
"typescript": "^5.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import { RestError, type Dialect, type SqlRenderer } from '@crudy/restloom';
|
||||
import mssqlDriver, { type ConnectionPool } from 'mssql';
|
||||
import mssqlDriver, { type ConnectionPool, type config as MssqlConfig } from 'mssql';
|
||||
import { introspect } from './introspect.js';
|
||||
import { MssqlRenderer } from './renderer.js';
|
||||
|
||||
export * from '@crudy/restloom';
|
||||
|
||||
/** A connected mssql ConnectionPool, or what opens one: a connection string or config. */
|
||||
export type MssqlConnection = ConnectionPool | MssqlConfig | string;
|
||||
|
||||
function poolOf(c: MssqlConnection): Promise<ConnectionPool> {
|
||||
if (typeof c !== 'string' && typeof (c as ConnectionPool).request === 'function') return Promise.resolve(c as ConnectionPool);
|
||||
const ready = new mssqlDriver.ConnectionPool(c as MssqlConfig).connect();
|
||||
// A failed connection surfaces on the first request, not as an unhandled rejection at startup.
|
||||
ready.catch(() => undefined);
|
||||
return ready;
|
||||
}
|
||||
|
||||
export { MssqlRenderer } from './renderer.js';
|
||||
|
||||
const CODES: Record<number, [number, string]> = {
|
||||
@@ -37,20 +50,21 @@ export interface MssqlOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQL Server 2022 dialect over an mssql ConnectionPool. Each request is one
|
||||
* The SQL Server 2022 dialect over an mssql ConnectionPool, given or opened. Each request is one
|
||||
* transaction; the statement timeout is the pool's `requestTimeout`, since the
|
||||
* driver sets it per pool. Row security is SQL Server's security policies,
|
||||
* which a `transaction` hook feeds through sp_set_session_context.
|
||||
*/
|
||||
export function mssql(pool: ConnectionPool, options: MssqlOptions = {}): Dialect {
|
||||
export function mssql(connection: MssqlConnection, options: MssqlOptions = {}): Dialect {
|
||||
const ready = poolOf(connection);
|
||||
return {
|
||||
name: 'mssql',
|
||||
capabilities: { returning: true, estimatedCount: false, rowSecurity: true, procedures: true },
|
||||
renderer: options.renderer ?? new MssqlRenderer(),
|
||||
decode: (value) => (typeof value === 'string' ? JSON.parse(value) : value),
|
||||
introspect: (scope) => introspect(pool, scope),
|
||||
introspect: async (scope) => introspect(await ready, scope),
|
||||
async transaction(fn) {
|
||||
const tx = new mssqlDriver.Transaction(pool);
|
||||
const tx = new mssqlDriver.Transaction(await ready);
|
||||
await tx.begin();
|
||||
try {
|
||||
const out = await fn({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-mysql",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "MySQL dialect for restloom",
|
||||
"keywords": [
|
||||
@@ -36,17 +36,11 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mysql2": "^3.11.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"mysql2": { "optional": true }
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"mysql2": "^3.24.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
"mysql2": "^3.24.5",
|
||||
"typescript": "^5.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { RestError, type Dialect, type SqlRenderer } from '@crudy/restloom';
|
||||
import type { Pool } from 'mysql2/promise';
|
||||
import { createPool, type Pool, type PoolOptions } from 'mysql2/promise';
|
||||
import { introspect } from './introspect.js';
|
||||
import { MysqlRenderer } from './renderer.js';
|
||||
|
||||
export * from '@crudy/restloom';
|
||||
|
||||
/** A mysql2/promise Pool, or what opens one: a connection URL or pool options. */
|
||||
export type MysqlConnection = Pool | PoolOptions | string;
|
||||
|
||||
const poolOf = (c: MysqlConnection): Pool =>
|
||||
typeof c === 'string' ? createPool({ uri: c }) : typeof (c as Pool).getConnection === 'function' ? (c as Pool) : createPool(c as PoolOptions);
|
||||
|
||||
export { MysqlRenderer } from './renderer.js';
|
||||
|
||||
const CODES: Record<number, [number, string]> = {
|
||||
@@ -31,12 +39,13 @@ export interface MysqlOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* The MySQL 8 dialect over a mysql2/promise Pool. Each request is one
|
||||
* The MySQL 8 dialect over a mysql2/promise Pool, given or opened. Each request is one
|
||||
* transaction on one connection, in UTC, with MAX_EXECUTION_TIME for reads.
|
||||
* Text compares with each column's collation, so with a case-insensitive
|
||||
* collation `eq` ignores case.
|
||||
*/
|
||||
export function mysql(pool: Pool, options: MysqlOptions = {}): Dialect {
|
||||
export function mysql(connection: MysqlConnection, options: MysqlOptions = {}): Dialect {
|
||||
const pool = poolOf(connection);
|
||||
return {
|
||||
name: 'mysql',
|
||||
capabilities: { returning: false, estimatedCount: false, rowSecurity: false, procedures: true },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-postgres",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "Postgres dialect for restloom",
|
||||
"keywords": ["restloom", "postgres", "postgresql", "rest", "api"],
|
||||
@@ -18,18 +18,12 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg": "^8.11.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"pg": { "optional": true }
|
||||
"@crudy/restloom": "^0.5.0",
|
||||
"pg": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.0",
|
||||
"@types/pg": "^8.11.0",
|
||||
"pg": "^8.16.0",
|
||||
"typescript": "^5.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { SqlRenderer, type Dialect, type Tx } from '@crudy/restloom';
|
||||
import type { Pool } from 'pg';
|
||||
import pg, { type Pool, type PoolConfig } from 'pg';
|
||||
import { mapError } from './errors.js';
|
||||
import { introspect } from './introspect.js';
|
||||
|
||||
export * from '@crudy/restloom';
|
||||
export { mapError } from './errors.js';
|
||||
|
||||
/** A pg Pool, or what opens one: a connection string or a pool config. */
|
||||
export type PostgresConnection = Pool | PoolConfig | string;
|
||||
|
||||
const poolOf = (c: PostgresConnection): Pool =>
|
||||
typeof c === 'string' ? new pg.Pool({ connectionString: c }) : typeof (c as Pool).connect === 'function' ? (c as Pool) : new pg.Pool(c as PoolConfig);
|
||||
|
||||
/** Postgres writes every primitive the core's defaults assume; subclass it to change one. */
|
||||
export class PostgresRenderer extends SqlRenderer {}
|
||||
|
||||
@@ -13,11 +20,13 @@ export interface PostgresOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Postgres dialect over a `pg` Pool. Every request runs in one transaction
|
||||
* The Postgres dialect over a `pg` Pool, given or opened from a connection
|
||||
* string or config. Every request runs in one transaction
|
||||
* with a local statement timeout, read-only for reads, so a `transaction` hook
|
||||
* can set the role and session settings that row security reads.
|
||||
*/
|
||||
export function postgres(pool: Pool, options: PostgresOptions = {}): Dialect {
|
||||
export function postgres(connection: PostgresConnection, options: PostgresOptions = {}): Dialect {
|
||||
const pool = poolOf(connection);
|
||||
return {
|
||||
name: 'postgres',
|
||||
capabilities: { returning: true, estimatedCount: true, rowSecurity: true, procedures: true },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@crudy/restloom-sqlite",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"type": "module",
|
||||
"description": "SQLite dialect for restloom",
|
||||
"keywords": [
|
||||
@@ -36,7 +36,7 @@
|
||||
"prepack": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crudy/restloom": "^0.4.0"
|
||||
"@crudy/restloom": "^0.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"better-sqlite3": ">=12"
|
||||
|
||||
@@ -3,6 +3,8 @@ import type { Database } from 'better-sqlite3';
|
||||
import { introspect } from './introspect.js';
|
||||
import { SqliteRenderer } from './renderer.js';
|
||||
|
||||
export * from '@crudy/restloom';
|
||||
|
||||
export { SqliteRenderer } from './renderer.js';
|
||||
|
||||
const CODES: Record<string, [number, string]> = {
|
||||
@@ -27,7 +29,8 @@ export interface SqliteOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQLite dialect over a better-sqlite3 Database. It turns on foreign keys
|
||||
* The SQLite dialect over a better-sqlite3 Database, or any object with its
|
||||
* API, such as sql.js in a browser. It turns on foreign keys
|
||||
* and case-sensitive LIKE for the connection. One connection runs one
|
||||
* transaction at a time, so requests are queued. SQLite cannot stop a running
|
||||
* statement, so `limits.timeoutMs` does not apply, and it has no functions to
|
||||
|
||||
Reference in New Issue
Block a user