rado 1.3.0-preview.3 → 1.3.0-preview.5
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/dist/core/Index.js +12 -1
- package/dist/core/MetaData.d.ts +1 -1
- package/dist/core/query/Select.d.ts +27 -25
- package/dist/driver/better-sqlite3.js +4 -1
- package/dist/driver/bun-sqlite.js +15 -4
- package/dist/driver/d1.d.ts +1 -1
- package/dist/driver/d1.js +9 -2
- package/dist/driver/libsql.d.ts +1 -1
- package/dist/driver/mysql2.d.ts +2 -1
- package/dist/driver/mysql2.js +12 -4
- package/dist/driver/node-sqlite.js +4 -1
- package/dist/driver/pg.js +15 -3
- package/package.json +4 -1
package/dist/core/Index.js
CHANGED
|
@@ -13,14 +13,25 @@ var IndexData = class {
|
|
|
13
13
|
};
|
|
14
14
|
var IndexApi = class extends IndexData {
|
|
15
15
|
toSql(tableName, indexName, ifNotExists) {
|
|
16
|
+
const fields = this.fields.map(
|
|
17
|
+
(field) => sql.join([
|
|
18
|
+
field,
|
|
19
|
+
this.order && sql.unsafe(this.order),
|
|
20
|
+
this.nulls && sql`nulls ${sql.unsafe(this.nulls)}`
|
|
21
|
+
])
|
|
22
|
+
);
|
|
16
23
|
return sql.join([
|
|
17
24
|
sql`create`,
|
|
18
25
|
this.unique && sql`unique`,
|
|
19
26
|
sql`index`,
|
|
27
|
+
this.concurrently && sql`concurrently`,
|
|
20
28
|
ifNotExists && sql`if not exists`,
|
|
21
29
|
sql.identifier(indexName),
|
|
22
30
|
sql`on`,
|
|
23
|
-
|
|
31
|
+
this.only && sql`only`,
|
|
32
|
+
sql.identifier(tableName),
|
|
33
|
+
this.using && sql`using ${this.using}`,
|
|
34
|
+
sql`(${sql.join(fields, sql`, `)})`,
|
|
24
35
|
this.where && sql`where ${this.where}`
|
|
25
36
|
]).inlineFields(false);
|
|
26
37
|
}
|
package/dist/core/MetaData.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type QueryMode = 'sync' | 'async' | undefined;
|
|
2
2
|
export type Runtime = 'sqlite' | 'mysql' | 'postgres';
|
|
3
3
|
export type QueryDialect = 'universal' | Runtime;
|
|
4
|
-
export type Deliver<Meta extends QueryMeta, Result> = Meta extends
|
|
4
|
+
export type Deliver<Meta extends QueryMeta, Result> = Meta extends Sync ? Result : Meta extends Async ? Promise<Result> : Result | Promise<Result>;
|
|
5
5
|
export interface QueryMeta {
|
|
6
6
|
mode: QueryMode;
|
|
7
7
|
dialect: QueryDialect;
|
|
@@ -83,13 +83,13 @@ export interface SelectBase<Input, Meta extends QueryMeta = QueryMeta> extends U
|
|
|
83
83
|
}
|
|
84
84
|
export interface WithoutSelection<Meta extends QueryMeta> {
|
|
85
85
|
from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>): AllFrom<TableFields<Definition>, Meta, Record<Name, TableFields<Definition>>>;
|
|
86
|
-
from<Input>(from: SubQuery<Input>):
|
|
87
|
-
from<Input>(from: VirtualTarget<Input>):
|
|
86
|
+
from<Input, Name extends string>(from: SubQuery<Input, Name>): SelectionFromTargets<Input, Meta, Name>;
|
|
87
|
+
from<Input>(from: VirtualTarget<Input>): SelectionFromTargets<Input, Meta, string>;
|
|
88
88
|
}
|
|
89
89
|
export interface WithSelection<Input, Meta extends QueryMeta> extends SelectBase<Input, Meta>, HasSql<SelectionRow<Input>> {
|
|
90
|
-
from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>):
|
|
91
|
-
from(from:
|
|
92
|
-
from(from:
|
|
90
|
+
from<Definition extends TableDefinition, Name extends string>(from: Table<Definition, Name>): SelectionFromTargets<Input, Meta, Name>;
|
|
91
|
+
from<SubInput, Name extends string>(from: SubQuery<SubInput, Name>): SelectionFromTargets<Input, Meta, Name>;
|
|
92
|
+
from<Name extends string>(from: HasTarget<Name>): SelectionFromTargets<Input, Meta, Name>;
|
|
93
93
|
from(from: HasSql): Select<Input, Meta>;
|
|
94
94
|
}
|
|
95
95
|
export interface AllFrom<Input, Meta extends QueryMeta, Tables = Input> extends SelectBase<Input, Meta> {
|
|
@@ -110,28 +110,30 @@ export interface AllFrom<Input, Meta extends QueryMeta, Tables = Input> extends
|
|
|
110
110
|
fullJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): AllFrom<Expand<MakeNullable<Tables> & MakeNullable<Record<Name, TableFields<Definition>>>>, Meta>;
|
|
111
111
|
fullJoin<Input, Name extends string>(right: SubQuery<Input, Name>, on: HasSql<boolean>): AllFrom<Expand<MakeNullable<Tables> & MakeNullable<Record<Name, Input>>>, Meta>;
|
|
112
112
|
}
|
|
113
|
-
type MarkFieldsAsNullable<Input, TableName extends string> = Expand<{
|
|
113
|
+
type MarkFieldsAsNullable<Input, TableName extends string> = Input extends Table<infer Definition, TableName> ? TableFields<Definition> & IsNullable : Input extends Table ? Input : Expand<{
|
|
114
114
|
[K in keyof Input]: Input[K] extends Field<infer T, TableName> ? HasSql<T | null> : Input[K] extends Table<infer Definition, TableName> ? TableFields<Definition> & IsNullable : Input[K] extends Record<string, Field<unknown, TableName> | HasSql<unknown>> ? Input[K] & IsNullable : Input[K] extends SelectionRecord ? MarkFieldsAsNullable<Input[K], TableName> : Input[K];
|
|
115
115
|
}>;
|
|
116
|
-
export interface SelectionFrom<Input, Meta extends QueryMeta> extends
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
leftJoin(right:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
fullJoin(right:
|
|
116
|
+
export interface SelectionFrom<Input, Meta extends QueryMeta> extends SelectionFromTargets<Input, Meta, never> {
|
|
117
|
+
}
|
|
118
|
+
interface SelectionFromTargets<Input, Meta extends QueryMeta, FromNames extends string = never> extends SelectBase<Input, Meta> {
|
|
119
|
+
leftJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
|
|
120
|
+
leftJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
|
|
121
|
+
leftJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
|
|
122
|
+
leftJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
|
|
123
|
+
leftJoinLateral<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, Name>, Meta, FromNames | Name>;
|
|
124
|
+
rightJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames | Name>;
|
|
125
|
+
rightJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames>;
|
|
126
|
+
innerJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames | Name>;
|
|
127
|
+
innerJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
|
|
128
|
+
innerJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames | Name>;
|
|
129
|
+
innerJoinLateral(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<Input, Meta, FromNames>;
|
|
130
|
+
crossJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFromTargets<Input, Meta, FromNames | Name>;
|
|
131
|
+
crossJoin(right: HasTarget): SelectionFromTargets<Input, Meta, FromNames>;
|
|
132
|
+
crossJoinLateral<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>): SelectionFromTargets<Input, Meta, FromNames | Name>;
|
|
133
|
+
crossJoinLateral(right: HasTarget): SelectionFromTargets<Input, Meta, FromNames>;
|
|
134
|
+
fullJoin<Definition extends TableDefinition, Name extends string>(right: Table<Definition, Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<MarkFieldsAsNullable<Input, FromNames>, Name>, Meta, FromNames | Name>;
|
|
135
|
+
fullJoin<Name extends string>(right: HasTarget<Name>, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<MarkFieldsAsNullable<Input, FromNames>, Name>, Meta, FromNames | Name>;
|
|
136
|
+
fullJoin(right: HasTarget, on: HasSql<boolean>): SelectionFromTargets<MarkFieldsAsNullable<Input, FromNames>, Meta, FromNames>;
|
|
135
137
|
}
|
|
136
138
|
export declare function querySelection({ select, from }: SelectQuery): Selection;
|
|
137
139
|
export declare function selectQuery(query: SelectQuery): Sql;
|
|
@@ -44,7 +44,10 @@ var BetterSqlite3Driver = class _BetterSqlite3Driver {
|
|
|
44
44
|
this.client.close();
|
|
45
45
|
}
|
|
46
46
|
prepare(sql, options) {
|
|
47
|
-
return new PreparedStatement(
|
|
47
|
+
return new PreparedStatement(
|
|
48
|
+
this.client.prepare(sql),
|
|
49
|
+
options?.isSelection ?? false
|
|
50
|
+
);
|
|
48
51
|
}
|
|
49
52
|
batch(queries) {
|
|
50
53
|
return this.transaction(
|
|
@@ -4,10 +4,12 @@ import { sqliteDialect } from "../sqlite.js";
|
|
|
4
4
|
import { sqliteDiff } from "../sqlite/diff.js";
|
|
5
5
|
import { execTransaction } from "../sqlite/transactions.js";
|
|
6
6
|
var PreparedStatement = class {
|
|
7
|
-
constructor(stmt) {
|
|
7
|
+
constructor(stmt, isSelection) {
|
|
8
8
|
this.stmt = stmt;
|
|
9
|
+
this.isSelection = isSelection;
|
|
9
10
|
}
|
|
10
11
|
stmt;
|
|
12
|
+
isSelection;
|
|
11
13
|
all(params) {
|
|
12
14
|
return this.stmt.all(...params);
|
|
13
15
|
}
|
|
@@ -18,6 +20,10 @@ var PreparedStatement = class {
|
|
|
18
20
|
return this.stmt.get(...params);
|
|
19
21
|
}
|
|
20
22
|
values(params) {
|
|
23
|
+
if (!this.isSelection) {
|
|
24
|
+
this.stmt.run(...params);
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
21
27
|
return this.stmt.values(...params);
|
|
22
28
|
}
|
|
23
29
|
free() {
|
|
@@ -39,12 +45,17 @@ var BunSqliteDriver = class _BunSqliteDriver {
|
|
|
39
45
|
close() {
|
|
40
46
|
this.client.close();
|
|
41
47
|
}
|
|
42
|
-
prepare(sql) {
|
|
43
|
-
return new PreparedStatement(
|
|
48
|
+
prepare(sql, options) {
|
|
49
|
+
return new PreparedStatement(
|
|
50
|
+
this.client.prepare(sql),
|
|
51
|
+
options?.isSelection ?? false
|
|
52
|
+
);
|
|
44
53
|
}
|
|
45
54
|
batch(queries) {
|
|
46
55
|
return this.transaction((tx) => {
|
|
47
|
-
return queries.map(
|
|
56
|
+
return queries.map(
|
|
57
|
+
({ sql, params, isSelection }) => tx.prepare(sql, { isSelection }).values(params)
|
|
58
|
+
);
|
|
48
59
|
}, {});
|
|
49
60
|
}
|
|
50
61
|
transaction(run, options) {
|
package/dist/driver/d1.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare class D1Driver implements AsyncDriver {
|
|
|
17
17
|
supportsTransactions: boolean;
|
|
18
18
|
constructor(client: Client);
|
|
19
19
|
exec(query: string): Promise<void>;
|
|
20
|
-
prepare(sql: string, options
|
|
20
|
+
prepare(sql: string, options?: PrepareOptions): PreparedStatement;
|
|
21
21
|
close(): Promise<void>;
|
|
22
22
|
batch(queries: Array<BatchedQuery>): Promise<Array<Array<unknown>>>;
|
|
23
23
|
transaction<T>(): Promise<T>;
|
package/dist/driver/d1.js
CHANGED
|
@@ -37,7 +37,10 @@ var D1Driver = class {
|
|
|
37
37
|
await this.client.exec(query);
|
|
38
38
|
}
|
|
39
39
|
prepare(sql, options) {
|
|
40
|
-
return new PreparedStatement(
|
|
40
|
+
return new PreparedStatement(
|
|
41
|
+
this.client.prepare(sql),
|
|
42
|
+
options?.isSelection ?? false
|
|
43
|
+
);
|
|
41
44
|
}
|
|
42
45
|
async close() {
|
|
43
46
|
}
|
|
@@ -46,7 +49,11 @@ var D1Driver = class {
|
|
|
46
49
|
({ sql, params }) => this.client.prepare(sql).bind(...params)
|
|
47
50
|
);
|
|
48
51
|
const rows = await this.client.batch(stmts);
|
|
49
|
-
return rows.map((row) =>
|
|
52
|
+
return rows.map((row, index) => {
|
|
53
|
+
const isSelection = queries[index]?.isSelection;
|
|
54
|
+
if (!isSelection) return [];
|
|
55
|
+
return row.results.map(Object.values);
|
|
56
|
+
});
|
|
50
57
|
}
|
|
51
58
|
async transaction() {
|
|
52
59
|
throw new Error("Transactions are not supported in D1");
|
package/dist/driver/libsql.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare class LibSQLClient implements AsyncDriver {
|
|
|
19
19
|
supportsTransactions: boolean;
|
|
20
20
|
constructor(client: Queryable, depth?: number);
|
|
21
21
|
exec(query: string): Promise<void>;
|
|
22
|
-
prepare(sql: string, options
|
|
22
|
+
prepare(sql: string, options?: PrepareOptions): PreparedStatement;
|
|
23
23
|
close(): Promise<void>;
|
|
24
24
|
batch(queries: Array<BatchedQuery>): Promise<Array<Array<unknown>>>;
|
|
25
25
|
transaction<T>(run: (inner: AsyncDriver) => Promise<T>, options: TransactionOptions['sqlite']): Promise<T>;
|
package/dist/driver/mysql2.d.ts
CHANGED
|
@@ -7,8 +7,9 @@ declare class PreparedStatement implements AsyncStatement {
|
|
|
7
7
|
#private;
|
|
8
8
|
private client;
|
|
9
9
|
private sql;
|
|
10
|
+
private isSelection;
|
|
10
11
|
private name?;
|
|
11
|
-
constructor(client: Queryable, sql: string, name?: string | undefined);
|
|
12
|
+
constructor(client: Queryable, sql: string, isSelection: boolean, name?: string | undefined);
|
|
12
13
|
all(params: Array<unknown>): Promise<Array<object>>;
|
|
13
14
|
run(params: Array<unknown>): Promise<void>;
|
|
14
15
|
get(params: Array<unknown>): Promise<object>;
|
package/dist/driver/mysql2.js
CHANGED
|
@@ -4,13 +4,15 @@ import { mysqlDialect } from "../mysql/dialect.js";
|
|
|
4
4
|
import { mysqlDiff } from "../mysql/diff.js";
|
|
5
5
|
import { setTransaction, startTransaction } from "../mysql/transactions.js";
|
|
6
6
|
var PreparedStatement = class {
|
|
7
|
-
constructor(client, sql, name) {
|
|
7
|
+
constructor(client, sql, isSelection, name) {
|
|
8
8
|
this.client = client;
|
|
9
9
|
this.sql = sql;
|
|
10
|
+
this.isSelection = isSelection;
|
|
10
11
|
this.name = name;
|
|
11
12
|
}
|
|
12
13
|
client;
|
|
13
14
|
sql;
|
|
15
|
+
isSelection;
|
|
14
16
|
name;
|
|
15
17
|
#transformParam = (param) => {
|
|
16
18
|
if (param instanceof Uint8Array) return Buffer.from(param);
|
|
@@ -26,6 +28,7 @@ var PreparedStatement = class {
|
|
|
26
28
|
return this.all(params).then((rows) => rows[0] ?? null);
|
|
27
29
|
}
|
|
28
30
|
values(params) {
|
|
31
|
+
if (!this.isSelection) return this.run(params).then(() => []);
|
|
29
32
|
return this.client.query({
|
|
30
33
|
sql: this.sql,
|
|
31
34
|
values: params.map(this.#transformParam),
|
|
@@ -48,7 +51,12 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
48
51
|
await this.client.query(query);
|
|
49
52
|
}
|
|
50
53
|
prepare(sql, options) {
|
|
51
|
-
return new PreparedStatement(
|
|
54
|
+
return new PreparedStatement(
|
|
55
|
+
this.client,
|
|
56
|
+
sql,
|
|
57
|
+
options?.isSelection ?? false,
|
|
58
|
+
options?.name
|
|
59
|
+
);
|
|
52
60
|
}
|
|
53
61
|
async close() {
|
|
54
62
|
if ("end" in this.client) return this.client.end();
|
|
@@ -56,8 +64,8 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
56
64
|
async batch(queries) {
|
|
57
65
|
const transact = async (tx) => {
|
|
58
66
|
const results = [];
|
|
59
|
-
for (const { sql, params } of queries)
|
|
60
|
-
results.push(await tx.prepare(sql).values(params));
|
|
67
|
+
for (const { sql, params, isSelection } of queries)
|
|
68
|
+
results.push(await tx.prepare(sql, { isSelection }).values(params));
|
|
61
69
|
return results;
|
|
62
70
|
};
|
|
63
71
|
if (this.depth > 0) return transact(this);
|
|
@@ -50,7 +50,10 @@ var NodeSqliteDriver = class _NodeSqliteDriver {
|
|
|
50
50
|
this.client.close();
|
|
51
51
|
}
|
|
52
52
|
prepare(sql, options) {
|
|
53
|
-
return new PreparedStatement(
|
|
53
|
+
return new PreparedStatement(
|
|
54
|
+
this.client.prepare(sql),
|
|
55
|
+
options?.isSelection ?? false
|
|
56
|
+
);
|
|
54
57
|
}
|
|
55
58
|
batch(queries) {
|
|
56
59
|
return this.transaction(
|
package/dist/driver/pg.js
CHANGED
|
@@ -3,6 +3,17 @@ import { AsyncDatabase } from "../core/Database.js";
|
|
|
3
3
|
import { postgresDialect } from "../postgres/dialect.js";
|
|
4
4
|
import { postgresDiff } from "../postgres/diff.js";
|
|
5
5
|
import { setTransaction } from "../postgres/transactions.js";
|
|
6
|
+
function isPool(client) {
|
|
7
|
+
return "connect" in client && "totalCount" in client && "idleCount" in client && "waitingCount" in client;
|
|
8
|
+
}
|
|
9
|
+
async function acquireClient(client, depth) {
|
|
10
|
+
if (depth > 0 || !isPool(client)) return { client };
|
|
11
|
+
const acquired = await client.connect();
|
|
12
|
+
return {
|
|
13
|
+
client: acquired,
|
|
14
|
+
release: () => acquired.release()
|
|
15
|
+
};
|
|
16
|
+
}
|
|
6
17
|
var PreparedStatement = class {
|
|
7
18
|
constructor(client, sql, name) {
|
|
8
19
|
this.client = client;
|
|
@@ -59,8 +70,9 @@ var PgDriver = class _PgDriver {
|
|
|
59
70
|
return new PreparedStatement(this.client, sql, options?.name);
|
|
60
71
|
}
|
|
61
72
|
async close() {
|
|
62
|
-
if (
|
|
73
|
+
if (this.depth > 0) throw new Error("Cannot close a transaction");
|
|
63
74
|
if ("release" in this.client) return this.client.release();
|
|
75
|
+
if ("end" in this.client) return this.client.end();
|
|
64
76
|
}
|
|
65
77
|
async batch(queries) {
|
|
66
78
|
return this.transaction(async (tx) => {
|
|
@@ -71,7 +83,7 @@ var PgDriver = class _PgDriver {
|
|
|
71
83
|
}, {});
|
|
72
84
|
}
|
|
73
85
|
async transaction(run, options) {
|
|
74
|
-
const client
|
|
86
|
+
const { client, release } = await acquireClient(this.client, this.depth);
|
|
75
87
|
try {
|
|
76
88
|
await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
|
|
77
89
|
if (this.depth === 0) await client.query(setTransaction(options));
|
|
@@ -86,7 +98,7 @@ var PgDriver = class _PgDriver {
|
|
|
86
98
|
);
|
|
87
99
|
throw error;
|
|
88
100
|
} finally {
|
|
89
|
-
|
|
101
|
+
release?.();
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rado",
|
|
3
|
-
"version": "1.3.0-preview.
|
|
3
|
+
"version": "1.3.0-preview.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
"format:check": "oxfmt --check .",
|
|
37
37
|
"lint": "oxlint .",
|
|
38
38
|
"check": "bun run format:check && bun run lint",
|
|
39
|
+
"test:mysql": "bun test --test-filter mysql",
|
|
40
|
+
"test:postgres": "bun test --test-filter postgres pg",
|
|
41
|
+
"test:sqlite": "bun test --test-filter sqlite",
|
|
39
42
|
"test:bun": "bun test",
|
|
40
43
|
"test:node": "node --disable-warning=ExperimentalWarning --test-force-exit --test-concurrency=1 --test-reporter=spec --experimental-transform-types --test \"**/*.test.ts\"",
|
|
41
44
|
"test:deno": "deno test --node-modules-dir=false --no-check -A --unstable-ffi",
|