@supabase/pg-delta 1.0.0-alpha.12 → 1.0.0-alpha.13

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Declarative schema export.
3
3
  */
4
- import type { Integration } from "../integrations/integration.types.ts";
4
+ import { type Integration } from "../integrations/integration.types.ts";
5
5
  import type { createPlan } from "../plan/create.ts";
6
6
  import type { SqlFormatOptions } from "../plan/sql-format/types.ts";
7
7
  import type { DeclarativeSchemaOutput, Grouping } from "./types.ts";
@@ -12,7 +12,7 @@ import type { DeclarativeSchemaOutput, Grouping } from "./types.ts";
12
12
  type PlanResult = NonNullable<Awaited<ReturnType<typeof createPlan>>>;
13
13
  export interface ExportOptions {
14
14
  /** Integration for custom serialization */
15
- integration?: Integration;
15
+ integration?: Pick<Integration, "serialize">;
16
16
  /**
17
17
  * SQL formatter options to control the output style.
18
18
  * Merged on top of the default export options (maxWidth: 180, keywordCase: "upper").
@@ -2,6 +2,7 @@
2
2
  * Declarative schema export.
3
3
  */
4
4
  import { buildPlanScopeFingerprint, hashStableIds } from "../fingerprint.js";
5
+ import { resolveIntegration, } from "../integrations/integration.types.js";
5
6
  import { DEFAULT_OPTIONS } from "../plan/sql-format/constants.js";
6
7
  import { formatSqlScript } from "../plan/statements.js";
7
8
  import { createFileMapper } from "./file-mapper.js";
@@ -22,7 +23,9 @@ import { groupChangesByFile } from "./grouper.js";
22
23
  */
23
24
  export function exportDeclarativeSchema(planResult, options) {
24
25
  const { ctx, sortedChanges } = planResult;
25
- const integration = options?.integration;
26
+ const integration = options?.integration
27
+ ? resolveIntegration(options?.integration)
28
+ : {};
26
29
  const formatOptions = options?.formatOptions === null
27
30
  ? undefined
28
31
  : {
@@ -1,6 +1,31 @@
1
+ import { type FilterDSL } from "./filter/dsl.ts";
1
2
  import type { ChangeFilter } from "./filter/filter.types.ts";
3
+ import { type SerializeDSL } from "./serialize/dsl.ts";
2
4
  import type { ChangeSerializer } from "./serialize/serialize.types.ts";
3
- export type Integration = {
5
+ /**
6
+ * A resolved integration is an integration that has been compiled to a function.
7
+ */
8
+ export type ResolvedIntegration = {
4
9
  filter?: ChangeFilter;
5
10
  serialize?: ChangeSerializer;
6
11
  };
12
+ /**
13
+ * A raw integration is an integration that has not been compiled to a function.
14
+ */
15
+ export type IntegrationDSL = {
16
+ filter?: FilterDSL;
17
+ serialize?: SerializeDSL;
18
+ };
19
+ /**
20
+ * An integration is a raw integration that has not been compiled to a function.
21
+ */
22
+ export type Integration = {
23
+ filter?: ResolvedIntegration["filter"] | IntegrationDSL["filter"];
24
+ serialize?: ResolvedIntegration["serialize"] | IntegrationDSL["serialize"];
25
+ };
26
+ /**
27
+ * Resolve an integration either DSL or already resovled into a ResolvedIntegration.
28
+ * @param integration - The integration to resolve.
29
+ * @returns The resolved integration.
30
+ */
31
+ export declare function resolveIntegration(integration: Integration): ResolvedIntegration | undefined;
@@ -1 +1,31 @@
1
- export {};
1
+ import { compileFilterDSL } from "./filter/dsl.js";
2
+ import { compileSerializeDSL } from "./serialize/dsl.js";
3
+ /**
4
+ * Resolve an integration either DSL or already resovled into a ResolvedIntegration.
5
+ * @param integration - The integration to resolve.
6
+ * @returns The resolved integration.
7
+ */
8
+ export function resolveIntegration(integration) {
9
+ // Determine if filter/serialize are DSL or functions, and extract DSL for storage
10
+ const isFilterDSL = integration.filter && typeof integration.filter !== "function";
11
+ const isSerializeDSL = integration.serialize && typeof integration.serialize !== "function";
12
+ const filterDSL = isFilterDSL ? integration.filter : undefined;
13
+ const serializeDSL = isSerializeDSL
14
+ ? integration.serialize
15
+ : undefined;
16
+ // Build final integration: compile DSL if needed, use functions directly otherwise
17
+ if (integration.filter || integration.serialize) {
18
+ return {
19
+ filter: typeof integration.filter === "function"
20
+ ? integration.filter
21
+ : filterDSL
22
+ ? compileFilterDSL(filterDSL)
23
+ : undefined,
24
+ serialize: typeof integration.serialize === "function"
25
+ ? integration.serialize
26
+ : serializeDSL
27
+ ? compileSerializeDSL(serializeDSL)
28
+ : undefined,
29
+ };
30
+ }
31
+ }
@@ -5,8 +5,7 @@ import { escapeIdentifier } from "pg";
5
5
  import { diffCatalogs } from "../catalog.diff.js";
6
6
  import { createEmptyCatalog, extractCatalog } from "../catalog.model.js";
7
7
  import { buildPlanScopeFingerprint, hashStableIds } from "../fingerprint.js";
8
- import { compileFilterDSL, } from "../integrations/filter/dsl.js";
9
- import { compileSerializeDSL, } from "../integrations/serialize/dsl.js";
8
+ import { resolveIntegration, } from "../integrations/integration.types.js";
10
9
  import { createManagedPool, endPool } from "../postgres-config.js";
11
10
  import { sortChanges } from "../sort/sort-changes.js";
12
11
  import { classifyChangesRisk } from "./risk.js";
@@ -103,21 +102,10 @@ function buildPlanForCatalogs(fromCatalog, toCatalog, options = {}) {
103
102
  ? serializeOption
104
103
  : undefined;
105
104
  // Build final integration: compile DSL if needed, use functions directly otherwise
106
- let finalIntegration;
107
- if (filterOption || serializeOption) {
108
- finalIntegration = {
109
- filter: typeof filterOption === "function"
110
- ? filterOption
111
- : filterDSL
112
- ? compileFilterDSL(filterDSL)
113
- : undefined,
114
- serialize: typeof serializeOption === "function"
115
- ? serializeOption
116
- : serializeDSL
117
- ? compileSerializeDSL(serializeDSL)
118
- : undefined,
119
- };
120
- }
105
+ const finalIntegration = resolveIntegration({
106
+ filter: filterOption,
107
+ serialize: serializeOption,
108
+ });
121
109
  // Use filter from final integration
122
110
  const filterFn = finalIntegration?.filter;
123
111
  let filteredChanges = filterFn
@@ -3,10 +3,7 @@
3
3
  */
4
4
  import z from "zod";
5
5
  import type { Change } from "../change.types.ts";
6
- import type { FilterDSL } from "../integrations/filter/dsl.ts";
7
- import type { ChangeFilter } from "../integrations/filter/filter.types.ts";
8
- import type { SerializeDSL } from "../integrations/serialize/dsl.ts";
9
- import type { ChangeSerializer } from "../integrations/serialize/serialize.types.ts";
6
+ import type { Integration } from "../integrations/integration.types.ts";
10
7
  export type PlanRisk = {
11
8
  level: "safe";
12
9
  } | {
@@ -133,9 +130,9 @@ export type Plan = z.infer<typeof PlanSchema>;
133
130
  */
134
131
  export interface CreatePlanOptions {
135
132
  /** Filter - either FilterDSL (stored in plan) or ChangeFilter function (not stored) */
136
- filter?: FilterDSL | ChangeFilter;
133
+ filter?: Integration["filter"];
137
134
  /** Serialize - either SerializeDSL (stored in plan) or ChangeSerializer function (not stored) */
138
- serialize?: SerializeDSL | ChangeSerializer;
135
+ serialize?: Integration["serialize"];
139
136
  /** Role to use when executing the migration (SET ROLE will be added to statements) */
140
137
  role?: string;
141
138
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supabase/pg-delta",
3
- "version": "1.0.0-alpha.12",
3
+ "version": "1.0.0-alpha.13",
4
4
  "description": "PostgreSQL migrations made easy",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -4,7 +4,11 @@
4
4
 
5
5
  import type { Change } from "../change.types.ts";
6
6
  import { buildPlanScopeFingerprint, hashStableIds } from "../fingerprint.ts";
7
- import type { Integration } from "../integrations/integration.types.ts";
7
+ import {
8
+ type Integration,
9
+ type ResolvedIntegration,
10
+ resolveIntegration,
11
+ } from "../integrations/integration.types.ts";
8
12
  import type { createPlan } from "../plan/create.ts";
9
13
  import { DEFAULT_OPTIONS } from "../plan/sql-format/constants.ts";
10
14
  import type { SqlFormatOptions } from "../plan/sql-format/types.ts";
@@ -29,7 +33,7 @@ type PlanResult = NonNullable<Awaited<ReturnType<typeof createPlan>>>;
29
33
 
30
34
  export interface ExportOptions {
31
35
  /** Integration for custom serialization */
32
- integration?: Integration;
36
+ integration?: Pick<Integration, "serialize">;
33
37
  /**
34
38
  * SQL formatter options to control the output style.
35
39
  * Merged on top of the default export options (maxWidth: 180, keywordCase: "upper").
@@ -64,7 +68,9 @@ export function exportDeclarativeSchema(
64
68
  options?: ExportOptions,
65
69
  ): DeclarativeSchemaOutput {
66
70
  const { ctx, sortedChanges } = planResult;
67
- const integration = options?.integration;
71
+ const integration = options?.integration
72
+ ? resolveIntegration(options?.integration)
73
+ : {};
68
74
  const formatOptions: SqlFormatOptions | undefined =
69
75
  options?.formatOptions === null
70
76
  ? undefined
@@ -108,7 +114,10 @@ export function exportDeclarativeSchema(
108
114
  };
109
115
  }
110
116
 
111
- function serializeChange(change: Change, integration?: Integration): string {
117
+ function serializeChange(
118
+ change: Change,
119
+ integration?: ResolvedIntegration,
120
+ ): string {
112
121
  return integration?.serialize?.(change) ?? change.serialize();
113
122
  }
114
123
 
@@ -1,7 +1,65 @@
1
+ import { compileFilterDSL, type FilterDSL } from "./filter/dsl.ts";
1
2
  import type { ChangeFilter } from "./filter/filter.types.ts";
3
+ import { compileSerializeDSL, type SerializeDSL } from "./serialize/dsl.ts";
2
4
  import type { ChangeSerializer } from "./serialize/serialize.types.ts";
3
5
 
4
- export type Integration = {
6
+ /**
7
+ * A resolved integration is an integration that has been compiled to a function.
8
+ */
9
+ export type ResolvedIntegration = {
5
10
  filter?: ChangeFilter;
6
11
  serialize?: ChangeSerializer;
7
12
  };
13
+
14
+ /**
15
+ * A raw integration is an integration that has not been compiled to a function.
16
+ */
17
+ export type IntegrationDSL = {
18
+ filter?: FilterDSL;
19
+ serialize?: SerializeDSL;
20
+ };
21
+
22
+ /**
23
+ * An integration is a raw integration that has not been compiled to a function.
24
+ */
25
+ export type Integration = {
26
+ filter?: ResolvedIntegration["filter"] | IntegrationDSL["filter"];
27
+ serialize?: ResolvedIntegration["serialize"] | IntegrationDSL["serialize"];
28
+ };
29
+
30
+ /**
31
+ * Resolve an integration either DSL or already resovled into a ResolvedIntegration.
32
+ * @param integration - The integration to resolve.
33
+ * @returns The resolved integration.
34
+ */
35
+ export function resolveIntegration(
36
+ integration: Integration,
37
+ ): ResolvedIntegration | undefined {
38
+ // Determine if filter/serialize are DSL or functions, and extract DSL for storage
39
+ const isFilterDSL =
40
+ integration.filter && typeof integration.filter !== "function";
41
+ const isSerializeDSL =
42
+ integration.serialize && typeof integration.serialize !== "function";
43
+ const filterDSL = isFilterDSL ? (integration.filter as FilterDSL) : undefined;
44
+ const serializeDSL = isSerializeDSL
45
+ ? (integration.serialize as SerializeDSL)
46
+ : undefined;
47
+
48
+ // Build final integration: compile DSL if needed, use functions directly otherwise
49
+ if (integration.filter || integration.serialize) {
50
+ return {
51
+ filter:
52
+ typeof integration.filter === "function"
53
+ ? integration.filter
54
+ : filterDSL
55
+ ? compileFilterDSL(filterDSL)
56
+ : undefined,
57
+ serialize:
58
+ typeof integration.serialize === "function"
59
+ ? integration.serialize
60
+ : serializeDSL
61
+ ? compileSerializeDSL(serializeDSL)
62
+ : undefined,
63
+ };
64
+ }
65
+ }
@@ -10,15 +10,12 @@ import { createEmptyCatalog, extractCatalog } from "../catalog.model.ts";
10
10
  import type { Change } from "../change.types.ts";
11
11
  import type { DiffContext } from "../context.ts";
12
12
  import { buildPlanScopeFingerprint, hashStableIds } from "../fingerprint.ts";
13
+ import type { FilterDSL } from "../integrations/filter/dsl.ts";
13
14
  import {
14
- compileFilterDSL,
15
- type FilterDSL,
16
- } from "../integrations/filter/dsl.ts";
17
- import type { Integration } from "../integrations/integration.types.ts";
18
- import {
19
- compileSerializeDSL,
20
- type SerializeDSL,
21
- } from "../integrations/serialize/dsl.ts";
15
+ type ResolvedIntegration,
16
+ resolveIntegration,
17
+ } from "../integrations/integration.types.ts";
18
+ import type { SerializeDSL } from "../integrations/serialize/dsl.ts";
22
19
  import { createManagedPool, endPool } from "../postgres-config.ts";
23
20
  import { sortChanges } from "../sort/sort-changes.ts";
24
21
  import type { PgDependRow } from "../sort/types.ts";
@@ -155,23 +152,10 @@ function buildPlanForCatalogs(
155
152
  : undefined;
156
153
 
157
154
  // Build final integration: compile DSL if needed, use functions directly otherwise
158
- let finalIntegration: Integration | undefined;
159
- if (filterOption || serializeOption) {
160
- finalIntegration = {
161
- filter:
162
- typeof filterOption === "function"
163
- ? filterOption
164
- : filterDSL
165
- ? compileFilterDSL(filterDSL)
166
- : undefined,
167
- serialize:
168
- typeof serializeOption === "function"
169
- ? serializeOption
170
- : serializeDSL
171
- ? compileSerializeDSL(serializeDSL)
172
- : undefined,
173
- };
174
- }
155
+ const finalIntegration = resolveIntegration({
156
+ filter: filterOption,
157
+ serialize: serializeOption,
158
+ });
175
159
 
176
160
  // Use filter from final integration
177
161
  const filterFn = finalIntegration?.filter;
@@ -317,7 +301,7 @@ function buildPlan(
317
301
  options?: CreatePlanOptions,
318
302
  filterDSL?: FilterDSL,
319
303
  serializeDSL?: SerializeDSL,
320
- integration?: Integration,
304
+ integration?: ResolvedIntegration,
321
305
  ): Plan {
322
306
  const role = options?.role;
323
307
  const statements = generateStatements(changes, {
@@ -350,7 +334,7 @@ function buildPlan(
350
334
  function generateStatements(
351
335
  changes: Change[],
352
336
  options?: {
353
- integration?: Integration;
337
+ integration?: ResolvedIntegration;
354
338
  role?: string;
355
339
  },
356
340
  ): string[] {
@@ -4,10 +4,7 @@
4
4
 
5
5
  import z from "zod";
6
6
  import type { Change } from "../change.types.ts";
7
- import type { FilterDSL } from "../integrations/filter/dsl.ts";
8
- import type { ChangeFilter } from "../integrations/filter/filter.types.ts";
9
- import type { SerializeDSL } from "../integrations/serialize/dsl.ts";
10
- import type { ChangeSerializer } from "../integrations/serialize/serialize.types.ts";
7
+ import type { Integration } from "../integrations/integration.types.ts";
11
8
 
12
9
  // ============================================================================
13
10
  // Core Types
@@ -157,9 +154,9 @@ export type Plan = z.infer<typeof PlanSchema>;
157
154
  */
158
155
  export interface CreatePlanOptions {
159
156
  /** Filter - either FilterDSL (stored in plan) or ChangeFilter function (not stored) */
160
- filter?: FilterDSL | ChangeFilter;
157
+ filter?: Integration["filter"];
161
158
  /** Serialize - either SerializeDSL (stored in plan) or ChangeSerializer function (not stored) */
162
- serialize?: SerializeDSL | ChangeSerializer;
159
+ serialize?: Integration["serialize"];
163
160
  /** Role to use when executing the migration (SET ROLE will be added to statements) */
164
161
  role?: string;
165
162
  /**