@tablecraft-app/plugin-api 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +46 -2
- package/dist/catalog.d.ts +112 -0
- package/dist/catalog.js +5 -0
- package/dist/completion.d.ts +109 -0
- package/dist/completion.js +12 -0
- package/dist/errors.d.ts +67 -0
- package/dist/errors.js +124 -0
- package/dist/explain.d.ts +58 -0
- package/dist/explain.js +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/inspection.d.ts +38 -0
- package/dist/inspection.js +21 -0
- package/dist/keyspace.d.ts +180 -0
- package/dist/keyspace.js +2 -0
- package/dist/manifest.d.ts +200 -0
- package/dist/manifest.js +238 -0
- package/dist/objects.d.ts +140 -0
- package/dist/objects.js +2 -0
- package/dist/plugin.d.ts +565 -0
- package/dist/plugin.js +58 -0
- package/dist/sessions.d.ts +59 -0
- package/dist/sessions.js +2 -0
- package/dist/sql/classify.d.ts +19 -0
- package/dist/sql/classify.js +95 -0
- package/dist/sql/complete.d.ts +23 -0
- package/dist/sql/complete.js +480 -0
- package/dist/sql/explain.d.ts +42 -0
- package/dist/sql/explain.js +108 -0
- package/dist/sql/format.d.ts +26 -0
- package/dist/sql/format.js +117 -0
- package/dist/sql/functions.d.ts +47 -0
- package/dist/sql/functions.js +159 -0
- package/dist/sql/generate.d.ts +22 -0
- package/dist/sql/generate.js +64 -0
- package/dist/sql/index.d.ts +16 -0
- package/dist/sql/index.js +16 -0
- package/dist/sql/inspect.d.ts +10 -0
- package/dist/sql/inspect.js +134 -0
- package/dist/sql/inspectContext.d.ts +78 -0
- package/dist/sql/inspectContext.js +251 -0
- package/dist/sql/inspectResolve.d.ts +6 -0
- package/dist/sql/inspectResolve.js +391 -0
- package/dist/sql/inspectStyle.d.ts +3 -0
- package/dist/sql/inspectStyle.js +384 -0
- package/dist/sql/inspectSyntax.d.ts +10 -0
- package/dist/sql/inspectSyntax.js +179 -0
- package/dist/sql/layout.d.ts +8 -0
- package/dist/sql/layout.js +114 -0
- package/dist/sql/layoutNodes.d.ts +46 -0
- package/dist/sql/layoutNodes.js +317 -0
- package/dist/sql/layoutPrint.d.ts +60 -0
- package/dist/sql/layoutPrint.js +806 -0
- package/dist/sql/layoutWriter.d.ts +21 -0
- package/dist/sql/layoutWriter.js +77 -0
- package/dist/sql/literals.d.ts +28 -0
- package/dist/sql/literals.js +78 -0
- package/dist/sql/namespace.d.ts +41 -0
- package/dist/sql/namespace.js +220 -0
- package/dist/sql/objects.d.ts +42 -0
- package/dist/sql/objects.js +222 -0
- package/dist/sql/parameters.d.ts +20 -0
- package/dist/sql/parameters.js +88 -0
- package/dist/sql/resolution.d.ts +73 -0
- package/dist/sql/resolution.js +192 -0
- package/dist/sql/routines.d.ts +27 -0
- package/dist/sql/routines.js +42 -0
- package/dist/sql/scope.d.ts +117 -0
- package/dist/sql/scope.js +540 -0
- package/dist/sql/select.d.ts +41 -0
- package/dist/sql/select.js +287 -0
- package/dist/sql/signature.d.ts +18 -0
- package/dist/sql/signature.js +137 -0
- package/dist/sql/splitter.d.ts +15 -0
- package/dist/sql/splitter.js +217 -0
- package/dist/sql/suggest.d.ts +6 -0
- package/dist/sql/suggest.js +36 -0
- package/dist/sql/tokens.d.ts +62 -0
- package/dist/sql/tokens.js +227 -0
- package/dist/sql/words.d.ts +23 -0
- package/dist/sql/words.js +72 -0
- package/dist/testing/index.d.ts +274 -0
- package/dist/testing/index.js +2398 -0
- package/dist/tls.d.ts +33 -0
- package/dist/tls.js +118 -0
- package/dist/url.d.ts +54 -0
- package/dist/url.js +228 -0
- package/dist/values.d.ts +44 -0
- package/dist/values.js +44 -0
- package/dist/version.d.ts +22 -0
- package/dist/version.js +29 -0
- package/package.json +42 -4
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { z, type DatasourcePlugin, type KeyChange, type KeyContents, type KeyType, type PluginManifest, type Routine, type RoutineArgument, type Row, type ServerMessage } from "@tablecraft-app/plugin-api";
|
|
2
|
+
export interface ContractFixture {
|
|
3
|
+
/** The plugin's parsed `table-craft-plugin.json`, whose connection form the suite checks. */
|
|
4
|
+
readonly manifest: PluginManifest;
|
|
5
|
+
/** Configuration that connects to a reachable, writable database seeded with `TYPE_PROBE_TABLE`. */
|
|
6
|
+
readonly config: unknown;
|
|
7
|
+
/** The same database with a wrong password; omitted by plugins that do not authenticate. */
|
|
8
|
+
readonly wrongPasswordConfig?: unknown;
|
|
9
|
+
readonly statements?: {
|
|
10
|
+
/** A statement that runs for `seconds`; required when the plugin declares `cancel`. */
|
|
11
|
+
readonly sleep?: (seconds: number) => string;
|
|
12
|
+
/**
|
|
13
|
+
* A write that succeeds on a writable session and leaves the fixture unchanged, such as an
|
|
14
|
+
* update setting a column to itself; the read-only case is skipped without one.
|
|
15
|
+
*/
|
|
16
|
+
readonly write?: string;
|
|
17
|
+
/**
|
|
18
|
+
* A statement the server answers with a warning or notice, and the level and code of the
|
|
19
|
+
* first one; required when the plugin declares `serverMessages`.
|
|
20
|
+
*/
|
|
21
|
+
readonly message?: {
|
|
22
|
+
readonly sql: string;
|
|
23
|
+
readonly level: ServerMessage["level"];
|
|
24
|
+
readonly code: string | null;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A statement with a syntax error and the 0-based offset the plugin's `PluginError.position`
|
|
28
|
+
* must resolve to; leave it out for a database that cannot locate one.
|
|
29
|
+
*/
|
|
30
|
+
readonly syntaxError?: {
|
|
31
|
+
readonly sql: string;
|
|
32
|
+
readonly offset: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** Required when the plugin declares `sql`. */
|
|
36
|
+
readonly typeProbe?: {
|
|
37
|
+
/** The rows of `SELECT * FROM type_probe ORDER BY id`, as wire values. */
|
|
38
|
+
readonly expected: readonly Row[];
|
|
39
|
+
/**
|
|
40
|
+
* Creates `TYPE_PROBE_COPY_TABLE` with `type_probe`'s columns and declared types; the literal
|
|
41
|
+
* round trip creates and drops it. `CREATE TABLE … AS` will not do where it drops declared types.
|
|
42
|
+
*/
|
|
43
|
+
readonly copyTable: string;
|
|
44
|
+
};
|
|
45
|
+
/** Scripts only this dialect splits, and the statements `language.split` must find in each. */
|
|
46
|
+
readonly scripts?: readonly SplitCase[];
|
|
47
|
+
/** Required when the plugin declares `schemaTree`. */
|
|
48
|
+
readonly catalog?: {
|
|
49
|
+
/** The namespace the fixture tables live in, which is also the connection's current one. */
|
|
50
|
+
readonly path: readonly string[];
|
|
51
|
+
/** An identifier that needs quoting, and what `qualifiedName(path, name)` must return for it. */
|
|
52
|
+
readonly quoted: {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly qualified: string;
|
|
55
|
+
};
|
|
56
|
+
/** `LINE_ITEMS_TABLE` as the dialect writes it in a statement, which completion must insert. */
|
|
57
|
+
readonly lineItems: string;
|
|
58
|
+
/** The name `orders`' check constraint carries, which its definition must show. */
|
|
59
|
+
readonly ordersCheck: string;
|
|
60
|
+
/** `customers`' table comment; null where the dialect has no comments. */
|
|
61
|
+
readonly customersComment: string | null;
|
|
62
|
+
};
|
|
63
|
+
/** Required when the plugin declares `currentNamespace`, which also needs `catalog`. */
|
|
64
|
+
readonly namespaceSwitch?: {
|
|
65
|
+
/** A statement that makes another namespace current, such as `USE archive`. */
|
|
66
|
+
readonly statement: string;
|
|
67
|
+
/** The path `currentNamespace` reports after it. */
|
|
68
|
+
readonly path: readonly string[];
|
|
69
|
+
/** A switch to a namespace that does not exist, where the dialect rejects one. */
|
|
70
|
+
readonly missing?: string;
|
|
71
|
+
};
|
|
72
|
+
/** Required when the plugin declares `commands` (decision 112). */
|
|
73
|
+
readonly commands?: CommandsFixture;
|
|
74
|
+
/** Required when the plugin declares `keyValue` (decision 113). */
|
|
75
|
+
readonly keyspace?: KeyspaceFixture;
|
|
76
|
+
/**
|
|
77
|
+
* Required when the plugin declares `sessions`, which also needs `statements.sleep`, and
|
|
78
|
+
* `statements.write` where it declares `transactions`.
|
|
79
|
+
*/
|
|
80
|
+
readonly sessions?: {
|
|
81
|
+
/** Connects as an account that sees every session and may stop any, such as a superuser. */
|
|
82
|
+
readonly monitorConfig: unknown;
|
|
83
|
+
/** What a listing shows as the sleeping statement's query; the statement itself by default. */
|
|
84
|
+
readonly sleepQuery?: string;
|
|
85
|
+
/** An account that sees only its own sessions, and what the listing's note must say about it. */
|
|
86
|
+
readonly limited?: {
|
|
87
|
+
readonly config: unknown;
|
|
88
|
+
readonly note: RegExp;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/** Required when the plugin declares `routineCall`, which also needs `catalog`. */
|
|
92
|
+
readonly routines?: {
|
|
93
|
+
/** Every routine the fixture seeds in `catalog.path`, as `describe` lists them. */
|
|
94
|
+
readonly expected: readonly Routine[];
|
|
95
|
+
/** A function given values, and the rows its call returns. */
|
|
96
|
+
readonly function: RoutineCase;
|
|
97
|
+
/** A call with one argument NULL, which must bind as SQL NULL. */
|
|
98
|
+
readonly nullArgument: RoutineCase;
|
|
99
|
+
/** A procedure whose OUT values come back as the last statement's rows. */
|
|
100
|
+
readonly procedureOut: RoutineCase;
|
|
101
|
+
/** A call that leaves a parameter to its default; omitted where the dialect has no defaults. */
|
|
102
|
+
readonly defaulted?: RoutineCase;
|
|
103
|
+
};
|
|
104
|
+
/** The statements whose text differs by dialect; each defaults to the text PostgreSQL, MySQL and SQLite accept. */
|
|
105
|
+
readonly sql?: ContractSql;
|
|
106
|
+
/**
|
|
107
|
+
* How the database stores an unquoted fixture name, such as Oracle's upper case; identity by
|
|
108
|
+
* default. `LINE_ITEMS_TABLE` is quoted in every dialect and never folded.
|
|
109
|
+
*/
|
|
110
|
+
readonly foldName?: (name: string) => string;
|
|
111
|
+
}
|
|
112
|
+
/** Dialect-specific text the suite runs; every member is optional (decision 100). */
|
|
113
|
+
export interface ContractSql {
|
|
114
|
+
/** A one-row query of `expressions`; Oracle adds `FROM DUAL`. */
|
|
115
|
+
readonly select?: (expressions: string) => string;
|
|
116
|
+
/** At least 100,000 rows; built from `select` by default. */
|
|
117
|
+
readonly largeResult?: string;
|
|
118
|
+
/** A join over `orders` and `customers` that plans with more than one step. */
|
|
119
|
+
readonly explainJoin?: string;
|
|
120
|
+
/** Replaces the scripts every other dialect splits the same way. */
|
|
121
|
+
readonly sharedScripts?: readonly SplitCase[];
|
|
122
|
+
/** Drops table `name` where it exists and does nothing where it does not. */
|
|
123
|
+
readonly dropTableIfExists?: (name: string) => string;
|
|
124
|
+
/** Creates a session-scoped table from `name`, and the name later statements reach it by. */
|
|
125
|
+
readonly temporaryTable?: (name: string, columns: string) => {
|
|
126
|
+
readonly create: string;
|
|
127
|
+
readonly name: string;
|
|
128
|
+
};
|
|
129
|
+
/** Opens a transaction explicitly in auto-commit mode. */
|
|
130
|
+
readonly begin?: string;
|
|
131
|
+
}
|
|
132
|
+
/** A command and the result tab it opens: column names and rows as wire values. */
|
|
133
|
+
export interface CommandRows {
|
|
134
|
+
readonly command: string;
|
|
135
|
+
readonly columns: readonly string[];
|
|
136
|
+
readonly rows: readonly Row[];
|
|
137
|
+
}
|
|
138
|
+
/** What a `commands` plugin's console runs against the fixture database (decision 112). */
|
|
139
|
+
export interface CommandsFixture {
|
|
140
|
+
/** Scripts the language splits, and the commands it must find in each. */
|
|
141
|
+
readonly scripts: readonly SplitCase[];
|
|
142
|
+
/** A command answered with one scalar, and the text Output shows for the reply. */
|
|
143
|
+
readonly scalar: {
|
|
144
|
+
readonly command: string;
|
|
145
|
+
readonly text: string;
|
|
146
|
+
};
|
|
147
|
+
/** A command answered with an array. */
|
|
148
|
+
readonly array: CommandRows;
|
|
149
|
+
/** A command answered with a map. */
|
|
150
|
+
readonly map: CommandRows;
|
|
151
|
+
/** A command answering bytes that are not UTF-8, and those bytes in hex. */
|
|
152
|
+
readonly binary: {
|
|
153
|
+
readonly command: string;
|
|
154
|
+
readonly hex: string;
|
|
155
|
+
};
|
|
156
|
+
/** A write a read-only session refuses, and the command name the refusal carries. */
|
|
157
|
+
readonly write: {
|
|
158
|
+
readonly command: string;
|
|
159
|
+
readonly name: string;
|
|
160
|
+
};
|
|
161
|
+
/** A command classified costly, and the text of the first quick fix its problem offers. */
|
|
162
|
+
readonly costly: {
|
|
163
|
+
readonly command: string;
|
|
164
|
+
readonly fixed: string;
|
|
165
|
+
};
|
|
166
|
+
/** A command classified destructive and confirmed by the datasource's name. */
|
|
167
|
+
readonly confirmByName: string;
|
|
168
|
+
}
|
|
169
|
+
/** The keys a `keyValue` plugin's fixture database carries (decision 113). */
|
|
170
|
+
export interface KeyspaceFixture {
|
|
171
|
+
/** The database the fixture keys live in. */
|
|
172
|
+
readonly database: number;
|
|
173
|
+
/** A glob, and how many keys it matches: enough for many scan batches. */
|
|
174
|
+
readonly scan: {
|
|
175
|
+
readonly match: string;
|
|
176
|
+
readonly count: number;
|
|
177
|
+
readonly batch: number;
|
|
178
|
+
};
|
|
179
|
+
/** A glob and a type, and the names of the keys of that type it matches. */
|
|
180
|
+
readonly typed: {
|
|
181
|
+
readonly match: string;
|
|
182
|
+
readonly type: KeyType;
|
|
183
|
+
readonly keys: readonly string[];
|
|
184
|
+
};
|
|
185
|
+
/** A key with an expiry. */
|
|
186
|
+
readonly expiring: string;
|
|
187
|
+
/** A key whose name is not valid UTF-8, as lower-case hex, a glob that finds it, and its value. */
|
|
188
|
+
readonly binary: {
|
|
189
|
+
readonly hex: string;
|
|
190
|
+
readonly match: string;
|
|
191
|
+
readonly type: KeyType;
|
|
192
|
+
readonly value: string;
|
|
193
|
+
};
|
|
194
|
+
/** A hash key and its first two columns' rows, in any order. */
|
|
195
|
+
readonly hash: KeyRowsFixture;
|
|
196
|
+
/** A sorted-set key and its member and score cells, in rank order. */
|
|
197
|
+
readonly zset: KeyRowsFixture;
|
|
198
|
+
/** A stream key, its columns and its rows, in id order. */
|
|
199
|
+
readonly stream: KeyRowsFixture & {
|
|
200
|
+
readonly columns: readonly string[];
|
|
201
|
+
};
|
|
202
|
+
/** A scratch key the suite creates, changes and removes. */
|
|
203
|
+
readonly edit: KeyEditFixture;
|
|
204
|
+
}
|
|
205
|
+
/** How the suite changes one element of a scratch key and reads it back (decision 115). */
|
|
206
|
+
export interface KeyEditFixture {
|
|
207
|
+
readonly key: string;
|
|
208
|
+
readonly type: KeyType;
|
|
209
|
+
/** A change setting the element to `value`, read as `original` (null: it did not exist). */
|
|
210
|
+
readonly change: (value: string, original: string | null) => KeyChange;
|
|
211
|
+
/** The element's value in what `read` returned; null when it is missing. */
|
|
212
|
+
readonly valueOf: (contents: KeyContents) => Promise<string | null>;
|
|
213
|
+
}
|
|
214
|
+
/** A key and the rows reading it gives. */
|
|
215
|
+
export interface KeyRowsFixture {
|
|
216
|
+
readonly key: string;
|
|
217
|
+
readonly rows: readonly Row[];
|
|
218
|
+
}
|
|
219
|
+
/** One routine call: which routine (from `routines.expected`), its arguments, and the rows it returns. */
|
|
220
|
+
export interface RoutineCase {
|
|
221
|
+
readonly name: string;
|
|
222
|
+
readonly kind: Routine["kind"];
|
|
223
|
+
readonly signature: string;
|
|
224
|
+
readonly args: readonly RoutineArgument[];
|
|
225
|
+
readonly rows: readonly Row[];
|
|
226
|
+
}
|
|
227
|
+
export interface SplitCase {
|
|
228
|
+
readonly text: string;
|
|
229
|
+
readonly statements: readonly string[];
|
|
230
|
+
}
|
|
231
|
+
/** The table every fixture database carries, one column per value rule the contract pins. */
|
|
232
|
+
export declare const TYPE_PROBE_TABLE = "type_probe";
|
|
233
|
+
/** Where the literal round trip inserts `type_probe`'s rows; created and dropped by the suite. */
|
|
234
|
+
export declare const TYPE_PROBE_COPY_TABLE = "type_probe_copy";
|
|
235
|
+
export declare const TYPE_PROBE_COLUMNS: readonly ["id", "small_int", "big_int", "exact_decimal", "unicode_text", "flag", "doc", "payload", "day", "moment"];
|
|
236
|
+
/** A fixture table whose name needs quoting in every dialect, for completion's quoting. */
|
|
237
|
+
export declare const LINE_ITEMS_TABLE = "Line Items";
|
|
238
|
+
/** The relations every fixture database carries, sorted by name as `describe` returns them. */
|
|
239
|
+
export declare const FIXTURE_RELATIONS: readonly [{
|
|
240
|
+
readonly name: "customer_totals";
|
|
241
|
+
readonly kind: "view";
|
|
242
|
+
}, {
|
|
243
|
+
readonly name: "customers";
|
|
244
|
+
readonly kind: "table";
|
|
245
|
+
}, {
|
|
246
|
+
readonly name: "orders";
|
|
247
|
+
readonly kind: "table";
|
|
248
|
+
}, {
|
|
249
|
+
readonly name: "edit_probe";
|
|
250
|
+
readonly kind: "table";
|
|
251
|
+
}, {
|
|
252
|
+
readonly name: "no_key_probe";
|
|
253
|
+
readonly kind: "table";
|
|
254
|
+
}, {
|
|
255
|
+
readonly name: "type_probe";
|
|
256
|
+
readonly kind: "table";
|
|
257
|
+
}, {
|
|
258
|
+
readonly name: "Line Items";
|
|
259
|
+
readonly kind: "table";
|
|
260
|
+
}];
|
|
261
|
+
/** The data editor's table (decision 026): a serial key and a default for every other column. */
|
|
262
|
+
export declare const EDIT_PROBE_TABLE = "edit_probe";
|
|
263
|
+
/** The statements the suite runs for `fixture`, each default filled in. */
|
|
264
|
+
export declare function contractSql(fixture: Pick<ContractFixture, "sql">): Required<ContractSql>;
|
|
265
|
+
/**
|
|
266
|
+
* Where a manifest's connection form and the plugin's `connectionSchema` disagree (decision 019),
|
|
267
|
+
* one sentence per problem; empty when they agree.
|
|
268
|
+
*/
|
|
269
|
+
export declare function connectionFormProblems(manifest: PluginManifest, connectionSchema: z.ZodType): string[];
|
|
270
|
+
/**
|
|
271
|
+
* The behaviour every plugin owes the host, gated on the capabilities it declares (decision 013).
|
|
272
|
+
* Call it from a Vitest file; it registers one `describe` block.
|
|
273
|
+
*/
|
|
274
|
+
export declare function runPluginContract(plugin: DatasourcePlugin, fixture: ContractFixture): void;
|