@dbx-tools/cli 0.9.58 → 0.9.61
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/README.md +594 -57
- package/bin/dbx-genie.ts +13 -0
- package/bin/dbx-graphiti.ts +5 -0
- package/bin/dbx-lakebase-proxy.ts +4 -0
- package/bin/dbx-model-gateway.ts +5 -0
- package/index.ts +47 -1
- package/lib/bin/dbx-genie.d.ts +2 -0
- package/lib/bin/dbx-genie.js +10 -0
- package/lib/bin/dbx-graphiti.d.ts +2 -0
- package/lib/bin/dbx-graphiti.js +4 -0
- package/lib/bin/dbx-lakebase-proxy.d.ts +2 -0
- package/lib/bin/dbx-lakebase-proxy.js +4 -0
- package/lib/bin/dbx-model-gateway.d.ts +2 -0
- package/lib/bin/dbx-model-gateway.js +4 -0
- package/lib/index.d.ts +47 -1
- package/lib/index.js +34 -2
- package/lib/src/appkit/cli.d.ts +24 -0
- package/lib/src/appkit/cli.js +54 -0
- package/lib/src/appkit/env-export.d.ts +40 -0
- package/lib/src/appkit/env-export.js +99 -0
- package/lib/src/auth/cli.d.ts +20 -0
- package/lib/src/auth/cli.js +129 -0
- package/lib/src/auth/options.d.ts +45 -0
- package/lib/src/auth/options.js +68 -0
- package/lib/src/cli.d.ts +2 -0
- package/lib/src/cli.js +19 -9
- package/lib/src/genie-code/cli.d.ts +19 -0
- package/lib/src/genie-code/cli.js +36 -0
- package/lib/src/genie-code/config.d.ts +38 -0
- package/lib/src/genie-code/config.js +111 -0
- package/lib/src/genie-code/install.d.ts +21 -0
- package/lib/src/genie-code/install.js +69 -0
- package/lib/src/genie-code/options.d.ts +7 -0
- package/lib/src/genie-code/options.js +7 -0
- package/lib/src/genie-code/runner.d.ts +21 -0
- package/lib/src/genie-code/runner.js +90 -0
- package/lib/src/genie-code/runtime.d.ts +48 -0
- package/lib/src/genie-code/runtime.js +162 -0
- package/lib/src/graphiti/cli.d.ts +18 -0
- package/lib/src/graphiti/cli.js +43 -0
- package/lib/src/graphiti/options.d.ts +10 -0
- package/lib/src/graphiti/options.js +10 -0
- package/lib/src/lakebase-proxy/cancellation.d.ts +22 -0
- package/lib/src/lakebase-proxy/cancellation.js +100 -0
- package/lib/src/lakebase-proxy/cli.d.ts +13 -0
- package/lib/src/lakebase-proxy/cli.js +54 -0
- package/lib/src/lakebase-proxy/options.d.ts +23 -0
- package/lib/src/lakebase-proxy/options.js +41 -0
- package/lib/src/lakebase-proxy/protocol.d.ts +37 -0
- package/lib/src/lakebase-proxy/protocol.js +124 -0
- package/lib/src/lakebase-proxy/proxy.d.ts +22 -0
- package/lib/src/lakebase-proxy/proxy.js +200 -0
- package/lib/src/model-gateway/cli.d.ts +19 -0
- package/lib/src/model-gateway/cli.js +63 -0
- package/lib/src/model-gateway/server.d.ts +16 -0
- package/lib/src/model-gateway/server.js +83 -0
- package/lib/src/tunnel/app.d.ts +20 -0
- package/lib/src/tunnel/app.js +52 -0
- package/lib/src/tunnel/cli.d.ts +27 -0
- package/lib/src/tunnel/cli.js +190 -0
- package/lib/src/tunnel/options.d.ts +72 -0
- package/lib/src/tunnel/options.js +138 -0
- package/lib/src/tunnel/proxy.d.ts +51 -0
- package/lib/src/tunnel/proxy.js +143 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +146 -9
- package/src/appkit/cli.ts +72 -0
- package/src/appkit/env-export.ts +124 -0
- package/src/auth/cli.ts +175 -0
- package/src/auth/options.ts +83 -0
- package/src/cli.ts +35 -8
- package/src/genie-code/cli.ts +58 -0
- package/src/genie-code/config.ts +161 -0
- package/src/genie-code/install.ts +103 -0
- package/src/genie-code/options.ts +14 -0
- package/src/genie-code/runner.ts +106 -0
- package/src/genie-code/runtime.ts +212 -0
- package/src/graphiti/cli.ts +75 -0
- package/src/graphiti/options.ts +20 -0
- package/src/lakebase-proxy/cancellation.ts +116 -0
- package/src/lakebase-proxy/cli.ts +80 -0
- package/src/lakebase-proxy/options.ts +56 -0
- package/src/lakebase-proxy/protocol.ts +170 -0
- package/src/lakebase-proxy/proxy.ts +256 -0
- package/src/model-gateway/cli.ts +93 -0
- package/src/model-gateway/server.ts +94 -0
- package/src/tunnel/app.ts +58 -0
- package/src/tunnel/cli.ts +218 -0
- package/src/tunnel/options.ts +169 -0
- package/src/tunnel/proxy.ts +194 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type CliServiceCliDependencies } from "@dbx-tools/cli-service/cli";
|
|
2
|
+
import { type CliServiceDefinition } from "@dbx-tools/cli-service/definition";
|
|
3
|
+
import { type GraphitiRuntimeOptions } from "@dbx-tools/graphiti/runtime";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { type GraphitiOptions } from "./options.ts";
|
|
6
|
+
/** Injectable runtime and service lifecycle boundaries for CLI callers. */
|
|
7
|
+
export interface GraphitiCliDependencies {
|
|
8
|
+
/** Run the Graphiti stack through the Node runtime owner. */
|
|
9
|
+
run(options: GraphitiRuntimeOptions): Promise<void>;
|
|
10
|
+
/** Shared service command dependencies for tests and embedding. */
|
|
11
|
+
readonly service?: CliServiceCliDependencies;
|
|
12
|
+
}
|
|
13
|
+
/** Runtime options persisted when installing the Graphiti desktop service. */
|
|
14
|
+
export type GraphitiServiceOptions = GraphitiOptions;
|
|
15
|
+
/** Define a Graphiti service without duplicating installation or lifecycle policy. */
|
|
16
|
+
export declare function graphitiServiceDefinition(options?: GraphitiServiceOptions): CliServiceDefinition;
|
|
17
|
+
/** Build foreground execution and shared desktop-service commands. */
|
|
18
|
+
export declare function buildProgram(name?: string, dependencies?: GraphitiCliDependencies): Command;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commander-owned Graphiti CLI and shared current-user service definition.
|
|
3
|
+
*
|
|
4
|
+
* This module owns every user-facing Graphiti command. The shared Graphiti Zod
|
|
5
|
+
* schema owns its options, environment names, defaults, and validation. The
|
|
6
|
+
* Node Graphiti package owns runtime and Python interaction.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { addArgs, parseArgs, serializeArgs } from "@dbx-tools/cli-args";
|
|
11
|
+
import { buildServiceCommand } from "@dbx-tools/cli-service/cli";
|
|
12
|
+
import { defineService } from "@dbx-tools/cli-service/definition";
|
|
13
|
+
import { runGraphiti } from "@dbx-tools/graphiti/runtime";
|
|
14
|
+
import { Command } from "commander";
|
|
15
|
+
import { PACKAGE_VERSION } from "../../index.js";
|
|
16
|
+
import { GraphitiCliOptionsSchema, GraphitiOptionsSchema, } from "./options.js";
|
|
17
|
+
/** Define a Graphiti service without duplicating installation or lifecycle policy. */
|
|
18
|
+
export function graphitiServiceDefinition(options = {}) {
|
|
19
|
+
return defineService(import.meta.url, {
|
|
20
|
+
id: "dbx-tools.cli-graphiti",
|
|
21
|
+
name: "dbx graphiti",
|
|
22
|
+
pythonPackage: { name: "dbx-tools-graphiti" },
|
|
23
|
+
command: {
|
|
24
|
+
binName: "dbx-graphiti",
|
|
25
|
+
arguments: serializeArgs(GraphitiOptionsSchema.parse(options)),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Build foreground execution and shared desktop-service commands. */
|
|
30
|
+
export function buildProgram(name = "dbx graphiti", dependencies = { run: runGraphiti }) {
|
|
31
|
+
const program = addArgs(new Command()
|
|
32
|
+
.name(name)
|
|
33
|
+
.description("Run Graphiti or manage its current-user desktop service")
|
|
34
|
+
.version(PACKAGE_VERSION, "-v, --version"), GraphitiCliOptionsSchema).action(async () => {
|
|
35
|
+
await dependencies.run(graphitiOptions(program));
|
|
36
|
+
});
|
|
37
|
+
program.addCommand(buildServiceCommand(() => graphitiServiceDefinition(graphitiOptions(program)), dependencies.service));
|
|
38
|
+
return program;
|
|
39
|
+
}
|
|
40
|
+
function graphitiOptions(command) {
|
|
41
|
+
return GraphitiOptionsSchema.parse(parseArgs(command, GraphitiCliOptionsSchema));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2dyYXBoaXRpL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxtQkFBbUIsRUFBa0MsTUFBTSw0QkFBNEIsQ0FBQztBQUNqRyxPQUFPLEVBQUUsYUFBYSxFQUE2QixNQUFNLG1DQUFtQyxDQUFDO0FBQzdGLE9BQU8sRUFBRSxXQUFXLEVBQStCLE1BQU0sNkJBQTZCLENBQUM7QUFDdkYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVwQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixxQkFBcUIsR0FFdEIsTUFBTSxjQUFjLENBQUM7QUFhdEIsc0ZBQXNGO0FBQ3RGLE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsVUFBa0MsRUFBRTtJQUVwQyxPQUFPLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUNwQyxFQUFFLEVBQUUsd0JBQXdCO1FBQzVCLElBQUksRUFBRSxjQUFjO1FBQ3BCLGFBQWEsRUFBRSxFQUFFLElBQUksRUFBRSxvQkFBb0IsRUFBRTtRQUM3QyxPQUFPLEVBQUU7WUFDUCxPQUFPLEVBQUUsY0FBYztZQUN2QixTQUFTLEVBQUUsYUFBYSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMvRDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxzRUFBc0U7QUFDdEUsTUFBTSxVQUFVLFlBQVksQ0FDMUIsSUFBSSxHQUFHLGNBQWMsRUFDckIsZUFBd0MsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFO0lBRTVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FDckIsSUFBSSxPQUFPLEVBQUU7U0FDVixJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ1YsV0FBVyxDQUFDLHlEQUF5RCxDQUFDO1NBQ3RFLE9BQU8sQ0FBQyxlQUFlLEVBQUUsZUFBZSxDQUFDLEVBQzVDLHdCQUF3QixDQUN6QixDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNsQixNQUFNLFlBQVksQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLENBQUMsVUFBVSxDQUNoQixtQkFBbUIsQ0FDakIsR0FBRyxFQUFFLENBQUMseUJBQXlCLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQ3pELFlBQVksQ0FBQyxPQUFPLENBQ3JCLENBQ0YsQ0FBQztJQUNGLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxPQUFnQjtJQUN2QyxPQUFPLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLHdCQUF3QixDQUFDLENBQUMsQ0FBQztBQUNuRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb21tYW5kZXItb3duZWQgR3JhcGhpdGkgQ0xJIGFuZCBzaGFyZWQgY3VycmVudC11c2VyIHNlcnZpY2UgZGVmaW5pdGlvbi5cbiAqXG4gKiBUaGlzIG1vZHVsZSBvd25zIGV2ZXJ5IHVzZXItZmFjaW5nIEdyYXBoaXRpIGNvbW1hbmQuIFRoZSBzaGFyZWQgR3JhcGhpdGkgWm9kXG4gKiBzY2hlbWEgb3ducyBpdHMgb3B0aW9ucywgZW52aXJvbm1lbnQgbmFtZXMsIGRlZmF1bHRzLCBhbmQgdmFsaWRhdGlvbi4gVGhlXG4gKiBOb2RlIEdyYXBoaXRpIHBhY2thZ2Ugb3ducyBydW50aW1lIGFuZCBQeXRob24gaW50ZXJhY3Rpb24uXG4gKlxuICogQG1vZHVsZVxuICovXG5pbXBvcnQgeyBhZGRBcmdzLCBwYXJzZUFyZ3MsIHNlcmlhbGl6ZUFyZ3MgfSBmcm9tIFwiQGRieC10b29scy9jbGktYXJnc1wiO1xuaW1wb3J0IHsgYnVpbGRTZXJ2aWNlQ29tbWFuZCwgdHlwZSBDbGlTZXJ2aWNlQ2xpRGVwZW5kZW5jaWVzIH0gZnJvbSBcIkBkYngtdG9vbHMvY2xpLXNlcnZpY2UvY2xpXCI7XG5pbXBvcnQgeyBkZWZpbmVTZXJ2aWNlLCB0eXBlIENsaVNlcnZpY2VEZWZpbml0aW9uIH0gZnJvbSBcIkBkYngtdG9vbHMvY2xpLXNlcnZpY2UvZGVmaW5pdGlvblwiO1xuaW1wb3J0IHsgcnVuR3JhcGhpdGksIHR5cGUgR3JhcGhpdGlSdW50aW1lT3B0aW9ucyB9IGZyb20gXCJAZGJ4LXRvb2xzL2dyYXBoaXRpL3J1bnRpbWVcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5cbmltcG9ydCB7IFBBQ0tBR0VfVkVSU0lPTiB9IGZyb20gXCIuLi8uLi9pbmRleC50c1wiO1xuaW1wb3J0IHtcbiAgR3JhcGhpdGlDbGlPcHRpb25zU2NoZW1hLFxuICBHcmFwaGl0aU9wdGlvbnNTY2hlbWEsXG4gIHR5cGUgR3JhcGhpdGlPcHRpb25zLFxufSBmcm9tIFwiLi9vcHRpb25zLnRzXCI7XG5cbi8qKiBJbmplY3RhYmxlIHJ1bnRpbWUgYW5kIHNlcnZpY2UgbGlmZWN5Y2xlIGJvdW5kYXJpZXMgZm9yIENMSSBjYWxsZXJzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcmFwaGl0aUNsaURlcGVuZGVuY2llcyB7XG4gIC8qKiBSdW4gdGhlIEdyYXBoaXRpIHN0YWNrIHRocm91Z2ggdGhlIE5vZGUgcnVudGltZSBvd25lci4gKi9cbiAgcnVuKG9wdGlvbnM6IEdyYXBoaXRpUnVudGltZU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+O1xuICAvKiogU2hhcmVkIHNlcnZpY2UgY29tbWFuZCBkZXBlbmRlbmNpZXMgZm9yIHRlc3RzIGFuZCBlbWJlZGRpbmcuICovXG4gIHJlYWRvbmx5IHNlcnZpY2U/OiBDbGlTZXJ2aWNlQ2xpRGVwZW5kZW5jaWVzO1xufVxuXG4vKiogUnVudGltZSBvcHRpb25zIHBlcnNpc3RlZCB3aGVuIGluc3RhbGxpbmcgdGhlIEdyYXBoaXRpIGRlc2t0b3Agc2VydmljZS4gKi9cbmV4cG9ydCB0eXBlIEdyYXBoaXRpU2VydmljZU9wdGlvbnMgPSBHcmFwaGl0aU9wdGlvbnM7XG5cbi8qKiBEZWZpbmUgYSBHcmFwaGl0aSBzZXJ2aWNlIHdpdGhvdXQgZHVwbGljYXRpbmcgaW5zdGFsbGF0aW9uIG9yIGxpZmVjeWNsZSBwb2xpY3kuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JhcGhpdGlTZXJ2aWNlRGVmaW5pdGlvbihcbiAgb3B0aW9uczogR3JhcGhpdGlTZXJ2aWNlT3B0aW9ucyA9IHt9LFxuKTogQ2xpU2VydmljZURlZmluaXRpb24ge1xuICByZXR1cm4gZGVmaW5lU2VydmljZShpbXBvcnQubWV0YS51cmwsIHtcbiAgICBpZDogXCJkYngtdG9vbHMuY2xpLWdyYXBoaXRpXCIsXG4gICAgbmFtZTogXCJkYnggZ3JhcGhpdGlcIixcbiAgICBweXRob25QYWNrYWdlOiB7IG5hbWU6IFwiZGJ4LXRvb2xzLWdyYXBoaXRpXCIgfSxcbiAgICBjb21tYW5kOiB7XG4gICAgICBiaW5OYW1lOiBcImRieC1ncmFwaGl0aVwiLFxuICAgICAgYXJndW1lbnRzOiBzZXJpYWxpemVBcmdzKEdyYXBoaXRpT3B0aW9uc1NjaGVtYS5wYXJzZShvcHRpb25zKSksXG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKiBCdWlsZCBmb3JlZ3JvdW5kIGV4ZWN1dGlvbiBhbmQgc2hhcmVkIGRlc2t0b3Atc2VydmljZSBjb21tYW5kcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFByb2dyYW0oXG4gIG5hbWUgPSBcImRieCBncmFwaGl0aVwiLFxuICBkZXBlbmRlbmNpZXM6IEdyYXBoaXRpQ2xpRGVwZW5kZW5jaWVzID0geyBydW46IHJ1bkdyYXBoaXRpIH0sXG4pOiBDb21tYW5kIHtcbiAgY29uc3QgcHJvZ3JhbSA9IGFkZEFyZ3MoXG4gICAgbmV3IENvbW1hbmQoKVxuICAgICAgLm5hbWUobmFtZSlcbiAgICAgIC5kZXNjcmlwdGlvbihcIlJ1biBHcmFwaGl0aSBvciBtYW5hZ2UgaXRzIGN1cnJlbnQtdXNlciBkZXNrdG9wIHNlcnZpY2VcIilcbiAgICAgIC52ZXJzaW9uKFBBQ0tBR0VfVkVSU0lPTiwgXCItdiwgLS12ZXJzaW9uXCIpLFxuICAgIEdyYXBoaXRpQ2xpT3B0aW9uc1NjaGVtYSxcbiAgKS5hY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IGRlcGVuZGVuY2llcy5ydW4oZ3JhcGhpdGlPcHRpb25zKHByb2dyYW0pKTtcbiAgfSk7XG5cbiAgcHJvZ3JhbS5hZGRDb21tYW5kKFxuICAgIGJ1aWxkU2VydmljZUNvbW1hbmQoXG4gICAgICAoKSA9PiBncmFwaGl0aVNlcnZpY2VEZWZpbml0aW9uKGdyYXBoaXRpT3B0aW9ucyhwcm9ncmFtKSksXG4gICAgICBkZXBlbmRlbmNpZXMuc2VydmljZSxcbiAgICApLFxuICApO1xuICByZXR1cm4gcHJvZ3JhbTtcbn1cblxuZnVuY3Rpb24gZ3JhcGhpdGlPcHRpb25zKGNvbW1hbmQ6IENvbW1hbmQpOiBHcmFwaGl0aU9wdGlvbnMge1xuICByZXR1cm4gR3JhcGhpdGlPcHRpb25zU2NoZW1hLnBhcnNlKHBhcnNlQXJncyhjb21tYW5kLCBHcmFwaGl0aUNsaU9wdGlvbnNTY2hlbWEpKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphiti CLI option surface.
|
|
3
|
+
*
|
|
4
|
+
* The Node Graphiti runtime owns the complete shared option contract. This
|
|
5
|
+
* module re-exports that surface without creating parallel CLI policy.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
export { GRAPHITI_DEFAULTS, GraphitiCliOptionsSchema, GraphitiOptionsSchema, ResolvedGraphitiOptionsSchema, graphitiOptionOverrides, graphitiOptionsEnvironment, graphitiOptionsFromEnvironment, resolveGraphitiOptions, } from "@dbx-tools/graphiti/options";
|
|
10
|
+
export type { GraphitiOptions, ResolvedGraphitiOptions } from "@dbx-tools/graphiti/options";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphiti CLI option surface.
|
|
3
|
+
*
|
|
4
|
+
* The Node Graphiti runtime owns the complete shared option contract. This
|
|
5
|
+
* module re-exports that surface without creating parallel CLI policy.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
export { GRAPHITI_DEFAULTS, GraphitiCliOptionsSchema, GraphitiOptionsSchema, ResolvedGraphitiOptionsSchema, graphitiOptionOverrides, graphitiOptionsEnvironment, graphitiOptionsFromEnvironment, resolveGraphitiOptions, } from "@dbx-tools/graphiti/options";
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ncmFwaGl0aS9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O0dBT0c7QUFFSCxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLHdCQUF3QixFQUN4QixxQkFBcUIsRUFDckIsNkJBQTZCLEVBQzdCLHVCQUF1QixFQUN2QiwwQkFBMEIsRUFDMUIsOEJBQThCLEVBQzlCLHNCQUFzQixHQUN2QixNQUFNLDZCQUE2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHcmFwaGl0aSBDTEkgb3B0aW9uIHN1cmZhY2UuXG4gKlxuICogVGhlIE5vZGUgR3JhcGhpdGkgcnVudGltZSBvd25zIHRoZSBjb21wbGV0ZSBzaGFyZWQgb3B0aW9uIGNvbnRyYWN0LiBUaGlzXG4gKiBtb2R1bGUgcmUtZXhwb3J0cyB0aGF0IHN1cmZhY2Ugd2l0aG91dCBjcmVhdGluZyBwYXJhbGxlbCBDTEkgcG9saWN5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5leHBvcnQge1xuICBHUkFQSElUSV9ERUZBVUxUUyxcbiAgR3JhcGhpdGlDbGlPcHRpb25zU2NoZW1hLFxuICBHcmFwaGl0aU9wdGlvbnNTY2hlbWEsXG4gIFJlc29sdmVkR3JhcGhpdGlPcHRpb25zU2NoZW1hLFxuICBncmFwaGl0aU9wdGlvbk92ZXJyaWRlcyxcbiAgZ3JhcGhpdGlPcHRpb25zRW52aXJvbm1lbnQsXG4gIGdyYXBoaXRpT3B0aW9uc0Zyb21FbnZpcm9ubWVudCxcbiAgcmVzb2x2ZUdyYXBoaXRpT3B0aW9ucyxcbn0gZnJvbSBcIkBkYngtdG9vbHMvZ3JhcGhpdGkvb3B0aW9uc1wiO1xuZXhwb3J0IHR5cGUgeyBHcmFwaGl0aU9wdGlvbnMsIFJlc29sdmVkR3JhcGhpdGlPcHRpb25zIH0gZnJvbSBcIkBkYngtdG9vbHMvZ3JhcGhpdGkvb3B0aW9uc1wiO1xuIl19
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** PostgreSQL cancellation key translation and TLS forwarding. */
|
|
2
|
+
import { type CancelMessage } from "./protocol.ts";
|
|
3
|
+
/** Upstream PostgreSQL backend key used to forward a cancellation request. */
|
|
4
|
+
export interface CancellationTarget {
|
|
5
|
+
host: string;
|
|
6
|
+
port: number;
|
|
7
|
+
processId: number;
|
|
8
|
+
secretKey: number;
|
|
9
|
+
}
|
|
10
|
+
/** Sends one PostgreSQL cancellation request to its upstream backend. */
|
|
11
|
+
export type CancellationForwarder = (target: CancellationTarget) => Promise<void>;
|
|
12
|
+
/** Maps synthetic local backend keys onto real upstream cancellation targets. */
|
|
13
|
+
export declare class CancellationRegistry {
|
|
14
|
+
private readonly forwarder;
|
|
15
|
+
private readonly targets;
|
|
16
|
+
constructor(forwarder?: CancellationForwarder);
|
|
17
|
+
register(target: CancellationTarget): CancelMessage;
|
|
18
|
+
remove(message: CancelMessage): void;
|
|
19
|
+
forward(message: CancelMessage): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
/** Forward a PostgreSQL cancellation request over a verified TLS connection. */
|
|
22
|
+
export declare function forwardCancellation(target: CancellationTarget): Promise<void>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** PostgreSQL cancellation key translation and TLS forwarding. */
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { createConnection, isIP } from "node:net";
|
|
4
|
+
import { connect as connectTls } from "node:tls";
|
|
5
|
+
import { cancelRequest, sslRequest } from "./protocol.js";
|
|
6
|
+
let nextProcessId = 10_000;
|
|
7
|
+
/** Maps synthetic local backend keys onto real upstream cancellation targets. */
|
|
8
|
+
export class CancellationRegistry {
|
|
9
|
+
forwarder;
|
|
10
|
+
targets = new Map();
|
|
11
|
+
constructor(forwarder = forwardCancellation) {
|
|
12
|
+
this.forwarder = forwarder;
|
|
13
|
+
}
|
|
14
|
+
register(target) {
|
|
15
|
+
const processId = nextProcessId++;
|
|
16
|
+
const secretKey = randomBytes(4).readInt32BE(0);
|
|
17
|
+
this.targets.set(key(processId, secretKey), target);
|
|
18
|
+
return { kind: "cancel", processId, secretKey };
|
|
19
|
+
}
|
|
20
|
+
remove(message) {
|
|
21
|
+
this.targets.delete(key(message.processId, message.secretKey));
|
|
22
|
+
}
|
|
23
|
+
async forward(message) {
|
|
24
|
+
const target = this.targets.get(key(message.processId, message.secretKey));
|
|
25
|
+
if (!target)
|
|
26
|
+
return false;
|
|
27
|
+
await this.forwarder(target);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Forward a PostgreSQL cancellation request over a verified TLS connection. */
|
|
32
|
+
export async function forwardCancellation(target) {
|
|
33
|
+
const socket = createConnection({ host: target.host, port: target.port });
|
|
34
|
+
await event(socket, "connect");
|
|
35
|
+
socket.write(sslRequest());
|
|
36
|
+
const response = await readByte(socket);
|
|
37
|
+
if (response !== "S".charCodeAt(0)) {
|
|
38
|
+
socket.destroy();
|
|
39
|
+
throw new Error("Lakebase upstream refused TLS for cancellation");
|
|
40
|
+
}
|
|
41
|
+
const tls = connectTls({
|
|
42
|
+
socket,
|
|
43
|
+
rejectUnauthorized: true,
|
|
44
|
+
...(isIP(target.host) === 0 ? { servername: target.host } : {}),
|
|
45
|
+
});
|
|
46
|
+
await event(tls, "secureConnect");
|
|
47
|
+
await writeAndClose(tls, cancelRequest(target.processId, target.secretKey));
|
|
48
|
+
}
|
|
49
|
+
function key(processId, secretKey) {
|
|
50
|
+
return `${processId}:${secretKey}`;
|
|
51
|
+
}
|
|
52
|
+
function event(socket, name) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const onEvent = () => finish();
|
|
55
|
+
const onError = (error) => finish(error);
|
|
56
|
+
const finish = (error) => {
|
|
57
|
+
socket.off(name, onEvent);
|
|
58
|
+
socket.off("error", onError);
|
|
59
|
+
if (error)
|
|
60
|
+
reject(error);
|
|
61
|
+
else
|
|
62
|
+
resolve();
|
|
63
|
+
};
|
|
64
|
+
socket.once(name, onEvent);
|
|
65
|
+
socket.once("error", onError);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function readByte(socket) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const onData = (chunk) => {
|
|
71
|
+
finish();
|
|
72
|
+
if (chunk.length > 1)
|
|
73
|
+
socket.unshift(chunk.subarray(1));
|
|
74
|
+
resolve(chunk[0]);
|
|
75
|
+
};
|
|
76
|
+
const onError = (error) => {
|
|
77
|
+
finish();
|
|
78
|
+
reject(error);
|
|
79
|
+
};
|
|
80
|
+
const onEnd = () => {
|
|
81
|
+
finish();
|
|
82
|
+
reject(new Error("Lakebase upstream closed during TLS negotiation"));
|
|
83
|
+
};
|
|
84
|
+
const finish = () => {
|
|
85
|
+
socket.off("data", onData);
|
|
86
|
+
socket.off("error", onError);
|
|
87
|
+
socket.off("end", onEnd);
|
|
88
|
+
};
|
|
89
|
+
socket.once("data", onData);
|
|
90
|
+
socket.once("error", onError);
|
|
91
|
+
socket.once("end", onEnd);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function writeAndClose(socket, packet) {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
socket.end(packet, () => resolve());
|
|
97
|
+
socket.once("error", reject);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FuY2VsbGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xha2ViYXNlLXByb3h5L2NhbmNlbGxhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxrRUFBa0U7QUFFbEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFlLE1BQU0sVUFBVSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxPQUFPLElBQUksVUFBVSxFQUFrQixNQUFNLFVBQVUsQ0FBQztBQUVqRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBc0IsTUFBTSxlQUFlLENBQUM7QUFhOUUsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDO0FBRTNCLGlGQUFpRjtBQUNqRixNQUFNLE9BQU8sb0JBQW9CO0lBR0Y7SUFGWixPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7SUFFakUsWUFBNkIsWUFBbUMsbUJBQW1CO1FBQXRELGNBQVMsR0FBVCxTQUFTLENBQTZDO0lBQUcsQ0FBQztJQUV2RixRQUFRLENBQUMsTUFBMEI7UUFDakMsTUFBTSxTQUFTLEdBQUcsYUFBYSxFQUFFLENBQUM7UUFDbEMsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQsTUFBTSxDQUFDLE9BQXNCO1FBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxT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QUFDLE1BQWlCLEVBQUUsTUFBYztJQUN0RCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3JDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIFBvc3RncmVTUUwgY2FuY2VsbGF0aW9uIGtleSB0cmFuc2xhdGlvbiBhbmQgVExTIGZvcndhcmRpbmcuICovXG5cbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0aW9uLCBpc0lQLCB0eXBlIFNvY2tldCB9IGZyb20gXCJub2RlOm5ldFwiO1xuaW1wb3J0IHsgY29ubmVjdCBhcyBjb25uZWN0VGxzLCB0eXBlIFRMU1NvY2tldCB9IGZyb20gXCJub2RlOnRsc1wiO1xuXG5pbXBvcnQgeyBjYW5jZWxSZXF1ZXN0LCBzc2xSZXF1ZXN0LCB0eXBlIENhbmNlbE1lc3NhZ2UgfSBmcm9tIFwiLi9wcm90b2NvbC50c1wiO1xuXG4vKiogVXBzdHJlYW0gUG9zdGdyZVNRTCBiYWNrZW5kIGtleSB1c2VkIHRvIGZvcndhcmQgYSBjYW5jZWxsYXRpb24gcmVxdWVzdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuY2VsbGF0aW9uVGFyZ2V0IHtcbiAgaG9zdDogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG4gIHByb2Nlc3NJZDogbnVtYmVyO1xuICBzZWNyZXRLZXk6IG51bWJlcjtcbn1cblxuLyoqIFNlbmRzIG9uZSBQb3N0Z3JlU1FMIGNhbmNlbGxhdGlvbiByZXF1ZXN0IHRvIGl0cyB1cHN0cmVhbSBiYWNrZW5kLiAqL1xuZXhwb3J0IHR5cGUgQ2FuY2VsbGF0aW9uRm9yd2FyZGVyID0gKHRhcmdldDogQ2FuY2VsbGF0aW9uVGFyZ2V0KSA9PiBQcm9taXNlPHZvaWQ+O1xuXG5sZXQgbmV4dFByb2Nlc3NJZCA9IDEwXzAwMDtcblxuLyoqIE1hcHMgc3ludGhldGljIGxvY2FsIGJhY2tlbmQga2V5cyBvbnRvIHJlYWwgdXBzdHJlYW0gY2FuY2VsbGF0aW9uIHRhcmdldHMuICovXG5leHBvcnQgY2xhc3MgQ2FuY2VsbGF0aW9uUmVnaXN0cnkge1xuICBwcml2YXRlIHJlYWRvbmx5IHRhcmdldHMgPSBuZXcgTWFwPHN0cmluZywgQ2FuY2VsbGF0aW9uVGFyZ2V0PigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZm9yd2FyZGVyOiBDYW5jZWxsYXRpb25Gb3J3YXJkZXIgPSBmb3J3YXJkQ2FuY2VsbGF0aW9uKSB7fVxuXG4gIHJlZ2lzdGVyKHRhcmdldDogQ2FuY2VsbGF0aW9uVGFyZ2V0KTogQ2FuY2VsTWVzc2FnZSB7XG4gICAgY29uc3QgcHJvY2Vzc0lkID0gbmV4dFByb2Nlc3NJZCsrO1xuICAgIGNvbnN0IHNlY3JldEtleSA9IHJhbmRvbUJ5dGVzKDQpLnJlYWRJbnQzMkJFKDApO1xuICAgIHRoaXMudGFyZ2V0cy5zZXQoa2V5KHByb2Nlc3NJZCwgc2VjcmV0S2V5KSwgdGFyZ2V0KTtcbiAgICByZXR1cm4geyBraW5kOiBcImNhbmNlbFwiLCBwcm9jZXNzSWQsIHNlY3JldEtleSB9O1xuICB9XG5cbiAgcmVtb3ZlKG1lc3NhZ2U6IENhbmNlbE1lc3NhZ2UpOiB2b2lkIHtcbiAgICB0aGlzLnRhcmdldHMuZGVsZXRlKGtleShtZXNzYWdlLnByb2Nlc3NJZCwgbWVzc2FnZS5zZWNyZXRLZXkpKTtcbiAgfVxuXG4gIGFzeW5jIGZvcndhcmQobWVzc2FnZTogQ2FuY2VsTWVzc2FnZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMudGFyZ2V0cy5nZXQoa2V5KG1lc3NhZ2UucHJvY2Vzc0lkLCBtZXNzYWdlLnNlY3JldEtleSkpO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm4gZmFsc2U7XG4gICAgYXdhaXQgdGhpcy5mb3J3YXJkZXIodGFyZ2V0KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKiogRm9yd2FyZCBhIFBvc3RncmVTUUwgY2FuY2VsbGF0aW9uIHJlcXVlc3Qgb3ZlciBhIHZlcmlmaWVkIFRMUyBjb25uZWN0aW9uLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZvcndhcmRDYW5jZWxsYXRpb24odGFyZ2V0OiBDYW5jZWxsYXRpb25UYXJnZXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgc29ja2V0ID0gY3JlYXRlQ29ubmVjdGlvbih7IGhvc3Q6IHRhcmdldC5ob3N0LCBwb3J0OiB0YXJnZXQucG9ydCB9KTtcbiAgYXdhaXQgZXZlbnQoc29ja2V0LCBcImNvbm5lY3RcIik7XG4gIHNvY2tldC53cml0ZShzc2xSZXF1ZXN0KCkpO1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlYWRCeXRlKHNvY2tldCk7XG4gIGlmIChyZXNwb25zZSAhPT0gXCJTXCIuY2hhckNvZGVBdCgwKSkge1xuICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTGFrZWJhc2UgdXBzdHJlYW0gcmVmdXNlZCBUTFMgZm9yIGNhbmNlbGxhdGlvblwiKTtcbiAgfVxuICBjb25zdCB0bHMgPSBjb25uZWN0VGxzKHtcbiAgICBzb2NrZXQsXG4gICAgcmVqZWN0VW5hdXRob3JpemVkOiB0cnVlLFxuICAgIC4uLihpc0lQKHRhcmdldC5ob3N0KSA9PT0gMCA/IHsgc2VydmVybmFtZTogdGFyZ2V0Lmhvc3QgfSA6IHt9KSxcbiAgfSk7XG4gIGF3YWl0IGV2ZW50KHRscywgXCJzZWN1cmVDb25uZWN0XCIpO1xuICBhd2FpdCB3cml0ZUFuZENsb3NlKHRscywgY2FuY2VsUmVxdWVzdCh0YXJnZXQucHJvY2Vzc0lkLCB0YXJnZXQuc2VjcmV0S2V5KSk7XG59XG5cbmZ1bmN0aW9uIGtleShwcm9jZXNzSWQ6IG51bWJlciwgc2VjcmV0S2V5OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7cHJvY2Vzc0lkfToke3NlY3JldEtleX1gO1xufVxuXG5mdW5jdGlvbiBldmVudChzb2NrZXQ6IFNvY2tldCB8IFRMU1NvY2tldCwgbmFtZTogXCJjb25uZWN0XCIgfCBcInNlY3VyZUNvbm5lY3RcIik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IG9uRXZlbnQgPSAoKSA9PiBmaW5pc2goKTtcbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvcikgPT4gZmluaXNoKGVycm9yKTtcbiAgICBjb25zdCBmaW5pc2ggPSAoZXJyb3I/OiBFcnJvcikgPT4ge1xuICAgICAgc29ja2V0Lm9mZihuYW1lLCBvbkV2ZW50KTtcbiAgICAgIHNvY2tldC5vZmYoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgIGlmIChlcnJvcikgcmVqZWN0KGVycm9yKTtcbiAgICAgIGVsc2UgcmVzb2x2ZSgpO1xuICAgIH07XG4gICAgc29ja2V0Lm9uY2UobmFtZSwgb25FdmVudCk7XG4gICAgc29ja2V0Lm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRCeXRlKHNvY2tldDogU29ja2V0KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBvbkRhdGEgPSAoY2h1bms6IEJ1ZmZlcikgPT4ge1xuICAgICAgZmluaXNoKCk7XG4gICAgICBpZiAoY2h1bmsubGVuZ3RoID4gMSkgc29ja2V0LnVuc2hpZnQoY2h1bmsuc3ViYXJyYXkoMSkpO1xuICAgICAgcmVzb2x2ZShjaHVua1swXSEpO1xuICAgIH07XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGZpbmlzaCgpO1xuICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uRW5kID0gKCkgPT4ge1xuICAgICAgZmluaXNoKCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKFwiTGFrZWJhc2UgdXBzdHJlYW0gY2xvc2VkIGR1cmluZyBUTFMgbmVnb3RpYXRpb25cIikpO1xuICAgIH07XG4gICAgY29uc3QgZmluaXNoID0gKCkgPT4ge1xuICAgICAgc29ja2V0Lm9mZihcImRhdGFcIiwgb25EYXRhKTtcbiAgICAgIHNvY2tldC5vZmYoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgIHNvY2tldC5vZmYoXCJlbmRcIiwgb25FbmQpO1xuICAgIH07XG4gICAgc29ja2V0Lm9uY2UoXCJkYXRhXCIsIG9uRGF0YSk7XG4gICAgc29ja2V0Lm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICBzb2NrZXQub25jZShcImVuZFwiLCBvbkVuZCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB3cml0ZUFuZENsb3NlKHNvY2tldDogVExTU29ja2V0LCBwYWNrZXQ6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNvY2tldC5lbmQocGFja2V0LCAoKSA9PiByZXNvbHZlKCkpO1xuICAgIHNvY2tldC5vbmNlKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Commander entry point for the pure Node Lakebase proxy. */
|
|
2
|
+
import { type CliServiceCliDependencies } from "@dbx-tools/cli-service/cli";
|
|
3
|
+
import { type CliServiceDefinition } from "@dbx-tools/cli-service/definition";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { type LakebaseProxyOptions } from "./options.ts";
|
|
6
|
+
/** Injectable service boundary for Lakebase proxy CLI composition and tests. */
|
|
7
|
+
export interface LakebaseProxyCliDependencies {
|
|
8
|
+
readonly service?: CliServiceCliDependencies;
|
|
9
|
+
}
|
|
10
|
+
/** Build the tray-only Lakebase proxy service definition. */
|
|
11
|
+
export declare function lakebaseProxyServiceDefinition(options?: LakebaseProxyOptions): CliServiceDefinition;
|
|
12
|
+
/** Build the Lakebase proxy command-line program. */
|
|
13
|
+
export declare function buildProgram(name?: string, dependencies?: LakebaseProxyCliDependencies): Command;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Commander entry point for the pure Node Lakebase proxy. */
|
|
2
|
+
import { addArgs, parseArgs, serializeArgs } from "@dbx-tools/cli-args";
|
|
3
|
+
import { buildServiceCommand } from "@dbx-tools/cli-service/cli";
|
|
4
|
+
import { defineService } from "@dbx-tools/cli-service/definition";
|
|
5
|
+
import { connectionUrl } from "@dbx-tools/lakebase";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { PACKAGE_VERSION } from "../../index.js";
|
|
8
|
+
import { LakebaseProxyOptionsSchema, LakebaseProxyUrlOptionsSchema, resolveLakebaseProxyOptions, } from "./options.js";
|
|
9
|
+
import { LakebaseProxy } from "./proxy.js";
|
|
10
|
+
/** Build the tray-only Lakebase proxy service definition. */
|
|
11
|
+
export function lakebaseProxyServiceDefinition(options = {}) {
|
|
12
|
+
const resolved = resolveLakebaseProxyOptions(options);
|
|
13
|
+
return defineService(import.meta.url, {
|
|
14
|
+
id: "dbx-tools.cli-lakebase-proxy",
|
|
15
|
+
name: "dbx lakebase proxy",
|
|
16
|
+
command: {
|
|
17
|
+
binName: "dbx-lakebase-proxy",
|
|
18
|
+
arguments: serializeArgs(resolved),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/** Build the Lakebase proxy command-line program. */
|
|
23
|
+
export function buildProgram(name = "dbx lakebase-proxy", dependencies = {}) {
|
|
24
|
+
const program = addArgs(new Command(name)
|
|
25
|
+
.description("Run a loopback PostgreSQL proxy for Databricks Lakebase")
|
|
26
|
+
.version(PACKAGE_VERSION)
|
|
27
|
+
.enablePositionalOptions(), LakebaseProxyOptionsSchema).action(async () => {
|
|
28
|
+
const proxy = new LakebaseProxy(parseArgs(program, LakebaseProxyOptionsSchema));
|
|
29
|
+
await proxy.listen();
|
|
30
|
+
await waitForShutdown();
|
|
31
|
+
await proxy.close();
|
|
32
|
+
});
|
|
33
|
+
const urlCommand = addArgs(program.command("url").description("Format a local PostgreSQL URL for a Lakebase target"), LakebaseProxyUrlOptionsSchema).action(() => {
|
|
34
|
+
const options = parseArgs(urlCommand, LakebaseProxyUrlOptionsSchema);
|
|
35
|
+
const target = options.target ?? options.lakebaseEndpoint;
|
|
36
|
+
process.stdout.write(`${connectionUrl(target, options.listen.host, options.listen.port)}\n`);
|
|
37
|
+
});
|
|
38
|
+
let installCommand;
|
|
39
|
+
const serviceCommand = buildServiceCommand(() => {
|
|
40
|
+
return lakebaseProxyServiceDefinition(parseArgs(installCommand, LakebaseProxyOptionsSchema));
|
|
41
|
+
}, dependencies.service);
|
|
42
|
+
installCommand = serviceCommand.commands.find((command) => command.name() === "install");
|
|
43
|
+
addArgs(installCommand, LakebaseProxyOptionsSchema);
|
|
44
|
+
program.addCommand(serviceCommand);
|
|
45
|
+
return program;
|
|
46
|
+
}
|
|
47
|
+
function waitForShutdown() {
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
const shutdown = () => resolve();
|
|
50
|
+
process.once("SIGINT", shutdown);
|
|
51
|
+
process.once("SIGTERM", shutdown);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xha2ViYXNlLXByb3h5L2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4REFBOEQ7QUFFOUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDeEUsT0FBTyxFQUFFLG1CQUFtQixFQUFrQyxNQUFNLDRCQUE0QixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxhQUFhLEVBQTZCLE1BQU0sbUNBQW1DLENBQUM7QUFDN0YsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFcEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsNkJBQTZCLEVBQzdCLDJCQUEyQixHQUU1QixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBTzNDLDZEQUE2RDtBQUM3RCxNQUFNLFVBQVUsOEJBQThCLENBQzVDLFVBQWdDLEVBQUU7SUFFbEMsTUFBTSxRQUFRLEdBQUcsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEQsT0FBTyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDcEMsRUFBRSxFQUFFLDhCQUE4QjtRQUNsQyxJQUFJLEVBQUUsb0JBQW9CO1FBQzFCLE9BQU8sRUFBRTtZQUNQLE9BQU8sRUFBRSxvQkFBb0I7WUFDN0IsU0FBUyxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUM7U0FDbkM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQscURBQXFEO0FBQ3JELE1BQU0sVUFBVSxZQUFZLENBQzFCLElBQUksR0FBRyxvQkFBb0IsRUFDM0IsZUFBNkMsRUFBRTtJQUUvQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQ3JCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQztTQUNkLFdBQVcsQ0FBQyx5REFBeUQsQ0FBQztTQUN0RSxPQUFPLENBQUMsZUFBZSxDQUFDO1NBQ3hCLHVCQUF1QixFQUFFLEVBQzVCLDBCQUEwQixDQUMzQixDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNsQixNQUFNLEtBQUssR0FBRyxJQUFJLGFBQWEsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLDBCQUEwQixDQUFDLENBQUMsQ0FBQztRQUNoRixNQUFNLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyQixNQUFNLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUN4QixPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsQ0FBQyxxREFBcUQsQ0FBQyxFQUN6Riw2QkFBNkIsQ0FDOUIsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFO1FBQ1osTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLFVBQVUsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLGdCQUFpQixDQUFDO1FBQzNELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvRixDQUFDLENBQUMsQ0FBQztJQUNILElBQUksY0FBd0IsQ0FBQztJQUM3QixNQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUU7UUFDOUMsT0FBTyw4QkFBOEIsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLDBCQUEwQixDQUFDLENBQUMsQ0FBQztJQUMvRixDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pCLGNBQWMsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLFNBQVMsQ0FBRSxDQUFDO0lBQzFGLE9BQU8sQ0FBQyxjQUFjLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztJQUNwRCxPQUFPLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ25DLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLGVBQWU7SUFDdEIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLE1BQU0sUUFBUSxHQUFHLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBDb21tYW5kZXIgZW50cnkgcG9pbnQgZm9yIHRoZSBwdXJlIE5vZGUgTGFrZWJhc2UgcHJveHkuICovXG5cbmltcG9ydCB7IGFkZEFyZ3MsIHBhcnNlQXJncywgc2VyaWFsaXplQXJncyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NsaS1hcmdzXCI7XG5pbXBvcnQgeyBidWlsZFNlcnZpY2VDb21tYW5kLCB0eXBlIENsaVNlcnZpY2VDbGlEZXBlbmRlbmNpZXMgfSBmcm9tIFwiQGRieC10b29scy9jbGktc2VydmljZS9jbGlcIjtcbmltcG9ydCB7IGRlZmluZVNlcnZpY2UsIHR5cGUgQ2xpU2VydmljZURlZmluaXRpb24gfSBmcm9tIFwiQGRieC10b29scy9jbGktc2VydmljZS9kZWZpbml0aW9uXCI7XG5pbXBvcnQgeyBjb25uZWN0aW9uVXJsIH0gZnJvbSBcIkBkYngtdG9vbHMvbGFrZWJhc2VcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5cbmltcG9ydCB7IFBBQ0tBR0VfVkVSU0lPTiB9IGZyb20gXCIuLi8uLi9pbmRleC50c1wiO1xuaW1wb3J0IHtcbiAgTGFrZWJhc2VQcm94eU9wdGlvbnNTY2hlbWEsXG4gIExha2ViYXNlUHJveHlVcmxPcHRpb25zU2NoZW1hLFxuICByZXNvbHZlTGFrZWJhc2VQcm94eU9wdGlvbnMsXG4gIHR5cGUgTGFrZWJhc2VQcm94eU9wdGlvbnMsXG59IGZyb20gXCIuL29wdGlvbnMudHNcIjtcbmltcG9ydCB7IExha2ViYXNlUHJveHkgfSBmcm9tIFwiLi9wcm94eS50c1wiO1xuXG4vKiogSW5qZWN0YWJsZSBzZXJ2aWNlIGJvdW5kYXJ5IGZvciBMYWtlYmFzZSBwcm94eSBDTEkgY29tcG9zaXRpb24gYW5kIHRlc3RzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWtlYmFzZVByb3h5Q2xpRGVwZW5kZW5jaWVzIHtcbiAgcmVhZG9ubHkgc2VydmljZT86IENsaVNlcnZpY2VDbGlEZXBlbmRlbmNpZXM7XG59XG5cbi8qKiBCdWlsZCB0aGUgdHJheS1vbmx5IExha2ViYXNlIHByb3h5IHNlcnZpY2UgZGVmaW5pdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYWtlYmFzZVByb3h5U2VydmljZURlZmluaXRpb24oXG4gIG9wdGlvbnM6IExha2ViYXNlUHJveHlPcHRpb25zID0ge30sXG4pOiBDbGlTZXJ2aWNlRGVmaW5pdGlvbiB7XG4gIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZUxha2ViYXNlUHJveHlPcHRpb25zKG9wdGlvbnMpO1xuICByZXR1cm4gZGVmaW5lU2VydmljZShpbXBvcnQubWV0YS51cmwsIHtcbiAgICBpZDogXCJkYngtdG9vbHMuY2xpLWxha2ViYXNlLXByb3h5XCIsXG4gICAgbmFtZTogXCJkYnggbGFrZWJhc2UgcHJveHlcIixcbiAgICBjb21tYW5kOiB7XG4gICAgICBiaW5OYW1lOiBcImRieC1sYWtlYmFzZS1wcm94eVwiLFxuICAgICAgYXJndW1lbnRzOiBzZXJpYWxpemVBcmdzKHJlc29sdmVkKSxcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIEJ1aWxkIHRoZSBMYWtlYmFzZSBwcm94eSBjb21tYW5kLWxpbmUgcHJvZ3JhbS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFByb2dyYW0oXG4gIG5hbWUgPSBcImRieCBsYWtlYmFzZS1wcm94eVwiLFxuICBkZXBlbmRlbmNpZXM6IExha2ViYXNlUHJveHlDbGlEZXBlbmRlbmNpZXMgPSB7fSxcbik6IENvbW1hbmQge1xuICBjb25zdCBwcm9ncmFtID0gYWRkQXJncyhcbiAgICBuZXcgQ29tbWFuZChuYW1lKVxuICAgICAgLmRlc2NyaXB0aW9uKFwiUnVuIGEgbG9vcGJhY2sgUG9zdGdyZVNRTCBwcm94eSBmb3IgRGF0YWJyaWNrcyBMYWtlYmFzZVwiKVxuICAgICAgLnZlcnNpb24oUEFDS0FHRV9WRVJTSU9OKVxuICAgICAgLmVuYWJsZVBvc2l0aW9uYWxPcHRpb25zKCksXG4gICAgTGFrZWJhc2VQcm94eU9wdGlvbnNTY2hlbWEsXG4gICkuYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwcm94eSA9IG5ldyBMYWtlYmFzZVByb3h5KHBhcnNlQXJncyhwcm9ncmFtLCBMYWtlYmFzZVByb3h5T3B0aW9uc1NjaGVtYSkpO1xuICAgIGF3YWl0IHByb3h5Lmxpc3RlbigpO1xuICAgIGF3YWl0IHdhaXRGb3JTaHV0ZG93bigpO1xuICAgIGF3YWl0IHByb3h5LmNsb3NlKCk7XG4gIH0pO1xuXG4gIGNvbnN0IHVybENvbW1hbmQgPSBhZGRBcmdzKFxuICAgIHByb2dyYW0uY29tbWFuZChcInVybFwiKS5kZXNjcmlwdGlvbihcIkZvcm1hdCBhIGxvY2FsIFBvc3RncmVTUUwgVVJMIGZvciBhIExha2ViYXNlIHRhcmdldFwiKSxcbiAgICBMYWtlYmFzZVByb3h5VXJsT3B0aW9uc1NjaGVtYSxcbiAgKS5hY3Rpb24oKCkgPT4ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBwYXJzZUFyZ3ModXJsQ29tbWFuZCwgTGFrZWJhc2VQcm94eVVybE9wdGlvbnNTY2hlbWEpO1xuICAgIGNvbnN0IHRhcmdldCA9IG9wdGlvbnMudGFyZ2V0ID8/IG9wdGlvbnMubGFrZWJhc2VFbmRwb2ludCE7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCR7Y29ubmVjdGlvblVybCh0YXJnZXQsIG9wdGlvbnMubGlzdGVuLmhvc3QsIG9wdGlvbnMubGlzdGVuLnBvcnQpfVxcbmApO1xuICB9KTtcbiAgbGV0IGluc3RhbGxDb21tYW5kITogQ29tbWFuZDtcbiAgY29uc3Qgc2VydmljZUNvbW1hbmQgPSBidWlsZFNlcnZpY2VDb21tYW5kKCgpID0+IHtcbiAgICByZXR1cm4gbGFrZWJhc2VQcm94eVNlcnZpY2VEZWZpbml0aW9uKHBhcnNlQXJncyhpbnN0YWxsQ29tbWFuZCwgTGFrZWJhc2VQcm94eU9wdGlvbnNTY2hlbWEpKTtcbiAgfSwgZGVwZW5kZW5jaWVzLnNlcnZpY2UpO1xuICBpbnN0YWxsQ29tbWFuZCA9IHNlcnZpY2VDb21tYW5kLmNvbW1hbmRzLmZpbmQoKGNvbW1hbmQpID0+IGNvbW1hbmQubmFtZSgpID09PSBcImluc3RhbGxcIikhO1xuICBhZGRBcmdzKGluc3RhbGxDb21tYW5kLCBMYWtlYmFzZVByb3h5T3B0aW9uc1NjaGVtYSk7XG4gIHByb2dyYW0uYWRkQ29tbWFuZChzZXJ2aWNlQ29tbWFuZCk7XG4gIHJldHVybiBwcm9ncmFtO1xufVxuXG5mdW5jdGlvbiB3YWl0Rm9yU2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHNodXRkb3duID0gKCkgPT4gcmVzb2x2ZSgpO1xuICAgIHByb2Nlc3Mub25jZShcIlNJR0lOVFwiLCBzaHV0ZG93bik7XG4gICAgcHJvY2Vzcy5vbmNlKFwiU0lHVEVSTVwiLCBzaHV0ZG93bik7XG4gIH0pO1xufVxuIl19
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lakebase proxy listener, service, and URL command options.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { options } from "@dbx-tools/shared-core";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
export declare const LakebaseProxyOptionsSchema: z.ZodObject<{
|
|
9
|
+
listen: z.ZodDefault<z.ZodType<options.TcpListenAddress, unknown, z.core.$ZodTypeInternals<options.TcpListenAddress, unknown>>>;
|
|
10
|
+
startupTimeoutSeconds: z.ZodDefault<z.ZodCoercedNumber<number>>;
|
|
11
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
12
|
+
postgresRole: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strict>;
|
|
14
|
+
export declare const LakebaseProxyUrlOptionsSchema: z.ZodObject<{
|
|
15
|
+
target: z.ZodOptional<z.ZodString>;
|
|
16
|
+
lakebaseEndpoint: z.ZodOptional<z.ZodString>;
|
|
17
|
+
listen: z.ZodDefault<z.ZodType<options.TcpListenAddress, unknown, z.core.$ZodTypeInternals<options.TcpListenAddress, unknown>>>;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
export type LakebaseProxyOptions = z.input<typeof LakebaseProxyOptionsSchema>;
|
|
20
|
+
export type ResolvedLakebaseProxyOptions = z.output<typeof LakebaseProxyOptionsSchema>;
|
|
21
|
+
export type LakebaseProxyUrlOptions = z.output<typeof LakebaseProxyUrlOptionsSchema>;
|
|
22
|
+
/** Validate and default Lakebase proxy listener options. */
|
|
23
|
+
export declare function resolveLakebaseProxyOptions(options?: LakebaseProxyOptions): ResolvedLakebaseProxyOptions;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lakebase proxy listener, service, and URL command options.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { options } from "@dbx-tools/shared-core";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
const text = (description) => z.string().trim().min(1).optional().describe(description);
|
|
9
|
+
export const LakebaseProxyOptionsSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
...options.PostgresOptionsSchema.shape,
|
|
12
|
+
listen: options
|
|
13
|
+
.listenAddressSchema({ port: 5432, loopback: true })
|
|
14
|
+
.describe("Loopback listener address."),
|
|
15
|
+
startupTimeoutSeconds: z.coerce
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.nonnegative()
|
|
19
|
+
.default(30)
|
|
20
|
+
.describe("Startup timeout in seconds."),
|
|
21
|
+
profile: options.DatabricksOptionsSchema.shape.profile.describe("Exact Databricks profile."),
|
|
22
|
+
})
|
|
23
|
+
.strict()
|
|
24
|
+
.describe("Lakebase proxy listener and service options.");
|
|
25
|
+
export const LakebaseProxyUrlOptionsSchema = z
|
|
26
|
+
.object({
|
|
27
|
+
target: text("Lakebase project, resource path, host, or URL."),
|
|
28
|
+
lakebaseEndpoint: options.LakebaseOptionsSchema.shape.lakebaseEndpoint,
|
|
29
|
+
listen: options.listenAddressSchema({ port: 5432 }).describe("Local proxy address."),
|
|
30
|
+
})
|
|
31
|
+
.strict()
|
|
32
|
+
.refine((configured) => configured.target !== undefined || configured.lakebaseEndpoint !== undefined, {
|
|
33
|
+
message: "URL requires target or endpoint.",
|
|
34
|
+
path: ["target"],
|
|
35
|
+
})
|
|
36
|
+
.describe("Options for formatting a local Lakebase PostgreSQL URL.");
|
|
37
|
+
/** Validate and default Lakebase proxy listener options. */
|
|
38
|
+
export function resolveLakebaseProxyOptions(options = {}) {
|
|
39
|
+
return LakebaseProxyOptionsSchema.parse(options);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYWtlYmFzZS1wcm94eS9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QixNQUFNLElBQUksR0FBRyxDQUFDLFdBQW1CLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRWhHLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLENBQUM7S0FDeEMsTUFBTSxDQUFDO0lBQ04sR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsS0FBSztJQUN0QyxNQUFNLEVBQUUsT0FBTztTQUNaLG1CQUFtQixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDbkQsUUFBUSxDQUFDLDRCQUE0QixDQUFDO0lBQ3pDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxNQUFNO1NBQzVCLE1BQU0sRUFBVTtTQUNoQixHQUFHLEVBQUU7U0FDTCxXQUFXLEVBQUU7U0FDYixPQUFPLENBQUMsRUFBRSxDQUFDO1NBQ1gsUUFBUSxDQUFDLDZCQUE2QixDQUFDO0lBQzFDLE9BQU8sRUFBRSxPQUFPLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUM7Q0FDN0YsQ0FBQztLQUNELE1BQU0sRUFBRTtLQUNSLFFBQVEsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0FBRTVELE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLENBQUM7S0FDM0MsTUFBTSxDQUFDO0lBQ04sTUFBTSxFQUFFLElBQUksQ0FBQyxnREFBZ0QsQ0FBQztJQUM5RCxnQkFBZ0IsRUFBRSxPQUFPLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLGdCQUFnQjtJQUN0RSxNQUFNLEVBQUUsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDO0NBQ3JGLENBQUM7S0FDRCxNQUFNLEVBQUU7S0FDUixNQUFNLENBQ0wsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLEVBQzVGO0lBQ0UsT0FBTyxFQUFFLGtDQUFrQztJQUMzQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUM7Q0FDakIsQ0FDRjtLQUNBLFFBQVEsQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO0FBUXZFLDREQUE0RDtBQUM1RCxNQUFNLFVBQVUsMkJBQTJCLENBQ3pDLFVBQWdDLEVBQUU7SUFFbEMsT0FBTywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGFrZWJhc2UgcHJveHkgbGlzdGVuZXIsIHNlcnZpY2UsIGFuZCBVUkwgY29tbWFuZCBvcHRpb25zLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBvcHRpb25zIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmNvbnN0IHRleHQgPSAoZGVzY3JpcHRpb246IHN0cmluZykgPT4gei5zdHJpbmcoKS50cmltKCkubWluKDEpLm9wdGlvbmFsKCkuZGVzY3JpYmUoZGVzY3JpcHRpb24pO1xuXG5leHBvcnQgY29uc3QgTGFrZWJhc2VQcm94eU9wdGlvbnNTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIC4uLm9wdGlvbnMuUG9zdGdyZXNPcHRpb25zU2NoZW1hLnNoYXBlLFxuICAgIGxpc3Rlbjogb3B0aW9uc1xuICAgICAgLmxpc3RlbkFkZHJlc3NTY2hlbWEoeyBwb3J0OiA1NDMyLCBsb29wYmFjazogdHJ1ZSB9KVxuICAgICAgLmRlc2NyaWJlKFwiTG9vcGJhY2sgbGlzdGVuZXIgYWRkcmVzcy5cIiksXG4gICAgc3RhcnR1cFRpbWVvdXRTZWNvbmRzOiB6LmNvZXJjZVxuICAgICAgLm51bWJlcjxudW1iZXI+KClcbiAgICAgIC5pbnQoKVxuICAgICAgLm5vbm5lZ2F0aXZlKClcbiAgICAgIC5kZWZhdWx0KDMwKVxuICAgICAgLmRlc2NyaWJlKFwiU3RhcnR1cCB0aW1lb3V0IGluIHNlY29uZHMuXCIpLFxuICAgIHByb2ZpbGU6IG9wdGlvbnMuRGF0YWJyaWNrc09wdGlvbnNTY2hlbWEuc2hhcGUucHJvZmlsZS5kZXNjcmliZShcIkV4YWN0IERhdGFicmlja3MgcHJvZmlsZS5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJMYWtlYmFzZSBwcm94eSBsaXN0ZW5lciBhbmQgc2VydmljZSBvcHRpb25zLlwiKTtcblxuZXhwb3J0IGNvbnN0IExha2ViYXNlUHJveHlVcmxPcHRpb25zU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0YXJnZXQ6IHRleHQoXCJMYWtlYmFzZSBwcm9qZWN0LCByZXNvdXJjZSBwYXRoLCBob3N0LCBvciBVUkwuXCIpLFxuICAgIGxha2ViYXNlRW5kcG9pbnQ6IG9wdGlvbnMuTGFrZWJhc2VPcHRpb25zU2NoZW1hLnNoYXBlLmxha2ViYXNlRW5kcG9pbnQsXG4gICAgbGlzdGVuOiBvcHRpb25zLmxpc3RlbkFkZHJlc3NTY2hlbWEoeyBwb3J0OiA1NDMyIH0pLmRlc2NyaWJlKFwiTG9jYWwgcHJveHkgYWRkcmVzcy5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAucmVmaW5lKFxuICAgIChjb25maWd1cmVkKSA9PiBjb25maWd1cmVkLnRhcmdldCAhPT0gdW5kZWZpbmVkIHx8IGNvbmZpZ3VyZWQubGFrZWJhc2VFbmRwb2ludCAhPT0gdW5kZWZpbmVkLFxuICAgIHtcbiAgICAgIG1lc3NhZ2U6IFwiVVJMIHJlcXVpcmVzIHRhcmdldCBvciBlbmRwb2ludC5cIixcbiAgICAgIHBhdGg6IFtcInRhcmdldFwiXSxcbiAgICB9LFxuICApXG4gIC5kZXNjcmliZShcIk9wdGlvbnMgZm9yIGZvcm1hdHRpbmcgYSBsb2NhbCBMYWtlYmFzZSBQb3N0Z3JlU1FMIFVSTC5cIik7XG5cbmV4cG9ydCB0eXBlIExha2ViYXNlUHJveHlPcHRpb25zID0gei5pbnB1dDx0eXBlb2YgTGFrZWJhc2VQcm94eU9wdGlvbnNTY2hlbWE+O1xuXG5leHBvcnQgdHlwZSBSZXNvbHZlZExha2ViYXNlUHJveHlPcHRpb25zID0gei5vdXRwdXQ8dHlwZW9mIExha2ViYXNlUHJveHlPcHRpb25zU2NoZW1hPjtcblxuZXhwb3J0IHR5cGUgTGFrZWJhc2VQcm94eVVybE9wdGlvbnMgPSB6Lm91dHB1dDx0eXBlb2YgTGFrZWJhc2VQcm94eVVybE9wdGlvbnNTY2hlbWE+O1xuXG4vKiogVmFsaWRhdGUgYW5kIGRlZmF1bHQgTGFrZWJhc2UgcHJveHkgbGlzdGVuZXIgb3B0aW9ucy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTGFrZWJhc2VQcm94eU9wdGlvbnMoXG4gIG9wdGlvbnM6IExha2ViYXNlUHJveHlPcHRpb25zID0ge30sXG4pOiBSZXNvbHZlZExha2ViYXNlUHJveHlPcHRpb25zIHtcbiAgcmV0dXJuIExha2ViYXNlUHJveHlPcHRpb25zU2NoZW1hLnBhcnNlKG9wdGlvbnMpO1xufVxuIl19
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Minimal PostgreSQL startup protocol helpers for the loopback proxy. */
|
|
2
|
+
import type { Socket } from "node:net";
|
|
3
|
+
/** PostgreSQL SSLRequest protocol code. */
|
|
4
|
+
export declare const SSL_REQUEST = 80877103;
|
|
5
|
+
/** PostgreSQL CancelRequest protocol code. */
|
|
6
|
+
export declare const CANCEL_REQUEST = 80877102;
|
|
7
|
+
/** PostgreSQL protocol version 3 code. */
|
|
8
|
+
export declare const PROTOCOL_3 = 196608;
|
|
9
|
+
/** Parsed PostgreSQL startup packet. */
|
|
10
|
+
export interface StartupMessage {
|
|
11
|
+
kind: "startup";
|
|
12
|
+
protocol: number;
|
|
13
|
+
parameters: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
/** Parsed PostgreSQL cancellation packet. */
|
|
16
|
+
export interface CancelMessage {
|
|
17
|
+
kind: "cancel";
|
|
18
|
+
processId: number;
|
|
19
|
+
secretKey: number;
|
|
20
|
+
}
|
|
21
|
+
/** First supported packet received from a PostgreSQL client. */
|
|
22
|
+
export type InitialMessage = StartupMessage | CancelMessage;
|
|
23
|
+
/** Error caused by an invalid or unsupported PostgreSQL startup packet. */
|
|
24
|
+
export declare class PostgresProtocolError extends Error {
|
|
25
|
+
}
|
|
26
|
+
/** Read and classify the first PostgreSQL frontend message from a socket. */
|
|
27
|
+
export declare function readInitialMessage(socket: Socket, timeoutMs: number): Promise<InitialMessage>;
|
|
28
|
+
/** Build a PostgreSQL SSL negotiation request packet. */
|
|
29
|
+
export declare function sslRequest(): Buffer;
|
|
30
|
+
/** Build a PostgreSQL cancellation request packet. */
|
|
31
|
+
export declare function cancelRequest(processId: number, secretKey: number): Buffer;
|
|
32
|
+
/** Build the backend messages that complete PostgreSQL startup. */
|
|
33
|
+
export declare function startupComplete(parameters: ReadonlyMap<string, string>, processId: number, secretKey: number, transactionStatus?: string): Buffer;
|
|
34
|
+
/** Replace client startup identity with the resolved upstream identity. */
|
|
35
|
+
export declare function upstreamStartupParameters(parameters: Record<string, string>, user: string, database: string): Record<string, string>;
|
|
36
|
+
/** Build a fatal PostgreSQL error response. */
|
|
37
|
+
export declare function fatalError(message: string, sqlstate?: string): Buffer;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/** Minimal PostgreSQL startup protocol helpers for the loopback proxy. */
|
|
2
|
+
/** PostgreSQL SSLRequest protocol code. */
|
|
3
|
+
export const SSL_REQUEST = 80_877_103;
|
|
4
|
+
/** PostgreSQL CancelRequest protocol code. */
|
|
5
|
+
export const CANCEL_REQUEST = 80_877_102;
|
|
6
|
+
/** PostgreSQL protocol version 3 code. */
|
|
7
|
+
export const PROTOCOL_3 = 196_608;
|
|
8
|
+
/** Error caused by an invalid or unsupported PostgreSQL startup packet. */
|
|
9
|
+
export class PostgresProtocolError extends Error {
|
|
10
|
+
}
|
|
11
|
+
/** Read and classify the first PostgreSQL frontend message from a socket. */
|
|
12
|
+
export async function readInitialMessage(socket, timeoutMs) {
|
|
13
|
+
const deadline = Date.now() + timeoutMs;
|
|
14
|
+
for (;;) {
|
|
15
|
+
const packet = await readPacket(socket, deadline);
|
|
16
|
+
const code = packet.readInt32BE(4);
|
|
17
|
+
if (code === SSL_REQUEST) {
|
|
18
|
+
socket.write("N");
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (code === CANCEL_REQUEST) {
|
|
22
|
+
if (packet.length !== 16)
|
|
23
|
+
throw new PostgresProtocolError("Invalid CancelRequest packet");
|
|
24
|
+
return {
|
|
25
|
+
kind: "cancel",
|
|
26
|
+
processId: packet.readInt32BE(8),
|
|
27
|
+
secretKey: packet.readInt32BE(12),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (code !== PROTOCOL_3) {
|
|
31
|
+
throw new PostgresProtocolError(`Unsupported PostgreSQL protocol version ${code}`);
|
|
32
|
+
}
|
|
33
|
+
return { kind: "startup", protocol: code, parameters: parseParameters(packet.subarray(8)) };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Build a PostgreSQL SSL negotiation request packet. */
|
|
37
|
+
export function sslRequest() {
|
|
38
|
+
return requestPacket(SSL_REQUEST);
|
|
39
|
+
}
|
|
40
|
+
/** Build a PostgreSQL cancellation request packet. */
|
|
41
|
+
export function cancelRequest(processId, secretKey) {
|
|
42
|
+
return requestPacket(CANCEL_REQUEST, processId, secretKey);
|
|
43
|
+
}
|
|
44
|
+
/** Build the backend messages that complete PostgreSQL startup. */
|
|
45
|
+
export function startupComplete(parameters, processId, secretKey, transactionStatus = "I") {
|
|
46
|
+
return Buffer.concat([
|
|
47
|
+
backendMessage("R", int32(0)),
|
|
48
|
+
...[...parameters].map(([name, value]) => backendMessage("S", Buffer.from(`${name}\0${value}\0`))),
|
|
49
|
+
backendMessage("K", Buffer.concat([int32(processId), int32(secretKey)])),
|
|
50
|
+
backendMessage("Z", Buffer.from(transactionStatus.slice(0, 1) || "I")),
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
/** Replace client startup identity with the resolved upstream identity. */
|
|
54
|
+
export function upstreamStartupParameters(parameters, user, database) {
|
|
55
|
+
return { ...parameters, user, database };
|
|
56
|
+
}
|
|
57
|
+
/** Build a fatal PostgreSQL error response. */
|
|
58
|
+
export function fatalError(message, sqlstate = "08001") {
|
|
59
|
+
return backendMessage("E", Buffer.concat([Buffer.from(`SFATAL\0C${sqlstate}\0M${message}\0`), Buffer.from([0])]));
|
|
60
|
+
}
|
|
61
|
+
function requestPacket(code, processId, secretKey) {
|
|
62
|
+
const values = [code];
|
|
63
|
+
if (processId !== undefined && secretKey !== undefined)
|
|
64
|
+
values.push(processId, secretKey);
|
|
65
|
+
return Buffer.concat([int32(4 + values.length * 4), ...values.map(int32)]);
|
|
66
|
+
}
|
|
67
|
+
function backendMessage(code, body) {
|
|
68
|
+
return Buffer.concat([Buffer.from(code), int32(body.length + 4), body]);
|
|
69
|
+
}
|
|
70
|
+
function int32(value) {
|
|
71
|
+
const buffer = Buffer.allocUnsafe(4);
|
|
72
|
+
buffer.writeInt32BE(value);
|
|
73
|
+
return buffer;
|
|
74
|
+
}
|
|
75
|
+
async function readPacket(socket, deadline) {
|
|
76
|
+
let buffer = Buffer.alloc(0);
|
|
77
|
+
while (buffer.length < 4)
|
|
78
|
+
buffer = Buffer.concat([buffer, await readChunk(socket, deadline)]);
|
|
79
|
+
const length = buffer.readInt32BE(0);
|
|
80
|
+
if (length < 8 || length > 1024 * 1024) {
|
|
81
|
+
throw new PostgresProtocolError("Invalid PostgreSQL startup packet");
|
|
82
|
+
}
|
|
83
|
+
while (buffer.length < length) {
|
|
84
|
+
buffer = Buffer.concat([buffer, await readChunk(socket, deadline)]);
|
|
85
|
+
}
|
|
86
|
+
const remainder = buffer.subarray(length);
|
|
87
|
+
if (remainder.length)
|
|
88
|
+
socket.unshift(remainder);
|
|
89
|
+
return buffer.subarray(0, length);
|
|
90
|
+
}
|
|
91
|
+
function readChunk(socket, deadline) {
|
|
92
|
+
const remaining = deadline - Date.now();
|
|
93
|
+
if (remaining <= 0) {
|
|
94
|
+
return Promise.reject(new PostgresProtocolError("PostgreSQL startup timed out"));
|
|
95
|
+
}
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const timer = setTimeout(() => finish(new PostgresProtocolError("PostgreSQL startup timed out")), remaining);
|
|
98
|
+
const onData = (chunk) => finish(undefined, chunk);
|
|
99
|
+
const onError = (error) => finish(error);
|
|
100
|
+
const onEnd = () => finish(new PostgresProtocolError("PostgreSQL client closed during startup"));
|
|
101
|
+
const finish = (error, chunk) => {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
socket.off("data", onData);
|
|
104
|
+
socket.off("error", onError);
|
|
105
|
+
socket.off("end", onEnd);
|
|
106
|
+
if (error)
|
|
107
|
+
reject(error);
|
|
108
|
+
else
|
|
109
|
+
resolve(chunk);
|
|
110
|
+
};
|
|
111
|
+
socket.once("data", onData);
|
|
112
|
+
socket.once("error", onError);
|
|
113
|
+
socket.once("end", onEnd);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function parseParameters(body) {
|
|
117
|
+
const values = body.toString("utf8").split("\0");
|
|
118
|
+
const parameters = {};
|
|
119
|
+
for (let index = 0; index + 1 < values.length && values[index]; index += 2) {
|
|
120
|
+
parameters[values[index]] = values[index + 1] ?? "";
|
|
121
|
+
}
|
|
122
|
+
return parameters;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGFrZWJhc2UtcHJveHkvcHJvdG9jb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEVBQTBFO0FBSTFFLDJDQUEyQztBQUMzQyxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDO0FBQ3RDLDhDQUE4QztBQUM5QyxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDO0FBQ3pDLDBDQUEwQztBQUMxQyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDO0FBbUJsQywyRUFBMkU7QUFDM0UsTUFBTSxPQUFPLHFCQUFzQixTQUFRLEtBQUs7Q0FBRztBQUVuRCw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLEtBQUssVUFBVSxrQkFBa0IsQ0FDdEMsTUFBYyxFQUNkLFNBQWlCO0lBRWpCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUM7SUFDeEMsU0FBUyxDQUFDO1FBQ1IsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDekIsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNsQixTQUFTO1FBQ1gsQ0FBQztRQUNELElBQUksSUFBSSxLQUFLLGNBQWMsRUFBRSxDQUFDO1lBQzVCLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxFQUFFO2dCQUFFLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQzFGLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsU0FBUyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFD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bHBlcnMgZm9yIHRoZSBsb29wYmFjayBwcm94eS4gKi9cblxuaW1wb3J0IHR5cGUgeyBTb2NrZXQgfSBmcm9tIFwibm9kZTpuZXRcIjtcblxuLyoqIFBvc3RncmVTUUwgU1NMUmVxdWVzdCBwcm90b2NvbCBjb2RlLiAqL1xuZXhwb3J0IGNvbnN0IFNTTF9SRVFVRVNUID0gODBfODc3XzEwMztcbi8qKiBQb3N0Z3JlU1FMIENhbmNlbFJlcXVlc3QgcHJvdG9jb2wgY29kZS4gKi9cbmV4cG9ydCBjb25zdCBDQU5DRUxfUkVRVUVTVCA9IDgwXzg3N18xMDI7XG4vKiogUG9zdGdyZVNRTCBwcm90b2NvbCB2ZXJzaW9uIDMgY29kZS4gKi9cbmV4cG9ydCBjb25zdCBQUk9UT0NPTF8zID0gMTk2XzYwODtcblxuLyoqIFBhcnNlZCBQb3N0Z3JlU1FMIHN0YXJ0dXAgcGFja2V0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGFydHVwTWVzc2FnZSB7XG4gIGtpbmQ6IFwic3RhcnR1cFwiO1xuICBwcm90b2NvbDogbnVtYmVyO1xuICBwYXJhbWV0ZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufVxuXG4vKiogUGFyc2VkIFBvc3RncmVTUUwgY2FuY2VsbGF0aW9uIHBhY2tldC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuY2VsTWVzc2FnZSB7XG4gIGtpbmQ6IFwiY2FuY2VsXCI7XG4gIHByb2Nlc3NJZDogbnVtYmVyO1xuICBzZWNyZXRLZXk6IG51bWJlcjtcbn1cblxuLyoqIEZpcnN0IHN1cHBvcnRlZCBwYWNrZXQgcmVjZWl2ZWQgZnJvbSBhIFBvc3RncmVTUUwgY2xpZW50LiAqL1xuZXhwb3J0IHR5cGUgSW5pdGlhbE1lc3NhZ2UgPSBTdGFydHVwTWVzc2FnZSB8IENhbmNlbE1lc3NhZ2U7XG5cbi8qKiBFcnJvciBjYXVzZWQgYnkgYW4gaW52YWxpZCBvciB1bnN1cHBvcnRlZCBQb3N0Z3JlU1FMIHN0YXJ0dXAgcGFja2V0LiAqL1xuZXhwb3J0IGNsYXNzIFBvc3RncmVzUHJvdG9jb2xFcnJvciBleHRlbmRzIEVycm9yIHt9XG5cbi8qKiBSZWFkIGFuZCBjbGFzc2lmeSB0aGUgZmlyc3QgUG9zdGdyZVNRTCBmcm9udGVuZCBtZXNzYWdlIGZyb20gYSBzb2NrZXQuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEluaXRpYWxNZXNzYWdlKFxuICBzb2NrZXQ6IFNvY2tldCxcbiAgdGltZW91dE1zOiBudW1iZXIsXG4pOiBQcm9taXNlPEluaXRpYWxNZXNzYWdlPiB7XG4gIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIHRpbWVvdXRNcztcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHBhY2tldCA9IGF3YWl0IHJlYWRQYWNrZXQoc29ja2V0LCBkZWFkbGluZSk7XG4gICAgY29uc3QgY29kZSA9IHBhY2tldC5yZWFkSW50MzJCRSg0KTtcbiAgICBpZiAoY29kZSA9PT0gU1NMX1JFUVVFU1QpIHtcbiAgICAgIHNvY2tldC53cml0ZShcIk5cIik7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGNvZGUgPT09IENBTkNFTF9SRVFVRVNUKSB7XG4gICAgICBpZiAocGFja2V0Lmxlbmd0aCAhPT0gMTYpIHRocm93IG5ldyBQb3N0Z3Jlc1Byb3RvY29sRXJyb3IoXCJJbnZhbGlkIENhbmNlbFJlcXVlc3QgcGFja2V0XCIpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2luZDogXCJjYW5jZWxcIixcbiAgICAgICAgcHJvY2Vzc0lkOiBwYWNrZXQucmVhZEludDMyQkUoOCksXG4gICAgICAgIHNlY3JldEtleTogcGFja2V0LnJlYWRJbnQzMkJFKDEyKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChjb2RlICE9PSBQUk9UT0NPTF8zKSB7XG4gICAgICB0aHJvdyBuZXcgUG9zdGdyZXNQcm90b2NvbEVycm9yKGBVbnN1cHBvcnRlZCBQb3N0Z3JlU1FMIHByb3RvY29sIHZlcnNpb24gJHtjb2RlfWApO1xuICAgIH1cbiAgICByZXR1cm4geyBraW5kOiBcInN0YXJ0dXBcIiwgcHJvdG9jb2w6IGNvZGUsIHBhcmFtZXRlcnM6IHBhcnNlUGFyYW1ldGVycyhwYWNrZXQuc3ViYXJyYXkoOCkpIH07XG4gIH1cbn1cblxuLyoqIEJ1aWxkIGEgUG9zdGdyZVNRTCBTU0wgbmVnb3RpYXRpb24gcmVxdWVzdCBwYWNrZXQuICovXG5leHBvcnQgZnVuY3Rpb24gc3NsUmVxdWVzdCgpOiBCdWZmZXIge1xuICByZXR1cm4gcmVxdWVzdFBhY2tldChTU0xfUkVRVUVTVCk7XG59XG5cbi8qKiBCdWlsZCBhIFBvc3RncmVTUUwgY2FuY2VsbGF0aW9uIHJlcXVlc3QgcGFja2V0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbmNlbFJlcXVlc3QocHJvY2Vzc0lkOiBudW1iZXIsIHNlY3JldEtleTogbnVtYmVyKTogQnVmZmVyIHtcbiAgcmV0dXJuIHJlcXVlc3RQYWNrZXQoQ0FOQ0VMX1JFUVVFU1QsIHByb2Nlc3NJZCwgc2VjcmV0S2V5KTtcbn1cblxuLyoqIEJ1aWxkIHRoZSBiYWNrZW5kIG1lc3NhZ2VzIHRoYXQgY29tcGxldGUgUG9zdGdyZVNRTCBzdGFydHVwLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0dXBDb21wbGV0ZShcbiAgcGFyYW1ldGVyczogUmVhZG9ubHlNYXA8c3RyaW5nLCBzdHJpbmc+LFxuICBwcm9jZXNzSWQ6IG51bWJlcixcbiAgc2VjcmV0S2V5OiBudW1iZXIsXG4gIHRyYW5zYWN0aW9uU3RhdHVzID0gXCJJXCIsXG4pOiBCdWZmZXIge1xuICByZXR1cm4gQnVmZmVyLmNvbmNhdChbXG4gICAgYmFja2VuZE1lc3NhZ2UoXCJSXCIsIGludDMyKDApKSxcbiAgICAuLi5bLi4ucGFyYW1ldGVyc10ubWFwKChbbmFtZSwgdmFsdWVdKSA9PlxuICAgICAgYmFja2VuZE1lc3NhZ2UoXCJTXCIsIEJ1ZmZlci5mcm9tKGAke25hbWV9XFwwJHt2YWx1ZX1cXDBgKSksXG4gICAgKSxcbiAgICBiYWNrZW5kTWVzc2FnZShcIktcIiwgQnVmZmVyLmNvbmNhdChbaW50MzIocHJvY2Vzc0lkKSwgaW50MzIoc2VjcmV0S2V5KV0pKSxcbiAgICBiYWNrZW5kTWVzc2FnZShcIlpcIiwgQnVmZmVyLmZyb20odHJhbnNhY3Rpb25TdGF0dXMuc2xpY2UoMCwgMSkgfHwgXCJJXCIpKSxcbiAgXSk7XG59XG5cbi8qKiBSZXBsYWNlIGNsaWVudCBzdGFydHVwIGlkZW50aXR5IHdpdGggdGhlIHJlc29sdmVkIHVwc3RyZWFtIGlkZW50aXR5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwc3RyZWFtU3RhcnR1cFBhcmFtZXRlcnMoXG4gIHBhcmFtZXRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gIHVzZXI6IHN0cmluZyxcbiAgZGF0YWJhc2U6IHN0cmluZyxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICByZXR1cm4geyAuLi5wYXJhbWV0ZXJzLCB1c2VyLCBkYXRhYmFzZSB9O1xufVxuXG4vKiogQnVpbGQgYSBmYXRhbCBQb3N0Z3JlU1FMIGVycm9yIHJlc3BvbnNlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhdGFsRXJyb3IobWVzc2FnZTogc3RyaW5nLCBzcWxzdGF0ZSA9IFwiMDgwMDFcIik6IEJ1ZmZlciB7XG4gIHJldHVybiBiYWNrZW5kTWVzc2FnZShcbiAgICBcIkVcIixcbiAgICBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShgU0ZBVEFMXFwwQyR7c3Fsc3RhdGV9XFwwTSR7bWVzc2FnZX1cXDBgKSwgQnVmZmVyLmZyb20oWzBdKV0pLFxuICApO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0UGFja2V0KGNvZGU6IG51bWJlciwgcHJvY2Vzc0lkPzogbnVtYmVyLCBzZWNyZXRLZXk/OiBudW1iZXIpOiBCdWZmZXIge1xuICBjb25zdCB2YWx1ZXMgPSBbY29kZV07XG4gIGlmIChwcm9jZXNzSWQgIT09IHVuZGVmaW5lZCAmJiBzZWNyZXRLZXkgIT09IHVuZGVmaW5lZCkgdmFsdWVzLnB1c2gocHJvY2Vzc0lkLCBzZWNyZXRLZXkpO1xuICByZXR1cm4gQnVmZmVyLmNvbmNhdChbaW50MzIoNCArIHZhbHVlcy5sZW5ndGggKiA0KSwgLi4udmFsdWVzLm1hcChpbnQzMildKTtcbn1cblxuZnVuY3Rpb24gYmFja2VuZE1lc3NhZ2UoY29kZTogc3RyaW5nLCBib2R5OiBCdWZmZXIpOiBCdWZmZXIge1xuICByZXR1cm4gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oY29kZSksIGludDMyKGJvZHkubGVuZ3RoICsgNCksIGJvZHldKTtcbn1cblxuZnVuY3Rpb24gaW50MzIodmFsdWU6IG51bWJlcik6IEJ1ZmZlciB7XG4gIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg0KTtcbiAgYnVmZmVyLndyaXRlSW50MzJCRSh2YWx1ZSk7XG4gIHJldHVybiBidWZmZXI7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRQYWNrZXQoc29ja2V0OiBTb2NrZXQsIGRlYWRsaW5lOiBudW1iZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBsZXQgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xuICB3aGlsZSAoYnVmZmVyLmxlbmd0aCA8IDQpIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2J1ZmZlciwgYXdhaXQgcmVhZENodW5rKHNvY2tldCwgZGVhZGxpbmUpXSk7XG4gIGNvbnN0IGxlbmd0aCA9IGJ1ZmZlci5yZWFkSW50MzJCRSgwKTtcbiAgaWYgKGxlbmd0aCA8IDggfHwgbGVuZ3RoID4gMTAyNCAqIDEwMjQpIHtcbiAgICB0aHJvdyBuZXcgUG9zdGdyZXNQcm90b2NvbEVycm9yKFwiSW52YWxpZCBQb3N0Z3JlU1FMIHN0YXJ0dXAgcGFja2V0XCIpO1xuICB9XG4gIHdoaWxlIChidWZmZXIubGVuZ3RoIDwgbGVuZ3RoKSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYnVmZmVyLCBhd2FpdCByZWFkQ2h1bmsoc29ja2V0LCBkZWFkbGluZSldKTtcbiAgfVxuICBjb25zdCByZW1haW5kZXIgPSBidWZmZXIuc3ViYXJyYXkobGVuZ3RoKTtcbiAgaWYgKHJlbWFpbmRlci5sZW5ndGgpIHNvY2tldC51bnNoaWZ0KHJlbWFpbmRlcik7XG4gIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgbGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gcmVhZENodW5rKHNvY2tldDogU29ja2V0LCBkZWFkbGluZTogbnVtYmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgY29uc3QgcmVtYWluaW5nID0gZGVhZGxpbmUgLSBEYXRlLm5vdygpO1xuICBpZiAocmVtYWluaW5nIDw9IDApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBvc3RncmVzUHJvdG9jb2xFcnJvcihcIlBvc3RncmVTUUwgc3RhcnR1cCB0aW1lZCBvdXRcIikpO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gZmluaXNoKG5ldyBQb3N0Z3Jlc1Byb3RvY29sRXJyb3IoXCJQb3N0Z3JlU1FMIHN0YXJ0dXAgdGltZWQgb3V0XCIpKSxcbiAgICAgIHJlbWFpbmluZyxcbiAgICApO1xuICAgIGNvbnN0IG9uRGF0YSA9IChjaHVuazogQnVmZmVyKSA9PiBmaW5pc2godW5kZWZpbmVkLCBjaHVuayk7XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IGZpbmlzaChlcnJvcik7XG4gICAgY29uc3Qgb25FbmQgPSAoKSA9PlxuICAgICAgZmluaXNoKG5ldyBQb3N0Z3Jlc1Byb3RvY29sRXJyb3IoXCJQb3N0Z3JlU1FMIGNsaWVudCBjbG9zZWQgZHVyaW5nIHN0YXJ0dXBcIikpO1xuICAgIGNvbnN0IGZpbmlzaCA9IChlcnJvcj86IEVycm9yLCBjaHVuaz86IEJ1ZmZlcikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHNvY2tldC5vZmYoXCJkYXRhXCIsIG9uRGF0YSk7XG4gICAgICBzb2NrZXQub2ZmKFwiZXJyb3JcIiwgb25FcnJvcik7XG4gICAgICBzb2NrZXQub2ZmKFwiZW5kXCIsIG9uRW5kKTtcbiAgICAgIGlmIChlcnJvcikgcmVqZWN0KGVycm9yKTtcbiAgICAgIGVsc2UgcmVzb2x2ZShjaHVuayEpO1xuICAgIH07XG4gICAgc29ja2V0Lm9uY2UoXCJkYXRhXCIsIG9uRGF0YSk7XG4gICAgc29ja2V0Lm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICBzb2NrZXQub25jZShcImVuZFwiLCBvbkVuZCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtZXRlcnMoYm9keTogQnVmZmVyKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IHZhbHVlcyA9IGJvZHkudG9TdHJpbmcoXCJ1dGY4XCIpLnNwbGl0KFwiXFwwXCIpO1xuICBjb25zdCBwYXJhbWV0ZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggKyAxIDwgdmFsdWVzLmxlbmd0aCAmJiB2YWx1ZXNbaW5kZXhdOyBpbmRleCArPSAyKSB7XG4gICAgcGFyYW1ldGVyc1t2YWx1ZXNbaW5kZXhdIV0gPSB2YWx1ZXNbaW5kZXggKyAxXSA/PyBcIlwiO1xuICB9XG4gIHJldHVybiBwYXJhbWV0ZXJzO1xufVxuIl19
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Pure Node PostgreSQL wire proxy for Databricks Lakebase. */
|
|
2
|
+
import { type LakebaseProxyOptions } from "./options.ts";
|
|
3
|
+
/** Loopback PostgreSQL wire proxy backed by Databricks Lakebase credentials. */
|
|
4
|
+
export declare class LakebaseProxy {
|
|
5
|
+
private readonly client;
|
|
6
|
+
private readonly options;
|
|
7
|
+
private readonly cancellations;
|
|
8
|
+
private server?;
|
|
9
|
+
private statsTimer?;
|
|
10
|
+
private opened;
|
|
11
|
+
private closed;
|
|
12
|
+
private failed;
|
|
13
|
+
private active;
|
|
14
|
+
constructor(options?: LakebaseProxyOptions);
|
|
15
|
+
listen(): Promise<{
|
|
16
|
+
host: string;
|
|
17
|
+
port: number;
|
|
18
|
+
}>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
private handle;
|
|
21
|
+
private reportStats;
|
|
22
|
+
}
|