@vrplatform/kysely 1.3.1 → 1.3.2
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/build/main/index.d.ts +7 -5
- package/build/main/index.js +13 -6
- package/build/main/index.js.map +1 -1
- package/build/main/local/index.d.ts +6 -2
- package/build/main/local/index.js +9 -2
- package/build/main/local/index.js.map +1 -1
- package/build/main/pganalyze-comment-plugin/comment-transformer.d.ts +21 -0
- package/build/main/pganalyze-comment-plugin/comment-transformer.js +90 -0
- package/build/main/pganalyze-comment-plugin/comment-transformer.js.map +1 -0
- package/build/main/pganalyze-comment-plugin/index.d.ts +9 -0
- package/build/main/pganalyze-comment-plugin/index.js +31 -0
- package/build/main/pganalyze-comment-plugin/index.js.map +1 -0
- package/build/main/test/index.d.ts +15 -0
- package/build/main/test/index.js +47 -0
- package/build/main/test/index.js.map +1 -0
- package/build/main/tsconfig.main.tsbuildinfo +1 -1
- package/build/module/index.d.ts +7 -5
- package/build/module/index.js +14 -7
- package/build/module/index.js.map +1 -1
- package/build/module/local/index.d.ts +6 -2
- package/build/module/local/index.js +9 -2
- package/build/module/local/index.js.map +1 -1
- package/build/module/pganalyze-comment-plugin/comment-transformer.d.ts +21 -0
- package/build/module/pganalyze-comment-plugin/comment-transformer.js +87 -0
- package/build/module/pganalyze-comment-plugin/comment-transformer.js.map +1 -0
- package/build/module/pganalyze-comment-plugin/index.d.ts +9 -0
- package/build/module/pganalyze-comment-plugin/index.js +14 -0
- package/build/module/pganalyze-comment-plugin/index.js.map +1 -0
- package/build/module/test/index.d.ts +15 -0
- package/build/module/test/index.js +42 -0
- package/build/module/test/index.js.map +1 -0
- package/build/module/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/index.ts +31 -8
- package/src/local/index.ts +14 -3
- package/src/pganalyze-comment-plugin/comment-transformer.ts +117 -0
- package/src/pganalyze-comment-plugin/index.ts +27 -0
- package/src/test/index.ts +63 -0
- package/src/test.ts +0 -19
|
@@ -2,9 +2,10 @@ import { join } from 'node:path';
|
|
|
2
2
|
import { PGlite } from '@electric-sql/pglite';
|
|
3
3
|
import { CamelCasePlugin, Kysely } from 'kysely';
|
|
4
4
|
import { KyselyPGlite } from 'kysely-pglite';
|
|
5
|
+
import { KyselyPganalyzeCommentPlugin } from '../pganalyze-comment-plugin';
|
|
5
6
|
export const root = join(__dirname, '../..');
|
|
6
7
|
export const dumpPath = join(root, '.data.tar');
|
|
7
|
-
export async function useLocalKysely() {
|
|
8
|
+
export async function useLocalKysely(args = {}) {
|
|
8
9
|
let isDestroyed = false;
|
|
9
10
|
const now = performance.now();
|
|
10
11
|
const dump = Bun.file(dumpPath);
|
|
@@ -14,7 +15,13 @@ export async function useLocalKysely() {
|
|
|
14
15
|
const { dialect } = new KyselyPGlite(pglite);
|
|
15
16
|
const kysely = new Kysely({
|
|
16
17
|
dialect,
|
|
17
|
-
|
|
18
|
+
log: args.log === true ? ['query', 'error'] : args.log,
|
|
19
|
+
plugins: [
|
|
20
|
+
new CamelCasePlugin(),
|
|
21
|
+
new KyselyPganalyzeCommentPlugin({
|
|
22
|
+
repository: args.repositoryName ?? 'localTesting',
|
|
23
|
+
}),
|
|
24
|
+
],
|
|
18
25
|
});
|
|
19
26
|
const originalDestroy = kysely.destroy.bind(kysely);
|
|
20
27
|
kysely.destroy = async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,EAAkB,MAAM,QAAQ,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAG3E,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC7C,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAMhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B,EAAE;IACnE,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,UAAU;IACV,MAAM,MAAM,CAAC,GAAG,CAAA,UAAU,CAAC;IAC3B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAK;QAC5B,OAAO;QACP,GAAG,EAAE,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG;QACtD,OAAO,EAAE;YACP,IAAI,eAAe,EAAE;YACrB,IAAI,4BAA4B,CAAC;gBAC/B,UAAU,EAAE,IAAI,CAAC,cAAc,IAAI,cAAc;aAClD,CAAC;SACH;KACF,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,WAAW;YAAE,OAAO;QACxB,WAAW,GAAG,IAAI,CAAC;QACnB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CACT,uBAAuB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,CACvE,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IAE9E,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { join } from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { CamelCasePlugin, Kysely, type LogConfig } from 'kysely';\nimport { KyselyPGlite } from 'kysely-pglite';\nimport { KyselyPganalyzeCommentPlugin } from '../pganalyze-comment-plugin';\nimport type { DB } from '../v1.generated';\n\nexport const root = join(__dirname, '../..');\nexport const dumpPath = join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\nexport async function useLocalKysely(args: UseLocalKyselyOptions = {}) {\n let isDestroyed = false;\n const now = performance.now();\n\n const dump = Bun.file(dumpPath);\n\n const pglite = new PGlite({ loadDataDir: dump });\n // warm up\n await pglite.sql`SELECT 1`;\n const { dialect } = new KyselyPGlite(pglite);\n const kysely = new Kysely<DB>({\n dialect,\n log: args.log === true ? ['query', 'error'] : args.log,\n plugins: [\n new CamelCasePlugin(),\n new KyselyPganalyzeCommentPlugin({\n repository: args.repositoryName ?? 'localTesting',\n }),\n ],\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n const destroyTime = performance.now();\n await originalDestroy().catch(() => undefined);\n await pglite.close().catch(() => undefined);\n console.log(\n `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n );\n };\n\n console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type DeleteQueryNode, type InsertQueryNode, OperationNodeTransformer, type RootOperationNode, type SelectQueryNode, type UpdateQueryNode } from 'kysely';
|
|
2
|
+
/**
|
|
3
|
+
* Transformer that adds a SQL comment to queries for pganalyze tracking.
|
|
4
|
+
* The comment format is: repository: REPOSITORY_NAME
|
|
5
|
+
*
|
|
6
|
+
* This works by appending the comment to queries using the endModifiers property,
|
|
7
|
+
* similar to how modifyEnd works.
|
|
8
|
+
*/
|
|
9
|
+
export declare class CommentTransformer extends OperationNodeTransformer {
|
|
10
|
+
readonly _repositoryName: string;
|
|
11
|
+
constructor(_repositoryName: string);
|
|
12
|
+
transformRootNode(node: RootOperationNode): RootOperationNode;
|
|
13
|
+
protected transformSelectQuery(node: SelectQueryNode): SelectQueryNode;
|
|
14
|
+
protected transformInsertQuery(node: InsertQueryNode): InsertQueryNode;
|
|
15
|
+
protected transformUpdateQuery(node: UpdateQueryNode): UpdateQueryNode;
|
|
16
|
+
protected transformDeleteQuery(node: DeleteQueryNode): DeleteQueryNode;
|
|
17
|
+
private addCommentToSelectQuery;
|
|
18
|
+
private addCommentToInsertQuery;
|
|
19
|
+
private addCommentToUpdateQuery;
|
|
20
|
+
private addCommentToDeleteQuery;
|
|
21
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { OperationNodeTransformer, SelectModifierNode, sql, } from 'kysely';
|
|
2
|
+
function createCommentNode(repositoryName) {
|
|
3
|
+
return SelectModifierNode.createWithExpression(sql.raw(`/* repository: ${repositoryName} */`).toOperationNode());
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Transformer that adds a SQL comment to queries for pganalyze tracking.
|
|
7
|
+
* The comment format is: repository: REPOSITORY_NAME
|
|
8
|
+
*
|
|
9
|
+
* This works by appending the comment to queries using the endModifiers property,
|
|
10
|
+
* similar to how modifyEnd works.
|
|
11
|
+
*/
|
|
12
|
+
export class CommentTransformer extends OperationNodeTransformer {
|
|
13
|
+
_repositoryName;
|
|
14
|
+
constructor(_repositoryName) {
|
|
15
|
+
super();
|
|
16
|
+
this._repositoryName = _repositoryName;
|
|
17
|
+
}
|
|
18
|
+
transformRootNode(node) {
|
|
19
|
+
if (node.kind === 'SelectQueryNode') {
|
|
20
|
+
return this.transformSelectQuery(node);
|
|
21
|
+
}
|
|
22
|
+
if (node.kind === 'InsertQueryNode') {
|
|
23
|
+
return this.transformInsertQuery(node);
|
|
24
|
+
}
|
|
25
|
+
if (node.kind === 'UpdateQueryNode') {
|
|
26
|
+
return this.transformUpdateQuery(node);
|
|
27
|
+
}
|
|
28
|
+
if (node.kind === 'DeleteQueryNode') {
|
|
29
|
+
return this.transformDeleteQuery(node);
|
|
30
|
+
}
|
|
31
|
+
return node;
|
|
32
|
+
}
|
|
33
|
+
transformSelectQuery(node) {
|
|
34
|
+
const transformed = super.transformSelectQuery(node);
|
|
35
|
+
return this.addCommentToSelectQuery(transformed);
|
|
36
|
+
}
|
|
37
|
+
transformInsertQuery(node) {
|
|
38
|
+
const transformed = super.transformInsertQuery(node);
|
|
39
|
+
return this.addCommentToInsertQuery(transformed);
|
|
40
|
+
}
|
|
41
|
+
transformUpdateQuery(node) {
|
|
42
|
+
const transformed = super.transformUpdateQuery(node);
|
|
43
|
+
return this.addCommentToUpdateQuery(transformed);
|
|
44
|
+
}
|
|
45
|
+
transformDeleteQuery(node) {
|
|
46
|
+
const transformed = super.transformDeleteQuery(node);
|
|
47
|
+
return this.addCommentToDeleteQuery(transformed);
|
|
48
|
+
}
|
|
49
|
+
addCommentToSelectQuery(node) {
|
|
50
|
+
// Append comment using endModifiers property, similar to modifyEnd
|
|
51
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
52
|
+
return {
|
|
53
|
+
...node,
|
|
54
|
+
endModifiers: node.endModifiers
|
|
55
|
+
? [...node.endModifiers, commentNode]
|
|
56
|
+
: [commentNode],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
addCommentToInsertQuery(node) {
|
|
60
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
61
|
+
return {
|
|
62
|
+
...node,
|
|
63
|
+
endModifiers: node.endModifiers
|
|
64
|
+
? [...node.endModifiers, commentNode]
|
|
65
|
+
: [commentNode],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
addCommentToUpdateQuery(node) {
|
|
69
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
70
|
+
return {
|
|
71
|
+
...node,
|
|
72
|
+
endModifiers: node.endModifiers
|
|
73
|
+
? [...node.endModifiers, commentNode]
|
|
74
|
+
: [commentNode],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
addCommentToDeleteQuery(node) {
|
|
78
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
79
|
+
return {
|
|
80
|
+
...node,
|
|
81
|
+
endModifiers: node.endModifiers
|
|
82
|
+
? [...node.endModifiers, commentNode]
|
|
83
|
+
: [commentNode],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=comment-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-transformer.js","sourceRoot":"src/","sources":["pganalyze-comment-plugin/comment-transformer.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type DeleteQueryNode,\n type InsertQueryNode,\n OperationNodeTransformer,\n type RootOperationNode,\n SelectModifierNode,\n type SelectQueryNode,\n sql,\n type UpdateQueryNode,\n} from 'kysely';\n\nfunction createCommentNode(repositoryName: string): SelectModifierNode {\n return SelectModifierNode.createWithExpression(\n sql.raw(`/* repository: ${repositoryName} */`).toOperationNode()\n );\n}\n/**\n * Transformer that adds a SQL comment to queries for pganalyze tracking.\n * The comment format is: repository: REPOSITORY_NAME\n *\n * This works by appending the comment to queries using the endModifiers property,\n * similar to how modifyEnd works.\n */\nexport class CommentTransformer extends OperationNodeTransformer {\n constructor(readonly _repositoryName: string) {\n super();\n }\n\n transformRootNode(node: RootOperationNode): RootOperationNode {\n if (node.kind === 'SelectQueryNode') {\n return this.transformSelectQuery(node);\n }\n if (node.kind === 'InsertQueryNode') {\n return this.transformInsertQuery(node);\n }\n if (node.kind === 'UpdateQueryNode') {\n return this.transformUpdateQuery(node);\n }\n if (node.kind === 'DeleteQueryNode') {\n return this.transformDeleteQuery(node);\n }\n return node;\n }\n\n protected override transformSelectQuery(\n node: SelectQueryNode\n ): SelectQueryNode {\n const transformed = super.transformSelectQuery(node);\n return this.addCommentToSelectQuery(transformed);\n }\n\n protected override transformInsertQuery(\n node: InsertQueryNode\n ): InsertQueryNode {\n const transformed = super.transformInsertQuery(node);\n return this.addCommentToInsertQuery(transformed);\n }\n\n protected override transformUpdateQuery(\n node: UpdateQueryNode\n ): UpdateQueryNode {\n const transformed = super.transformUpdateQuery(node);\n return this.addCommentToUpdateQuery(transformed);\n }\n\n protected override transformDeleteQuery(\n node: DeleteQueryNode\n ): DeleteQueryNode {\n const transformed = super.transformDeleteQuery(node);\n return this.addCommentToDeleteQuery(transformed);\n }\n\n private addCommentToSelectQuery(node: SelectQueryNode): SelectQueryNode {\n // Append comment using endModifiers property, similar to modifyEnd\n const commentNode = createCommentNode(this._repositoryName);\n\n return {\n ...node,\n endModifiers: node.endModifiers\n ? [...node.endModifiers, commentNode]\n : [commentNode],\n };\n }\n\n private addCommentToInsertQuery(node: InsertQueryNode): InsertQueryNode {\n const commentNode = createCommentNode(this._repositoryName);\n\n return {\n ...node,\n endModifiers: node.endModifiers\n ? [...node.endModifiers, commentNode]\n : [commentNode],\n };\n }\n\n private addCommentToUpdateQuery(node: UpdateQueryNode): UpdateQueryNode {\n const commentNode = createCommentNode(this._repositoryName);\n\n return {\n ...node,\n endModifiers: node.endModifiers\n ? [...node.endModifiers, commentNode]\n : [commentNode],\n };\n }\n\n private addCommentToDeleteQuery(node: DeleteQueryNode): DeleteQueryNode {\n const commentNode = createCommentNode(this._repositoryName);\n\n return {\n ...node,\n endModifiers: node.endModifiers\n ? [...node.endModifiers, commentNode]\n : [commentNode],\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs, QueryResult, RootOperationNode, UnknownRow } from 'kysely';
|
|
2
|
+
export declare class KyselyPganalyzeCommentPlugin implements KyselyPlugin {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(options: {
|
|
5
|
+
repository: string;
|
|
6
|
+
});
|
|
7
|
+
transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
|
|
8
|
+
transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CommentTransformer } from './comment-transformer';
|
|
2
|
+
export class KyselyPganalyzeCommentPlugin {
|
|
3
|
+
#transformer;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.#transformer = new CommentTransformer(options.repository);
|
|
6
|
+
}
|
|
7
|
+
transformQuery(args) {
|
|
8
|
+
return this.#transformer.transformRootNode(args.node);
|
|
9
|
+
}
|
|
10
|
+
async transformResult(args) {
|
|
11
|
+
return args.result;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["pganalyze-comment-plugin/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,OAAO,4BAA4B;IAC9B,YAAY,CAAqB;IAE1C,YAAY,OAA+B;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,IAA+B;QAE/B,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF","sourcesContent":["import type {\n KyselyPlugin,\n PluginTransformQueryArgs,\n PluginTransformResultArgs,\n QueryResult,\n RootOperationNode,\n UnknownRow,\n} from 'kysely';\nimport { CommentTransformer } from './comment-transformer';\n\nexport class KyselyPganalyzeCommentPlugin implements KyselyPlugin {\n readonly #transformer: CommentTransformer;\n\n constructor(options: { repository: string }) {\n this.#transformer = new CommentTransformer(options.repository);\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n return this.#transformer.transformRootNode(args.node);\n }\n\n async transformResult(\n args: PluginTransformResultArgs\n ): Promise<QueryResult<UnknownRow>> {\n return args.result;\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { type UseLocalKyselyOptions } from '../local';
|
|
3
|
+
import type { DB } from '../v1.generated';
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Use `useLocalKyselyResource` instead.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useTestKysely(cleanupStrategy: 'afterAll', args?: UseLocalKyselyOptions): Promise<{
|
|
8
|
+
kysely: Kysely<DB>;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function useTestAutoCleanupKysely(args?: UseLocalKyselyOptions): Promise<Kysely<DB>>;
|
|
11
|
+
type ReturnType = Kysely<DB> & {
|
|
12
|
+
[Symbol.dispose]: () => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export declare function useLocalKyselyResource(args?: UseLocalKyselyOptions): Promise<ReturnType>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { afterAll } from 'bun:test';
|
|
2
|
+
import { useLocalKysely } from '../local';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use `useLocalKyselyResource` instead.
|
|
5
|
+
*/
|
|
6
|
+
export async function useTestKysely(cleanupStrategy, args) {
|
|
7
|
+
const kysely = await useLocalKysely(args);
|
|
8
|
+
if (cleanupStrategy === 'afterAll')
|
|
9
|
+
afterAll(async () => {
|
|
10
|
+
await kysely.destroy();
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
kysely,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export async function useTestAutoCleanupKysely(args) {
|
|
17
|
+
const kysely = await useLocalKysely(args);
|
|
18
|
+
afterAll(async () => {
|
|
19
|
+
await kysely.destroy();
|
|
20
|
+
});
|
|
21
|
+
return kysely;
|
|
22
|
+
}
|
|
23
|
+
export async function useLocalKyselyResource(args) {
|
|
24
|
+
const kysely = await useLocalKysely(args);
|
|
25
|
+
return new Proxy({}, {
|
|
26
|
+
get(_target, prop) {
|
|
27
|
+
if (prop === Symbol.dispose) {
|
|
28
|
+
return async () => {
|
|
29
|
+
await kysely.destroy();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (prop === 'kysely') {
|
|
33
|
+
return kysely;
|
|
34
|
+
}
|
|
35
|
+
if (typeof kysely[prop] === 'function') {
|
|
36
|
+
return kysely[prop].bind(kysely);
|
|
37
|
+
}
|
|
38
|
+
return kysely[prop];
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAA8B,cAAc,EAAE,MAAM,UAAU,CAAC;AAGtE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,eAA2B,EAC3B,IAA4B;IAE5B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE1C,IAAI,eAAe,KAAK,UAAU;QAChC,QAAQ,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAA4B;IACzE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE1C,QAAQ,CAAC,KAAK,IAAI,EAAE;QAClB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAA4B;IAE5B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE1C,OAAO,IAAI,KAAK,CACd,EAAE,EACF;QACE,GAAG,CAAC,OAAO,EAAE,IAAI;YACf,IAAI,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC5B,OAAO,KAAK,IAAI,EAAE;oBAChB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;gBACzB,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;gBACvC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CACY,CAAC;AAClB,CAAC","sourcesContent":["import { afterAll } from 'bun:test';\nimport type { Kysely } from 'kysely';\nimport { type UseLocalKyselyOptions, useLocalKysely } from '../local';\nimport type { DB } from '../v1.generated';\n\n/**\n * @deprecated Use `useLocalKyselyResource` instead.\n */\nexport async function useTestKysely(\n cleanupStrategy: 'afterAll',\n args?: UseLocalKyselyOptions\n) {\n const kysely = await useLocalKysely(args);\n\n if (cleanupStrategy === 'afterAll')\n afterAll(async () => {\n await kysely.destroy();\n });\n\n return {\n kysely,\n };\n}\n\nexport async function useTestAutoCleanupKysely(args?: UseLocalKyselyOptions) {\n const kysely = await useLocalKysely(args);\n\n afterAll(async () => {\n await kysely.destroy();\n });\n\n return kysely;\n}\n\ntype ReturnType = Kysely<DB> & {\n [Symbol.dispose]: () => Promise<void>;\n};\n\nexport async function useLocalKyselyResource(\n args?: UseLocalKyselyOptions\n): Promise<ReturnType> {\n const kysely = await useLocalKysely(args);\n\n return new Proxy(\n {},\n {\n get(_target, prop) {\n if (prop === Symbol.dispose) {\n return async () => {\n await kysely.destroy();\n };\n }\n if (prop === 'kysely') {\n return kysely;\n }\n if (typeof kysely[prop] === 'function') {\n return kysely[prop].bind(kysely);\n }\n return kysely[prop];\n },\n }\n ) as ReturnType;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../../src/index.ts","../../src/
|
|
1
|
+
{"root":["../../src/index.ts","../../src/v1.generated.ts","../../src/local/generate.ts","../../src/local/index.ts","../../src/pganalyze-comment-plugin/comment-transformer.ts","../../src/pganalyze-comment-plugin/index.ts","../../src/test/index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { serializeError } from '@finalytic/utils';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CamelCasePlugin,
|
|
4
|
+
Kysely as K,
|
|
5
|
+
type KyselyPlugin,
|
|
6
|
+
type LogConfig,
|
|
7
|
+
type Transaction as T,
|
|
8
|
+
} from 'kysely';
|
|
3
9
|
import { PostgresJSDialect } from 'kysely-postgres-js';
|
|
4
10
|
import postgres, { type Sql } from 'postgres';
|
|
5
11
|
|
|
@@ -21,11 +27,17 @@ export { jsonArrayFrom } from 'kysely/helpers/postgres';
|
|
|
21
27
|
export * from './v1.generated';
|
|
22
28
|
|
|
23
29
|
import { join, relative } from 'node:path';
|
|
30
|
+
import { KyselyPganalyzeCommentPlugin } from './pganalyze-comment-plugin';
|
|
24
31
|
import type { DB } from './v1.generated';
|
|
25
32
|
|
|
26
33
|
export type Transaction = T<DB>;
|
|
27
34
|
export { sql } from 'kysely';
|
|
28
35
|
|
|
36
|
+
type KyselyOpts = {
|
|
37
|
+
repositoryName?: string;
|
|
38
|
+
log?: true | LogConfig;
|
|
39
|
+
};
|
|
40
|
+
|
|
29
41
|
type PgOpt = {
|
|
30
42
|
forceDisableSSL?: boolean;
|
|
31
43
|
retries?: false | number;
|
|
@@ -36,14 +48,22 @@ export type Postgres = Sql;
|
|
|
36
48
|
/**
|
|
37
49
|
* @deprecated This method is deprecated in favor of the useAsyncKysely method.
|
|
38
50
|
*/
|
|
39
|
-
export function useKysely(postgres: Sql, options
|
|
51
|
+
export function useKysely(postgres: Sql, options?: KyselyOpts) {
|
|
40
52
|
console.debug('Creating Kysely instance');
|
|
53
|
+
const plugins: KyselyPlugin[] = [new CamelCasePlugin()];
|
|
54
|
+
if (options?.repositoryName) {
|
|
55
|
+
plugins.push(
|
|
56
|
+
new KyselyPganalyzeCommentPlugin({
|
|
57
|
+
repository: options.repositoryName,
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
41
61
|
const kysely = new K<DB>({
|
|
42
62
|
dialect: new PostgresJSDialect({
|
|
43
63
|
postgres,
|
|
44
64
|
}),
|
|
45
|
-
plugins
|
|
46
|
-
log: options?.log ? ['query', 'error'] :
|
|
65
|
+
plugins,
|
|
66
|
+
log: options?.log === true ? ['query', 'error'] : options?.log,
|
|
47
67
|
});
|
|
48
68
|
|
|
49
69
|
kysely.destroy = async () => {
|
|
@@ -78,8 +98,8 @@ export async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {
|
|
|
78
98
|
ssl: ssl ? 'require' : false,
|
|
79
99
|
// connect_timeout: 10
|
|
80
100
|
// idle_timeout: 10
|
|
81
|
-
//
|
|
82
|
-
prepare:
|
|
101
|
+
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
102
|
+
prepare: true,
|
|
83
103
|
connect_timeout: 10,
|
|
84
104
|
idle_timeout: 60,
|
|
85
105
|
});
|
|
@@ -107,9 +127,12 @@ export async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {
|
|
|
107
127
|
throw new Error('Unable to connect to Postgres');
|
|
108
128
|
}
|
|
109
129
|
|
|
110
|
-
export async function useAsyncKysely(
|
|
130
|
+
export async function useAsyncKysely(
|
|
131
|
+
connectionString: string,
|
|
132
|
+
opt?: PgOpt & KyselyOpts
|
|
133
|
+
) {
|
|
111
134
|
const sql = await useAsyncPostgres(connectionString, opt);
|
|
112
|
-
return useKysely(sql);
|
|
135
|
+
return useKysely(sql, opt);
|
|
113
136
|
}
|
|
114
137
|
|
|
115
138
|
/**
|
package/src/local/index.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { PGlite } from '@electric-sql/pglite';
|
|
3
|
-
import { CamelCasePlugin, Kysely } from 'kysely';
|
|
3
|
+
import { CamelCasePlugin, Kysely, type LogConfig } from 'kysely';
|
|
4
4
|
import { KyselyPGlite } from 'kysely-pglite';
|
|
5
|
+
import { KyselyPganalyzeCommentPlugin } from '../pganalyze-comment-plugin';
|
|
5
6
|
import type { DB } from '../v1.generated';
|
|
6
7
|
|
|
7
8
|
export const root = join(__dirname, '../..');
|
|
8
9
|
export const dumpPath = join(root, '.data.tar');
|
|
9
10
|
|
|
10
|
-
export
|
|
11
|
+
export type UseLocalKyselyOptions = {
|
|
12
|
+
repositoryName?: string;
|
|
13
|
+
log?: true | LogConfig;
|
|
14
|
+
};
|
|
15
|
+
export async function useLocalKysely(args: UseLocalKyselyOptions = {}) {
|
|
11
16
|
let isDestroyed = false;
|
|
12
17
|
const now = performance.now();
|
|
13
18
|
|
|
@@ -19,7 +24,13 @@ export async function useLocalKysely() {
|
|
|
19
24
|
const { dialect } = new KyselyPGlite(pglite);
|
|
20
25
|
const kysely = new Kysely<DB>({
|
|
21
26
|
dialect,
|
|
22
|
-
|
|
27
|
+
log: args.log === true ? ['query', 'error'] : args.log,
|
|
28
|
+
plugins: [
|
|
29
|
+
new CamelCasePlugin(),
|
|
30
|
+
new KyselyPganalyzeCommentPlugin({
|
|
31
|
+
repository: args.repositoryName ?? 'localTesting',
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
23
34
|
});
|
|
24
35
|
|
|
25
36
|
const originalDestroy = kysely.destroy.bind(kysely);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type DeleteQueryNode,
|
|
3
|
+
type InsertQueryNode,
|
|
4
|
+
OperationNodeTransformer,
|
|
5
|
+
type RootOperationNode,
|
|
6
|
+
SelectModifierNode,
|
|
7
|
+
type SelectQueryNode,
|
|
8
|
+
sql,
|
|
9
|
+
type UpdateQueryNode,
|
|
10
|
+
} from 'kysely';
|
|
11
|
+
|
|
12
|
+
function createCommentNode(repositoryName: string): SelectModifierNode {
|
|
13
|
+
return SelectModifierNode.createWithExpression(
|
|
14
|
+
sql.raw(`/* repository: ${repositoryName} */`).toOperationNode()
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Transformer that adds a SQL comment to queries for pganalyze tracking.
|
|
19
|
+
* The comment format is: repository: REPOSITORY_NAME
|
|
20
|
+
*
|
|
21
|
+
* This works by appending the comment to queries using the endModifiers property,
|
|
22
|
+
* similar to how modifyEnd works.
|
|
23
|
+
*/
|
|
24
|
+
export class CommentTransformer extends OperationNodeTransformer {
|
|
25
|
+
constructor(readonly _repositoryName: string) {
|
|
26
|
+
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
transformRootNode(node: RootOperationNode): RootOperationNode {
|
|
30
|
+
if (node.kind === 'SelectQueryNode') {
|
|
31
|
+
return this.transformSelectQuery(node);
|
|
32
|
+
}
|
|
33
|
+
if (node.kind === 'InsertQueryNode') {
|
|
34
|
+
return this.transformInsertQuery(node);
|
|
35
|
+
}
|
|
36
|
+
if (node.kind === 'UpdateQueryNode') {
|
|
37
|
+
return this.transformUpdateQuery(node);
|
|
38
|
+
}
|
|
39
|
+
if (node.kind === 'DeleteQueryNode') {
|
|
40
|
+
return this.transformDeleteQuery(node);
|
|
41
|
+
}
|
|
42
|
+
return node;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected override transformSelectQuery(
|
|
46
|
+
node: SelectQueryNode
|
|
47
|
+
): SelectQueryNode {
|
|
48
|
+
const transformed = super.transformSelectQuery(node);
|
|
49
|
+
return this.addCommentToSelectQuery(transformed);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected override transformInsertQuery(
|
|
53
|
+
node: InsertQueryNode
|
|
54
|
+
): InsertQueryNode {
|
|
55
|
+
const transformed = super.transformInsertQuery(node);
|
|
56
|
+
return this.addCommentToInsertQuery(transformed);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected override transformUpdateQuery(
|
|
60
|
+
node: UpdateQueryNode
|
|
61
|
+
): UpdateQueryNode {
|
|
62
|
+
const transformed = super.transformUpdateQuery(node);
|
|
63
|
+
return this.addCommentToUpdateQuery(transformed);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected override transformDeleteQuery(
|
|
67
|
+
node: DeleteQueryNode
|
|
68
|
+
): DeleteQueryNode {
|
|
69
|
+
const transformed = super.transformDeleteQuery(node);
|
|
70
|
+
return this.addCommentToDeleteQuery(transformed);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private addCommentToSelectQuery(node: SelectQueryNode): SelectQueryNode {
|
|
74
|
+
// Append comment using endModifiers property, similar to modifyEnd
|
|
75
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
...node,
|
|
79
|
+
endModifiers: node.endModifiers
|
|
80
|
+
? [...node.endModifiers, commentNode]
|
|
81
|
+
: [commentNode],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private addCommentToInsertQuery(node: InsertQueryNode): InsertQueryNode {
|
|
86
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
...node,
|
|
90
|
+
endModifiers: node.endModifiers
|
|
91
|
+
? [...node.endModifiers, commentNode]
|
|
92
|
+
: [commentNode],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private addCommentToUpdateQuery(node: UpdateQueryNode): UpdateQueryNode {
|
|
97
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
...node,
|
|
101
|
+
endModifiers: node.endModifiers
|
|
102
|
+
? [...node.endModifiers, commentNode]
|
|
103
|
+
: [commentNode],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private addCommentToDeleteQuery(node: DeleteQueryNode): DeleteQueryNode {
|
|
108
|
+
const commentNode = createCommentNode(this._repositoryName);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...node,
|
|
112
|
+
endModifiers: node.endModifiers
|
|
113
|
+
? [...node.endModifiers, commentNode]
|
|
114
|
+
: [commentNode],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
KyselyPlugin,
|
|
3
|
+
PluginTransformQueryArgs,
|
|
4
|
+
PluginTransformResultArgs,
|
|
5
|
+
QueryResult,
|
|
6
|
+
RootOperationNode,
|
|
7
|
+
UnknownRow,
|
|
8
|
+
} from 'kysely';
|
|
9
|
+
import { CommentTransformer } from './comment-transformer';
|
|
10
|
+
|
|
11
|
+
export class KyselyPganalyzeCommentPlugin implements KyselyPlugin {
|
|
12
|
+
readonly #transformer: CommentTransformer;
|
|
13
|
+
|
|
14
|
+
constructor(options: { repository: string }) {
|
|
15
|
+
this.#transformer = new CommentTransformer(options.repository);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
|
|
19
|
+
return this.#transformer.transformRootNode(args.node);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async transformResult(
|
|
23
|
+
args: PluginTransformResultArgs
|
|
24
|
+
): Promise<QueryResult<UnknownRow>> {
|
|
25
|
+
return args.result;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { afterAll } from 'bun:test';
|
|
2
|
+
import type { Kysely } from 'kysely';
|
|
3
|
+
import { type UseLocalKyselyOptions, useLocalKysely } from '../local';
|
|
4
|
+
import type { DB } from '../v1.generated';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use `useLocalKyselyResource` instead.
|
|
8
|
+
*/
|
|
9
|
+
export async function useTestKysely(
|
|
10
|
+
cleanupStrategy: 'afterAll',
|
|
11
|
+
args?: UseLocalKyselyOptions
|
|
12
|
+
) {
|
|
13
|
+
const kysely = await useLocalKysely(args);
|
|
14
|
+
|
|
15
|
+
if (cleanupStrategy === 'afterAll')
|
|
16
|
+
afterAll(async () => {
|
|
17
|
+
await kysely.destroy();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
kysely,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function useTestAutoCleanupKysely(args?: UseLocalKyselyOptions) {
|
|
26
|
+
const kysely = await useLocalKysely(args);
|
|
27
|
+
|
|
28
|
+
afterAll(async () => {
|
|
29
|
+
await kysely.destroy();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return kysely;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type ReturnType = Kysely<DB> & {
|
|
36
|
+
[Symbol.dispose]: () => Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export async function useLocalKyselyResource(
|
|
40
|
+
args?: UseLocalKyselyOptions
|
|
41
|
+
): Promise<ReturnType> {
|
|
42
|
+
const kysely = await useLocalKysely(args);
|
|
43
|
+
|
|
44
|
+
return new Proxy(
|
|
45
|
+
{},
|
|
46
|
+
{
|
|
47
|
+
get(_target, prop) {
|
|
48
|
+
if (prop === Symbol.dispose) {
|
|
49
|
+
return async () => {
|
|
50
|
+
await kysely.destroy();
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (prop === 'kysely') {
|
|
54
|
+
return kysely;
|
|
55
|
+
}
|
|
56
|
+
if (typeof kysely[prop] === 'function') {
|
|
57
|
+
return kysely[prop].bind(kysely);
|
|
58
|
+
}
|
|
59
|
+
return kysely[prop];
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
) as ReturnType;
|
|
63
|
+
}
|
package/src/test.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { afterAll } from 'bun:test';
|
|
2
|
-
import { useLocalKysely } from './local';
|
|
3
|
-
|
|
4
|
-
export async function useTestKysely(
|
|
5
|
-
cleanupStrategy: 'afterAll' | 'using' | 'manual'
|
|
6
|
-
) {
|
|
7
|
-
const kysely = await useLocalKysely();
|
|
8
|
-
|
|
9
|
-
if (cleanupStrategy === 'afterAll')
|
|
10
|
-
afterAll(async () => {
|
|
11
|
-
await kysely.destroy();
|
|
12
|
-
});
|
|
13
|
-
return {
|
|
14
|
-
kysely,
|
|
15
|
-
[Symbol.dispose]: async () => {
|
|
16
|
-
await kysely.destroy();
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
}
|