shelving 1.179.2 → 1.180.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.
Files changed (48) hide show
  1. package/api/endpoint/Endpoint.d.ts +3 -3
  2. package/api/endpoint/util.d.ts +13 -7
  3. package/api/endpoint/util.js +6 -7
  4. package/api/index.d.ts +1 -0
  5. package/api/index.js +1 -0
  6. package/api/provider/MockEnpdointAPIProvider.d.ts +16 -0
  7. package/api/provider/MockEnpdointAPIProvider.js +18 -0
  8. package/bun/BunPostgreSQLProvider.d.ts +10 -0
  9. package/bun/BunPostgreSQLProvider.js +16 -0
  10. package/bun/index.d.ts +1 -0
  11. package/bun/index.js +1 -0
  12. package/cloudflare/CloudflareD1Provider.d.ts +14 -0
  13. package/cloudflare/CloudflareD1Provider.js +56 -0
  14. package/cloudflare/CloudflareKVProvider.d.ts +2 -9
  15. package/cloudflare/CloudflareKVProvider.js +1 -1
  16. package/cloudflare/index.d.ts +2 -0
  17. package/cloudflare/index.js +2 -0
  18. package/cloudflare/types.d.ts +44 -0
  19. package/cloudflare/types.js +1 -0
  20. package/db/collection/Collection.d.ts +2 -2
  21. package/db/index.d.ts +7 -0
  22. package/db/index.js +7 -0
  23. package/db/migrate/DBMigrator.d.ts +8 -0
  24. package/db/migrate/DBMigrator.js +7 -0
  25. package/db/migrate/PostgreSQLMigrator.d.ts +37 -0
  26. package/db/migrate/PostgreSQLMigrator.js +207 -0
  27. package/db/migrate/SQLMigrator.d.ts +52 -0
  28. package/db/migrate/SQLMigrator.js +193 -0
  29. package/db/migrate/SQLiteMigrator.d.ts +15 -0
  30. package/db/migrate/SQLiteMigrator.js +124 -0
  31. package/db/provider/PostgreSQLProvider.d.ts +12 -0
  32. package/db/provider/PostgreSQLProvider.js +72 -0
  33. package/db/provider/SQLProvider.d.ts +69 -0
  34. package/db/provider/SQLProvider.js +190 -0
  35. package/db/provider/SQLiteProvider.d.ts +18 -0
  36. package/db/provider/SQLiteProvider.js +106 -0
  37. package/db/store/QueryStore.js +2 -2
  38. package/error/BaseError.js +1 -1
  39. package/firestore/client/FirestoreClientProvider.js +16 -10
  40. package/firestore/lite/FirestoreLiteProvider.js +16 -10
  41. package/firestore/server/FirestoreServerProvider.js +16 -10
  42. package/package.json +4 -3
  43. package/util/data.d.ts +52 -14
  44. package/util/data.js +9 -2
  45. package/util/query.d.ts +32 -26
  46. package/util/query.js +52 -33
  47. package/util/update.d.ts +9 -9
  48. package/util/update.js +12 -7
@@ -1,11 +1,11 @@
1
1
  import { type Schema } from "../../schema/Schema.js";
2
2
  import type { ImmutableArray } from "../../util/array.js";
3
3
  import { type Data } from "../../util/data.js";
4
- import type { AnyCaller, Arguments } from "../../util/function.js";
4
+ import type { AnyCaller } from "../../util/function.js";
5
5
  import type { RequestMethod, RequestParams } from "../../util/http.js";
6
6
  import type { AbsolutePath } from "../../util/path.js";
7
7
  import { type TemplatePlaceholders } from "../../util/template.js";
8
- import type { EndpointCallback, EndpointHandler } from "./util.js";
8
+ import type { EndpointCallback, EndpointContext, EndpointHandler } from "./util.js";
9
9
  /**
10
10
  * An abstract API resource definition, used to specify types for e.g. serverless functions.
11
11
  *
@@ -44,7 +44,7 @@ export declare class Endpoint<P, R> {
44
44
  * @param callback The callback function that implements the logic for this endpoint by receiving the payload and returning the response.
45
45
  * @returns An `EndpointHandler` object combining this endpoint and the callback into a single typed object.
46
46
  */
47
- handler<A extends Arguments = []>(callback: EndpointCallback<P, R, A>): EndpointHandler<P, R, A>;
47
+ handler<C extends EndpointContext>(callback: EndpointCallback<P, R, C>): EndpointHandler<P, R, C>;
48
48
  /** Convert to string, e.g. `GET /user/{id}` */
49
49
  toString(): string;
50
50
  }
@@ -1,6 +1,12 @@
1
- import type { Arguments } from "../../util/function.js";
1
+ import type { AnyCaller } from "../../util/function.js";
2
2
  import { type PossibleURL } from "../../util/url.js";
3
3
  import type { Endpoint } from "./Endpoint.js";
4
+ /**
5
+ * The second argument to an `EndpointCallback` is its context.
6
+ * This must contain the `Request` that triggered the callback, but may contain additional details too. */
7
+ export interface EndpointContext {
8
+ readonly request: Request;
9
+ }
4
10
  /**
5
11
  * A function that handles an endpoint request, with a payload and returns a result.
6
12
  *
@@ -11,16 +17,16 @@ import type { Endpoint } from "./Endpoint.js";
11
17
  * @returns {Response} Returning a `Response` object (this will pass back to the client without validation).
12
18
  * @returns {R} Returning the return type of the handler (this will be validated against the Endpoint's result schema).
13
19
  */
14
- export type EndpointCallback<P, R, A extends Arguments = []> = (payload: P, request: Request, ...args: A) => R | Response | Promise<R | Response>;
20
+ export type EndpointCallback<P, R, C extends EndpointContext> = (payload: P, context: C) => R | Response | Promise<R | Response>;
15
21
  /** A typed endpoint definition paired with its implementation callback. */
16
- export interface EndpointHandler<P = unknown, R = unknown, A extends Arguments = []> {
22
+ export interface EndpointHandler<P, R, C extends EndpointContext> {
17
23
  readonly endpoint: Endpoint<P, R>;
18
- readonly callback: EndpointCallback<P, R, A>;
24
+ readonly callback: EndpointCallback<P, R, C>;
19
25
  }
20
26
  /** Any endpoint handler. */
21
- export type AnyEndpointHandler<A extends Arguments = []> = EndpointHandler<any, any, A>;
27
+ export type AnyEndpointHandler<C extends EndpointContext = EndpointContext> = EndpointHandler<any, any, C>;
22
28
  /** A collection of endpoint handlers that can be matched and invoked by `handleEndpoints()`. */
23
- export type EndpointHandlers<A extends Arguments = []> = Iterable<AnyEndpointHandler<A>>;
29
+ export type EndpointHandlers<C extends EndpointContext = EndpointContext> = Iterable<AnyEndpointHandler<C>>;
24
30
  /**
25
31
  * Handle a `Request` with the first matching endpoint handler after stripping any base-path prefix from the request pathname.
26
32
  * - The original `Request` object is passed through to the callback unchanged.
@@ -31,4 +37,4 @@ export type EndpointHandlers<A extends Arguments = []> = Iterable<AnyEndpointHan
31
37
  * @param base The base URL for the API, e.g. `https://myapi.com/a/b`
32
38
  * - `pathname` of this URL gets trimmed from `request.path` to form the target path when matching against endpoints, e.g. `/a/b/c/d` will produce `/c/d` for matching.
33
39
  */
34
- export declare function handleEndpoints<A extends Arguments = []>(request: Request, base: PossibleURL, handlers: EndpointHandlers<A>, ...args: A): Promise<Response>;
40
+ export declare function handleEndpoints<C extends EndpointContext>(base: PossibleURL, handlers: EndpointHandlers<C>, context: C, caller?: AnyCaller): Promise<Response>;
@@ -14,9 +14,8 @@ import { requireURL } from "../../util/url.js";
14
14
  * @param base The base URL for the API, e.g. `https://myapi.com/a/b`
15
15
  * - `pathname` of this URL gets trimmed from `request.path` to form the target path when matching against endpoints, e.g. `/a/b/c/d` will produce `/c/d` for matching.
16
16
  */
17
- export function handleEndpoints(request, base, handlers, ...args) {
18
- const caller = handleEndpoints;
19
- const { url, method } = request;
17
+ export function handleEndpoints(base, handlers, context, caller = handleEndpoints) {
18
+ const { url, method } = context.request;
20
19
  if (!isRequestMethod(method))
21
20
  throw new MethodNotAllowedError("Unsupported request method", { received: method, caller });
22
21
  const { origin: baseOrigin, pathname: basePath } = requireURL(base, undefined, caller);
@@ -31,7 +30,7 @@ export function handleEndpoints(request, base, handlers, ...args) {
31
30
  if (!pathParams)
32
31
  continue;
33
32
  const params = searchParams.size ? { ...getDictionary(searchParams), ...pathParams } : pathParams;
34
- return _handleEndpoint(handler, params, request, args, handleEndpoints);
33
+ return _handleEndpoint(handler, params, context, handleEndpoints);
35
34
  }
36
35
  throw new NotFoundError("No matching endpoint", { received: targetPath, caller });
37
36
  }
@@ -40,11 +39,11 @@ export function handleEndpoints(request, base, handlers, ...args) {
40
39
  */
41
40
  async function _handleEndpoint({ endpoint, callback },
42
41
  /** Params we already matched/parsed from the URL. */
43
- params, request, args, caller = _handleEndpoint) {
44
- const content = await getRequestContent(request, caller);
42
+ params, context, caller) {
43
+ const content = await getRequestContent(context.request, caller);
45
44
  const unsafePayload = content === undefined ? params : isPlainObject(content) ? { ...content, ...params } : content;
46
45
  const payload = endpoint.payload.validate(unsafePayload);
47
- const unsafeResult = await callback(payload, request, ...args);
46
+ const unsafeResult = await callback(payload, context);
48
47
  if (unsafeResult instanceof Response)
49
48
  return unsafeResult;
50
49
  try {
package/api/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from "./provider/APIProvider.js";
6
6
  export * from "./provider/ClientAPIProvider.js";
7
7
  export * from "./provider/DebugAPIProvider.js";
8
8
  export * from "./provider/MockAPIProvider.js";
9
+ export * from "./provider/MockEnpdointAPIProvider.js";
9
10
  export * from "./provider/ThroughAPIProvider.js";
10
11
  export * from "./provider/ValidationAPIProvider.js";
11
12
  export * from "./store/EndpointStore.js";
package/api/index.js CHANGED
@@ -6,6 +6,7 @@ export * from "./provider/APIProvider.js";
6
6
  export * from "./provider/ClientAPIProvider.js";
7
7
  export * from "./provider/DebugAPIProvider.js";
8
8
  export * from "./provider/MockAPIProvider.js";
9
+ export * from "./provider/MockEnpdointAPIProvider.js";
9
10
  export * from "./provider/ThroughAPIProvider.js";
10
11
  export * from "./provider/ValidationAPIProvider.js";
11
12
  export * from "./store/EndpointStore.js";
@@ -0,0 +1,16 @@
1
+ import { type EndpointContext, type EndpointHandlers } from "../endpoint/util.js";
2
+ import { MockAPIProvider, type MockAPIProviderOptions } from "./MockAPIProvider.js";
3
+ /**
4
+ * Provider that mocks an API that calls and matches an array of `EndpointHandler` objects returned from `Endpoint.handler()`
5
+ * - Used to test server-side API code, calls against an API made up of multiple `Endpoint` instances.
6
+ *
7
+ * @example
8
+ * const endpoint = POST("/squared", INTEGER, INTEGER); // Create an endpoint designed to square its input number.
9
+ * const handlers = [endpoint.handler(num => num * num)]; // Implement handlers for the endpoints.
10
+ * const api = new MockEnpdointAPIProvider(handlers); // Create a new mock provider.
11
+ * const result = await api.fetch(endpoint, 4); // Mock a call to the endpoint through the provider.
12
+ * expect(result).toBe(16);
13
+ */
14
+ export declare class MockEnpdointAPIProvider<C extends EndpointContext> extends MockAPIProvider {
15
+ constructor(handlers: EndpointHandlers<C>, c: Omit<EndpointContext, "request">, options: MockAPIProviderOptions);
16
+ }
@@ -0,0 +1,18 @@
1
+ import { handleEndpoints } from "../endpoint/util.js";
2
+ import { MockAPIProvider } from "./MockAPIProvider.js";
3
+ /**
4
+ * Provider that mocks an API that calls and matches an array of `EndpointHandler` objects returned from `Endpoint.handler()`
5
+ * - Used to test server-side API code, calls against an API made up of multiple `Endpoint` instances.
6
+ *
7
+ * @example
8
+ * const endpoint = POST("/squared", INTEGER, INTEGER); // Create an endpoint designed to square its input number.
9
+ * const handlers = [endpoint.handler(num => num * num)]; // Implement handlers for the endpoints.
10
+ * const api = new MockEnpdointAPIProvider(handlers); // Create a new mock provider.
11
+ * const result = await api.fetch(endpoint, 4); // Mock a call to the endpoint through the provider.
12
+ * expect(result).toBe(16);
13
+ */
14
+ export class MockEnpdointAPIProvider extends MockAPIProvider {
15
+ constructor(handlers, c, options) {
16
+ super(request => handleEndpoints(this.url, handlers, { ...c, request }), options);
17
+ }
18
+ }
@@ -0,0 +1,10 @@
1
+ import type { SQL } from "bun";
2
+ import { PostgreSQLProvider, type SQLFragment } from "../db/index.js";
3
+ import type { ImmutableArray } from "../util/array.js";
4
+ import type { Data } from "../util/data.js";
5
+ export declare class BunPostgreSQLProvider extends PostgreSQLProvider {
6
+ private _sql;
7
+ constructor(sql: SQL);
8
+ exec<T extends Data>(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): Promise<ImmutableArray<T>>;
9
+ sqlIdentifier(name: string): SQLFragment;
10
+ }
@@ -0,0 +1,16 @@
1
+ import { PostgreSQLProvider } from "../db/index.js";
2
+ export class BunPostgreSQLProvider extends PostgreSQLProvider {
3
+ _sql;
4
+ constructor(sql) {
5
+ super();
6
+ this._sql = sql;
7
+ }
8
+ // Implement `SQLProvider` using `Bun.SQL` instance.
9
+ exec(strings, ...values) {
10
+ return this._sql(strings, ...values);
11
+ }
12
+ // Override to wrap identifiers using `sql()`, since Bun SQL engine supports this and it's more secure.
13
+ sqlIdentifier(name) {
14
+ return this.sql `${this._sql(name)}`;
15
+ }
16
+ }
package/bun/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./BunPostgreSQLProvider.js";
package/bun/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./BunPostgreSQLProvider.js";
@@ -0,0 +1,14 @@
1
+ import { SQLiteProvider } from "../db/provider/SQLiteProvider.js";
2
+ import { type ImmutableArray } from "../util/array.js";
3
+ import type { Data } from "../util/data.js";
4
+ import type { D1Database } from "./types.js";
5
+ /**
6
+ * Cloudflare D1 database provider.
7
+ *
8
+ * Uses the D1 Worker API for execution and standard SQL from `SQLProvider`.
9
+ */
10
+ export declare class CloudflareD1Provider extends SQLiteProvider {
11
+ private readonly _db;
12
+ constructor(db: D1Database);
13
+ exec<T extends Data = Data>(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): Promise<readonly T[]>;
14
+ }
@@ -0,0 +1,56 @@
1
+ import { SQLiteProvider } from "../db/provider/SQLiteProvider.js";
2
+ import { ValueError } from "../error/ValueError.js";
3
+ import { isArray } from "../util/array.js";
4
+ import { isPlainObject } from "../util/object.js";
5
+ /**
6
+ * Cloudflare D1 database provider.
7
+ *
8
+ * Uses the D1 Worker API for execution and standard SQL from `SQLProvider`.
9
+ */
10
+ export class CloudflareD1Provider extends SQLiteProvider {
11
+ _db;
12
+ constructor(db) {
13
+ super();
14
+ this._db = db;
15
+ }
16
+ async exec(strings, ...values) {
17
+ const { query, values: bindings } = _getD1Query(strings, values, this.exec);
18
+ const result = await this._db
19
+ .prepare(query)
20
+ .bind(...bindings)
21
+ .run();
22
+ return result.results ?? [];
23
+ }
24
+ }
25
+ function _getD1Query(strings, values, caller) {
26
+ let query = strings[0] ?? "";
27
+ const bindings = [];
28
+ for (const [index, value] of values.entries()) {
29
+ const part = _getD1Part(value, caller);
30
+ query += part.query;
31
+ bindings.push(...part.values);
32
+ query += strings[index + 1] ?? "";
33
+ }
34
+ return { query, values: bindings };
35
+ }
36
+ function _getD1Part(value, caller) {
37
+ if (_isSQLQuery(value))
38
+ return _getD1Query(value.strings, value.values, caller);
39
+ return { query: "?", values: [_getD1Value(value, caller)] };
40
+ }
41
+ function _getD1Value(value, caller) {
42
+ if (value === null || typeof value === "boolean" || typeof value === "string" || typeof value === "number")
43
+ return value;
44
+ if (isArray(value) || isPlainObject(value)) {
45
+ try {
46
+ return JSON.stringify(value);
47
+ }
48
+ catch (cause) {
49
+ throw new ValueError("Cannot convert value to D1 JSON value", { cause, received: value, caller });
50
+ }
51
+ }
52
+ throw new ValueError("Cannot convert value to D1 binding", { received: value, caller });
53
+ }
54
+ function _isSQLQuery(value) {
55
+ return typeof value === "object" && !!value && "strings" in value && "values" in value;
56
+ }
@@ -4,14 +4,7 @@ import type { Data } from "../util/data.js";
4
4
  import type { Items, OptionalItem } from "../util/item.js";
5
5
  import type { ItemQuery } from "../util/query.js";
6
6
  import type { Updates } from "../util/update.js";
7
- /** Minimal interface matching Cloudflare Workers KV namespace runtime object. */
8
- export interface KVNamespace {
9
- get(key: string, options: {
10
- type: "json";
11
- }): Promise<unknown>;
12
- put(key: string, value: string): Promise<void>;
13
- delete(key: string): Promise<void>;
14
- }
7
+ import type { KVNamespace } from "./types.js";
15
8
  /**
16
9
  * Cloudflare Workers KV database provider.
17
10
  *
@@ -49,5 +42,5 @@ export declare class CloudflareKVProvider extends DBProvider<string> {
49
42
  getQuerySequence<T extends Data>(_c: Collection<string, string, T>, _q?: ItemQuery<string, T>): AsyncIterable<Items<string, T>>;
50
43
  setQuery<T extends Data>(_c: Collection<string, string, T>, _q: ItemQuery<string, T>, _data: T): Promise<void>;
51
44
  updateQuery<T extends Data>(_c: Collection<string, string, T>, _q: ItemQuery<string, T>, _updates: Updates<T>): Promise<void>;
52
- deleteQuery<T extends Data>(c: Collection<string, string, T>, _q: ItemQuery<string, T>): Promise<void>;
45
+ deleteQuery<T extends Data>(_c: Collection<string, string, T>, _q: ItemQuery<string, T>): Promise<void>;
53
46
  }
@@ -66,7 +66,7 @@ export class CloudflareKVProvider extends DBProvider {
66
66
  async updateQuery(_c, _q, _updates) {
67
67
  throw new UnimplementedError("CloudflareKVProvider does not support updates to items");
68
68
  }
69
- async deleteQuery(c, _q) {
69
+ async deleteQuery(_c, _q) {
70
70
  throw new UnimplementedError("CloudflareKVProvider does not support querying items");
71
71
  }
72
72
  }
@@ -1 +1,3 @@
1
+ export * from "./CloudflareD1Provider.js";
1
2
  export * from "./CloudflareKVProvider.js";
3
+ export * from "./types.js";
@@ -1 +1,3 @@
1
+ export * from "./CloudflareD1Provider.js";
1
2
  export * from "./CloudflareKVProvider.js";
3
+ export * from "./types.js";
@@ -0,0 +1,44 @@
1
+ /** Minimal interface matching Cloudflare Workers KV namespace runtime object. */
2
+ export interface KVNamespace {
3
+ get(key: string, options: {
4
+ type: "json";
5
+ }): Promise<unknown>;
6
+ put(key: string, value: string): Promise<void>;
7
+ delete(key: string): Promise<void>;
8
+ }
9
+ /** Value that can be passed through the D1 Worker API. */
10
+ export type D1Value = boolean | null | number | string;
11
+ /** Metadata returned by the D1 Worker API. */
12
+ export interface D1Meta {
13
+ readonly changed_db?: boolean | undefined;
14
+ readonly duration?: number | undefined;
15
+ readonly last_row_id?: number | undefined;
16
+ readonly rows_read?: number | undefined;
17
+ readonly rows_written?: number | undefined;
18
+ }
19
+ /** Result object returned by `D1PreparedStatement.run()`. */
20
+ export interface D1Result<T extends Record<string, unknown> = Record<string, unknown>> {
21
+ readonly success: boolean;
22
+ readonly meta?: D1Meta | undefined;
23
+ readonly results?: readonly T[] | undefined;
24
+ }
25
+ /** Result object returned by `D1Database.exec()`. */
26
+ export interface D1ExecResult {
27
+ readonly count: number;
28
+ readonly duration: number;
29
+ }
30
+ /** Minimal prepared statement interface for D1 databases and sessions. */
31
+ export interface D1PreparedStatement {
32
+ bind(...values: D1Value[]): D1PreparedStatement;
33
+ first<T = Record<string, unknown>>(column?: string): Promise<T | null>;
34
+ raw<T = unknown[]>(options?: {
35
+ columnNames?: boolean;
36
+ }): Promise<readonly T[]>;
37
+ run<T extends Record<string, unknown> = Record<string, unknown>>(): Promise<D1Result<T>>;
38
+ }
39
+ /** Minimal D1 binding/session interface used by `CloudflareD1Provider`. */
40
+ export interface D1Database {
41
+ batch<T extends Record<string, unknown> = Record<string, unknown>>(statements: readonly D1PreparedStatement[]): Promise<readonly D1Result<T>[]>;
42
+ exec?(query: string): Promise<D1ExecResult>;
43
+ prepare(query: string): D1PreparedStatement;
44
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -17,8 +17,8 @@ export declare class Collection<K extends string, I extends Identifier, T extend
17
17
  }
18
18
  /** Shortcut factory for creating a Collection. */
19
19
  export declare function COLLECTION<K extends string, I extends Identifier, T extends Data>(name: K, id: Schema<I>, data: Schemas<T> | DataSchema<T>): Collection<K, I, T>;
20
- /** A readonly array of Collection instances. */
21
- export type Collections = ReadonlyArray<Collection<string, Identifier, Data>>;
20
+ /** A readonly array of Collection instances, possibly with a standardised `Identifier`. */
21
+ export type Collections<I extends Identifier = Identifier> = ReadonlyArray<Collection<string, I, Data>>;
22
22
  /** Extract the union of collection key strings from a Collections type. */
23
23
  export type CollectionKeys<C extends Collections> = C[number]["name"];
24
24
  /** Convert a Collections array type to a Database-style object mapping. */
package/db/index.d.ts CHANGED
@@ -1,10 +1,17 @@
1
1
  export * from "./collection/Collection.js";
2
+ export * from "./migrate/DBMigrator.js";
3
+ export * from "./migrate/PostgreSQLMigrator.js";
4
+ export * from "./migrate/SQLiteMigrator.js";
5
+ export * from "./migrate/SQLMigrator.js";
2
6
  export * from "./provider/CacheDBProvider.js";
3
7
  export * from "./provider/ChangesDBProvider.js";
4
8
  export * from "./provider/DBProvider.js";
5
9
  export * from "./provider/DebugDBProvider.js";
6
10
  export * from "./provider/MemoryDBProvider.js";
7
11
  export * from "./provider/MockDBProvider.js";
12
+ export * from "./provider/PostgreSQLProvider.js";
13
+ export * from "./provider/SQLiteProvider.js";
14
+ export * from "./provider/SQLProvider.js";
8
15
  export * from "./provider/ThroughDBProvider.js";
9
16
  export * from "./provider/ValidationDBProvider.js";
10
17
  export * from "./store/ItemStore.js";
package/db/index.js CHANGED
@@ -1,10 +1,17 @@
1
1
  export * from "./collection/Collection.js";
2
+ export * from "./migrate/DBMigrator.js";
3
+ export * from "./migrate/PostgreSQLMigrator.js";
4
+ export * from "./migrate/SQLiteMigrator.js";
5
+ export * from "./migrate/SQLMigrator.js";
2
6
  export * from "./provider/CacheDBProvider.js";
3
7
  export * from "./provider/ChangesDBProvider.js";
4
8
  export * from "./provider/DBProvider.js";
5
9
  export * from "./provider/DebugDBProvider.js";
6
10
  export * from "./provider/MemoryDBProvider.js";
7
11
  export * from "./provider/MockDBProvider.js";
12
+ export * from "./provider/PostgreSQLProvider.js";
13
+ export * from "./provider/SQLiteProvider.js";
14
+ export * from "./provider/SQLProvider.js";
8
15
  export * from "./provider/ThroughDBProvider.js";
9
16
  export * from "./provider/ValidationDBProvider.js";
10
17
  export * from "./store/ItemStore.js";
@@ -0,0 +1,8 @@
1
+ import type { Collections } from "../collection/Collection.js";
2
+ import type { DBProvider } from "../provider/DBProvider.js";
3
+ /** Base class for database schema migrators. */
4
+ export declare abstract class DBMigrator<T extends DBProvider = DBProvider> {
5
+ readonly provider: T;
6
+ constructor(provider: T);
7
+ abstract migrate(...collections: Collections): Promise<void>;
8
+ }
@@ -0,0 +1,7 @@
1
+ /** Base class for database schema migrators. */
2
+ export class DBMigrator {
3
+ provider;
4
+ constructor(provider) {
5
+ this.provider = provider;
6
+ }
7
+ }
@@ -0,0 +1,37 @@
1
+ import type { Schema } from "../../schema/Schema.js";
2
+ import type { Data } from "../../util/data.js";
3
+ import type { Identifier } from "../../util/item.js";
4
+ import type { Collection } from "../collection/Collection.js";
5
+ import type { SQLProvider } from "../provider/SQLProvider.js";
6
+ import { SQLMigrator, type SQLTable, type SQLTableColumn } from "./SQLMigrator.js";
7
+ type PostgreSQLColumnRow = {
8
+ readonly generated: boolean;
9
+ readonly identity: boolean;
10
+ readonly name: string;
11
+ readonly nullable: boolean;
12
+ readonly primary: boolean;
13
+ readonly type: string;
14
+ readonly value: string | null;
15
+ };
16
+ /** PostgreSQL migrator using pg_catalog-style schema inspection. */
17
+ export declare class PostgreSQLMigrator<T extends SQLProvider = SQLProvider> extends SQLMigrator<T> {
18
+ protected getTables(): Promise<readonly string[]>;
19
+ protected getTable(name: string): Promise<SQLTable | undefined>;
20
+ protected getCreateTableSuffix<TData extends Data>(_collection: Collection<string, Identifier, TData>): string;
21
+ protected getDataColumnDefinition(): string;
22
+ protected getGeneratedColumnDefinition(_columnName: string, path: string, definition: string): string;
23
+ protected getIDColumnDefinition<TData extends Data>(collection: Collection<string, Identifier, TData>): string;
24
+ protected getAlterColumnQueries(tableName: string, from: SQLTableColumn, to: SQLTableColumn): readonly string[];
25
+ protected definition<TValue>(schema: Schema<TValue>): string | undefined;
26
+ protected getCurrentColumnStatement({ generated, identity, name: _name, nullable, primary, type, value }: PostgreSQLColumnRow): string;
27
+ protected getGeneratedExpression(path: string, definition: string): string;
28
+ protected getGeneratedCast(definition: string): string | undefined;
29
+ protected parseColumn({ name, statement }: SQLTableColumn): {
30
+ readonly defaultValue?: string | undefined;
31
+ readonly generated: boolean;
32
+ readonly name: string;
33
+ readonly nullable: boolean;
34
+ readonly type: string;
35
+ } | undefined;
36
+ }
37
+ export {};