@crvouga/mockingbird-service-postgres 1.0.0 → 1.2.0
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/AGENTS.md +8 -2
- package/CHANGELOG.md +20 -0
- package/COMPATIBILITY.md +1 -1
- package/README.md +65 -13
- package/dist/wire/cli.d.ts +2 -0
- package/dist/wire/cli.js +23770 -0
- package/dist/wire/cli.js.map +7 -0
- package/dist/wire/cluster.d.ts +71 -0
- package/dist/wire/connection.d.ts +107 -0
- package/dist/wire/index.d.ts +69 -0
- package/dist/wire/index.js +23715 -0
- package/dist/wire/index.js.map +7 -0
- package/dist/wire/protocol.d.ts +119 -0
- package/dist/wire/scram.d.ts +17 -0
- package/dist/wire/split.d.ts +6 -0
- package/package.json +18 -5
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL frontend/backend protocol 3.0 message framing: the byte codec only, no behavior.
|
|
3
|
+
* https://www.postgresql.org/docs/18/protocol-message-formats.html
|
|
4
|
+
*/
|
|
5
|
+
export declare const SSL_REQUEST_CODE = 80877103;
|
|
6
|
+
export declare const GSSENC_REQUEST_CODE = 80877104;
|
|
7
|
+
export declare const CANCEL_REQUEST_CODE = 80877102;
|
|
8
|
+
export declare const PROTOCOL_3_0 = 196608;
|
|
9
|
+
/** Growable big-endian byte builder for one or more backend messages. */
|
|
10
|
+
export declare class ByteWriter {
|
|
11
|
+
private buf;
|
|
12
|
+
private view;
|
|
13
|
+
private len;
|
|
14
|
+
private ensure;
|
|
15
|
+
u8(value: number): this;
|
|
16
|
+
i16(value: number): this;
|
|
17
|
+
i32(value: number): this;
|
|
18
|
+
bytes(value: Uint8Array): this;
|
|
19
|
+
/** A NUL-terminated string. */
|
|
20
|
+
cstring(value: string): this;
|
|
21
|
+
get length(): number;
|
|
22
|
+
take(): Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
/** One backend message: type byte, int32 length (including itself), body. */
|
|
25
|
+
export declare const message: (type: string, body: (w: ByteWriter) => void) => Uint8Array;
|
|
26
|
+
export type FieldDescription = {
|
|
27
|
+
name: string;
|
|
28
|
+
tableOid?: number;
|
|
29
|
+
columnAttr?: number;
|
|
30
|
+
typeOid: number;
|
|
31
|
+
typeLen: number;
|
|
32
|
+
typeMod?: number;
|
|
33
|
+
/** 0 text, 1 binary. */
|
|
34
|
+
format: 0 | 1;
|
|
35
|
+
};
|
|
36
|
+
export type ErrorFields = {
|
|
37
|
+
severity?: "ERROR" | "FATAL" | "PANIC" | "WARNING" | "NOTICE";
|
|
38
|
+
code: string;
|
|
39
|
+
message: string;
|
|
40
|
+
detail?: string;
|
|
41
|
+
hint?: string;
|
|
42
|
+
position?: number;
|
|
43
|
+
constraint?: string;
|
|
44
|
+
table?: string;
|
|
45
|
+
column?: string;
|
|
46
|
+
schema?: string;
|
|
47
|
+
};
|
|
48
|
+
export declare const backend: {
|
|
49
|
+
authenticationOk: () => Uint8Array<ArrayBufferLike>;
|
|
50
|
+
authenticationSASL: (mechanisms: string[]) => Uint8Array<ArrayBufferLike>;
|
|
51
|
+
authenticationSASLContinue: (data: string) => Uint8Array<ArrayBufferLike>;
|
|
52
|
+
authenticationSASLFinal: (data: string) => Uint8Array<ArrayBufferLike>;
|
|
53
|
+
parameterStatus: (name: string, value: string) => Uint8Array<ArrayBufferLike>;
|
|
54
|
+
backendKeyData: (pid: number, key: number) => Uint8Array<ArrayBufferLike>;
|
|
55
|
+
readyForQuery: (status: "I" | "T" | "E") => Uint8Array<ArrayBufferLike>;
|
|
56
|
+
rowDescription: (fields: FieldDescription[]) => Uint8Array<ArrayBufferLike>;
|
|
57
|
+
dataRow: (values: (Uint8Array | null)[]) => Uint8Array<ArrayBufferLike>;
|
|
58
|
+
commandComplete: (tag: string) => Uint8Array<ArrayBufferLike>;
|
|
59
|
+
emptyQueryResponse: () => Uint8Array<ArrayBufferLike>;
|
|
60
|
+
errorResponse: (fields: ErrorFields) => Uint8Array<ArrayBufferLike>;
|
|
61
|
+
noticeResponse: (fields: ErrorFields) => Uint8Array<ArrayBufferLike>;
|
|
62
|
+
parseComplete: () => Uint8Array<ArrayBufferLike>;
|
|
63
|
+
bindComplete: () => Uint8Array<ArrayBufferLike>;
|
|
64
|
+
closeComplete: () => Uint8Array<ArrayBufferLike>;
|
|
65
|
+
noData: () => Uint8Array<ArrayBufferLike>;
|
|
66
|
+
portalSuspended: () => Uint8Array<ArrayBufferLike>;
|
|
67
|
+
parameterDescription: (oids: number[]) => Uint8Array<ArrayBufferLike>;
|
|
68
|
+
notificationResponse: (pid: number, channel: string, payload: string) => Uint8Array<ArrayBufferLike>;
|
|
69
|
+
/** The one-byte answers to SSLRequest / GSSENCRequest: no encryption here. */
|
|
70
|
+
no: () => Uint8Array<ArrayBuffer>;
|
|
71
|
+
};
|
|
72
|
+
/** Sequential reader over one message body. */
|
|
73
|
+
export declare class ByteReader {
|
|
74
|
+
readonly bytes: Uint8Array;
|
|
75
|
+
private pos;
|
|
76
|
+
private readonly view;
|
|
77
|
+
constructor(bytes: Uint8Array, start?: number);
|
|
78
|
+
get remaining(): number;
|
|
79
|
+
u8(): number;
|
|
80
|
+
i16(): number;
|
|
81
|
+
i32(): number;
|
|
82
|
+
take(n: number): Uint8Array;
|
|
83
|
+
cstring(): string;
|
|
84
|
+
rest(): Uint8Array;
|
|
85
|
+
}
|
|
86
|
+
export declare class ProtocolError extends Error {
|
|
87
|
+
constructor(message: string);
|
|
88
|
+
}
|
|
89
|
+
export type FrontendMessage = {
|
|
90
|
+
kind: "ssl";
|
|
91
|
+
} | {
|
|
92
|
+
kind: "gssenc";
|
|
93
|
+
} | {
|
|
94
|
+
kind: "cancel";
|
|
95
|
+
pid: number;
|
|
96
|
+
key: number;
|
|
97
|
+
} | {
|
|
98
|
+
kind: "startup";
|
|
99
|
+
protocol: number;
|
|
100
|
+
parameters: Record<string, string>;
|
|
101
|
+
} | {
|
|
102
|
+
kind: "typed";
|
|
103
|
+
type: string;
|
|
104
|
+
body: ByteReader;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Splits a byte stream into frontend messages. Before the startup message is seen, frames have
|
|
108
|
+
* no type byte (StartupMessage, SSLRequest, GSSENCRequest, CancelRequest).
|
|
109
|
+
*/
|
|
110
|
+
export declare class FrameParser {
|
|
111
|
+
private pending;
|
|
112
|
+
private started;
|
|
113
|
+
push(chunk: Uint8Array): FrontendMessage[];
|
|
114
|
+
private next;
|
|
115
|
+
}
|
|
116
|
+
export declare const utf8: {
|
|
117
|
+
encode: (s: string) => Uint8Array;
|
|
118
|
+
decode: (b: Uint8Array) => string;
|
|
119
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server side of SCRAM-SHA-256 (RFC 7677) as PostgreSQL speaks it: one round trip after the
|
|
3
|
+
* client's first message, channel binding declined (`n` or `y`; no TLS here).
|
|
4
|
+
*/
|
|
5
|
+
export declare class ScramServer {
|
|
6
|
+
private readonly password;
|
|
7
|
+
private clientFirstBare;
|
|
8
|
+
private serverFirst;
|
|
9
|
+
private nonce;
|
|
10
|
+
private readonly salt;
|
|
11
|
+
private readonly iterations;
|
|
12
|
+
constructor(password: string);
|
|
13
|
+
/** The server-first-message for a client-first-message; null when the client message is malformed. */
|
|
14
|
+
first(clientFirst: string): string | null;
|
|
15
|
+
/** The server-final-message (`v=…`) when the client's proof is right; null otherwise. */
|
|
16
|
+
final(clientFinal: string): string | null;
|
|
17
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a simple-query script into statements at top-level semicolons, the way the server's
|
|
3
|
+
* lexer would: quoted strings (`'…'`, `E'…'` with backslashes, `"…"`), dollar quoting
|
|
4
|
+
* (`$tag$…$tag$`), line and (nested) block comments never split. Empty statements are dropped.
|
|
5
|
+
*/
|
|
6
|
+
export declare const splitStatements: (script: string) => string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crvouga/mockingbird-service-postgres",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Pure TypeScript in-memory PostgreSQL implementation with zero WASM/native dependencies",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"types": "./dist/unstable.d.ts",
|
|
23
23
|
"import": "./dist/unstable.js",
|
|
24
24
|
"default": "./dist/unstable.js"
|
|
25
|
+
},
|
|
26
|
+
"./wire": {
|
|
27
|
+
"types": "./dist/wire/index.d.ts",
|
|
28
|
+
"import": "./dist/wire/index.js",
|
|
29
|
+
"default": "./dist/wire/index.js"
|
|
25
30
|
}
|
|
26
31
|
},
|
|
27
32
|
"files": [
|
|
@@ -49,7 +54,7 @@
|
|
|
49
54
|
},
|
|
50
55
|
"scripts": {
|
|
51
56
|
"build": "bun run scripts/build.ts",
|
|
52
|
-
"test": "bun test tests/contract tests/fuzz tests/harness",
|
|
57
|
+
"test": "bun test tests/contract tests/fuzz tests/harness tests/server",
|
|
53
58
|
"test:contract": "bun test tests/contract",
|
|
54
59
|
"test:fuzz": "bun test tests/fuzz",
|
|
55
60
|
"test:pbt": "bun test tests/fuzz",
|
|
@@ -87,7 +92,8 @@
|
|
|
87
92
|
"portability": "bun ../../../scripts/portability.ts",
|
|
88
93
|
"example:react-vite": "cd examples/react-vite && bun install && bun run dev",
|
|
89
94
|
"fc": "clear && bun format && bun check:full",
|
|
90
|
-
"test:postgres-native": "bun run scripts/run-postgres-native-tests.ts"
|
|
95
|
+
"test:postgres-native": "bun run scripts/run-postgres-native-tests.ts",
|
|
96
|
+
"test:server": "bun test tests/server"
|
|
91
97
|
},
|
|
92
98
|
"devDependencies": {
|
|
93
99
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -124,7 +130,11 @@
|
|
|
124
130
|
"website": "https://www.postgresql.org",
|
|
125
131
|
"docs": "https://www.postgresql.org/docs/current/"
|
|
126
132
|
},
|
|
127
|
-
"status": "ready"
|
|
133
|
+
"status": "ready",
|
|
134
|
+
"entries": {
|
|
135
|
+
"wire/index": "node",
|
|
136
|
+
"wire/cli": "node"
|
|
137
|
+
}
|
|
128
138
|
},
|
|
129
139
|
"trustedDependencies": [
|
|
130
140
|
"@embedded-postgres/darwin-arm64",
|
|
@@ -135,5 +145,8 @@
|
|
|
135
145
|
"@embedded-postgres/linux-ppc64",
|
|
136
146
|
"@embedded-postgres/linux-x64",
|
|
137
147
|
"@embedded-postgres/windows-x64"
|
|
138
|
-
]
|
|
148
|
+
],
|
|
149
|
+
"bin": {
|
|
150
|
+
"mockingbird-postgres": "./dist/wire/cli.js"
|
|
151
|
+
}
|
|
139
152
|
}
|