@pgpmjs/transform 0.9.0 → 0.11.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/bundle-driver.d.ts +100 -9
- package/bundle-driver.js +118 -14
- package/esm/bundle-driver.js +117 -15
- package/esm/index.js +2 -1
- package/index.d.ts +3 -2
- package/index.js +5 -1
- package/package.json +4 -4
package/bundle-driver.d.ts
CHANGED
|
@@ -7,23 +7,104 @@
|
|
|
7
7
|
* purpose — no dependency on `@pgpmjs/bundle`/`@pgpmjs/core` — so the driver
|
|
8
8
|
* stays a pure function factory over `transformSql` and `classifyStatements`.
|
|
9
9
|
*/
|
|
10
|
-
import { SchemaTransformResult, TransformSqlOptions } from '@pgsql/transform';
|
|
10
|
+
import { ExtensionDefinition, ExtensionRouteSpec, ExtensionRouter, ExtensionTransformResult, RoleRouteSpec, RoleTransformResult, SchemaRouter, SchemaTransformResult, TransformSqlOptions } from '@pgsql/transform';
|
|
11
11
|
/** Identity of the script being transformed/validated (matches the bundle seams). */
|
|
12
12
|
export interface BundleScriptContext {
|
|
13
13
|
change: string;
|
|
14
14
|
kind: 'deploy' | 'revert' | 'verify';
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A single object-level route: send one named object out of a source schema to
|
|
18
|
+
* a different target schema, independent of the schema-level default. The
|
|
19
|
+
* object `kind` selects the routing namespace (relation / function / type) so a
|
|
20
|
+
* table and a function of the same name route independently.
|
|
21
|
+
*/
|
|
22
|
+
export interface SchemaObjectRoute {
|
|
23
|
+
/** Source schema the object is defined in (e.g. `users`). */
|
|
24
|
+
fromSchema: string;
|
|
25
|
+
/** Object namespace. `table`/`view` → relation, `procedure` → function. */
|
|
26
|
+
kind: 'table' | 'view' | 'function' | 'procedure' | 'type';
|
|
27
|
+
/** Unqualified object name (e.g. `accounts`). */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Target schema this object is routed to (e.g. `reporting`). */
|
|
30
|
+
toSchema: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extension routing for a transpile: where to install extensions and where the
|
|
34
|
+
* symbols they provide (functions/types/operators) should resolve. Distinct
|
|
35
|
+
* from schema routing — the objects are owned by an extension, not declared in
|
|
36
|
+
* the SQL — so it is driven by a version-aware symbol inventory. See the
|
|
37
|
+
* upstream `ExtensionRouter` for the full model. `toSchema: null` (or a `routes`
|
|
38
|
+
* entry with `to: null`) strips qualification — the "rely on search_path"
|
|
39
|
+
* direction — so the same mechanism moves symbols into a dedicated schema and
|
|
40
|
+
* back out again.
|
|
41
|
+
*/
|
|
42
|
+
export interface ExtensionRoutingInput {
|
|
43
|
+
/**
|
|
44
|
+
* Move the matched extensions and their provided symbols to this single
|
|
45
|
+
* schema (`null` strips qualification). Ignored when `routes` is given.
|
|
46
|
+
*/
|
|
47
|
+
toSchema?: string | null;
|
|
48
|
+
/** With `toSchema`: limit to these extensions (default: every inventoried one). */
|
|
49
|
+
only?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* With `toSchema`: which source qualifications to rewrite (a `null` entry
|
|
52
|
+
* also rewrites bare references). Defaults to `public` + bare.
|
|
53
|
+
*/
|
|
54
|
+
from?: (string | null)[];
|
|
55
|
+
/** Advanced: explicit per-extension route spec. Overrides `toSchema`/`only`/`from`. */
|
|
56
|
+
routes?: ExtensionRouteSpec;
|
|
57
|
+
/** Target PostgreSQL major version, for core-graduation awareness (e.g. `gen_random_uuid`). */
|
|
58
|
+
serverVersion?: number;
|
|
59
|
+
/** Augmented or replacement symbol inventory (defaults to the curated common set). */
|
|
60
|
+
inventory?: ExtensionDefinition[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build an {@link ExtensionRouter} from the declarative {@link ExtensionRoutingInput}:
|
|
64
|
+
* an explicit `routes` spec when given, otherwise the "move everything matched
|
|
65
|
+
* to one schema" shortcut via `ExtensionRouter.toSchema`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildExtensionRouter(input: ExtensionRoutingInput): ExtensionRouter;
|
|
16
68
|
export interface SchemaTranspilerOptions {
|
|
17
|
-
/**
|
|
18
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Whole-schema default: source schema → target schema. Optional when
|
|
71
|
+
* `routes` fully cover the objects being moved.
|
|
72
|
+
*/
|
|
73
|
+
schemaMap?: Record<string, string>;
|
|
74
|
+
/**
|
|
75
|
+
* Object-level overrides. Each route wins over the schema-level default for
|
|
76
|
+
* its specific object, letting a single source schema fan out per object.
|
|
77
|
+
*/
|
|
78
|
+
routes?: SchemaObjectRoute[];
|
|
79
|
+
/**
|
|
80
|
+
* Route extension installs and provided-symbol references (a dimension
|
|
81
|
+
* orthogonal to schema routing). See {@link ExtensionRoutingInput}.
|
|
82
|
+
*/
|
|
83
|
+
extensions?: ExtensionRoutingInput;
|
|
84
|
+
/**
|
|
85
|
+
* Rename role identifiers (source role name → target role name), for
|
|
86
|
+
* translating between databases that name equivalent roles differently.
|
|
87
|
+
* Renames identifiers only — never role attributes.
|
|
88
|
+
*/
|
|
89
|
+
roles?: RoleRouteSpec | Map<string, string>;
|
|
19
90
|
/** Forwarded to {@link transformSql} (round-trip validation, extra passes). */
|
|
20
91
|
transform?: TransformSqlOptions;
|
|
21
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Build a {@link SchemaRouter} from a schema-level default map plus object
|
|
95
|
+
* routes. Object routes are grouped into the router's relation/function/type
|
|
96
|
+
* buckets; schema-level entries become each route's default target.
|
|
97
|
+
*/
|
|
98
|
+
export declare function buildSchemaRouter(options: SchemaTranspilerOptions): SchemaRouter;
|
|
22
99
|
export interface SchemaTranspiler {
|
|
23
100
|
/**
|
|
24
|
-
* Change-name/path rewrite (the pgpm structural dimension):
|
|
25
|
-
* segment
|
|
26
|
-
*
|
|
101
|
+
* Change-name/path rewrite (the pgpm structural dimension): rewrites the
|
|
102
|
+
* schema segment of a change path to the object's routed target. The object
|
|
103
|
+
* identity is read from the path itself — `schemas/<schema>/<kind>/<name>` —
|
|
104
|
+
* so a table and a function under the same source schema can land in
|
|
105
|
+
* different target schemas, e.g. `schemas/users/tables/accounts/table` →
|
|
106
|
+
* `schemas/tenant_a/tables/accounts/table` while
|
|
107
|
+
* `schemas/users/procedures/account_count` → `schemas/reporting/procedures/account_count`.
|
|
27
108
|
*/
|
|
28
109
|
renameChange: (name: string) => string;
|
|
29
110
|
/**
|
|
@@ -37,11 +118,21 @@ export interface SchemaTranspiler {
|
|
|
37
118
|
* schemas found/transformed and any per-script errors.
|
|
38
119
|
*/
|
|
39
120
|
result: SchemaTransformResult;
|
|
121
|
+
/**
|
|
122
|
+
* Accumulated extension-routing report (installs moved, symbols rewritten).
|
|
123
|
+
* Present only when `extensions` was configured.
|
|
124
|
+
*/
|
|
125
|
+
extensionResult?: ExtensionTransformResult;
|
|
126
|
+
/**
|
|
127
|
+
* Accumulated role-routing report (role → rewrite count). Present only when
|
|
128
|
+
* `roles` was configured.
|
|
129
|
+
*/
|
|
130
|
+
roleResult?: RoleTransformResult;
|
|
40
131
|
}
|
|
41
132
|
/**
|
|
42
|
-
* Build the caller-supplied callbacks for `transpileBundle` from a
|
|
43
|
-
*
|
|
44
|
-
* lockstep.
|
|
133
|
+
* Build the caller-supplied callbacks for `transpileBundle` from a schema map
|
|
134
|
+
* and/or object routes, so the folder/plan rename (change identity) and the
|
|
135
|
+
* in-SQL rewrite (AST) stay in lockstep on the exact same {@link SchemaRouter}.
|
|
45
136
|
*/
|
|
46
137
|
export declare function makeSchemaTranspiler(options: SchemaTranspilerOptions): SchemaTranspiler;
|
|
47
138
|
export interface NamespaceValidatorOptions {
|
package/bundle-driver.js
CHANGED
|
@@ -9,35 +9,139 @@
|
|
|
9
9
|
* stays a pure function factory over `transformSql` and `classifyStatements`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.buildExtensionRouter = buildExtensionRouter;
|
|
13
|
+
exports.buildSchemaRouter = buildSchemaRouter;
|
|
12
14
|
exports.makeSchemaTranspiler = makeSchemaTranspiler;
|
|
13
15
|
exports.makeNamespaceValidator = makeNamespaceValidator;
|
|
14
16
|
const transform_1 = require("@pgsql/transform");
|
|
15
17
|
const transform_2 = require("@pgsql/transform");
|
|
16
18
|
/**
|
|
17
|
-
* Build
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* Build an {@link ExtensionRouter} from the declarative {@link ExtensionRoutingInput}:
|
|
20
|
+
* an explicit `routes` spec when given, otherwise the "move everything matched
|
|
21
|
+
* to one schema" shortcut via `ExtensionRouter.toSchema`.
|
|
22
|
+
*/
|
|
23
|
+
function buildExtensionRouter(input) {
|
|
24
|
+
const opts = {};
|
|
25
|
+
if (input.serverVersion !== undefined)
|
|
26
|
+
opts.serverVersion = input.serverVersion;
|
|
27
|
+
if (input.inventory)
|
|
28
|
+
opts.inventory = input.inventory;
|
|
29
|
+
if (input.routes)
|
|
30
|
+
return new transform_2.ExtensionRouter(input.routes, opts);
|
|
31
|
+
return transform_2.ExtensionRouter.toSchema(input.toSchema ?? null, {
|
|
32
|
+
...opts,
|
|
33
|
+
extensions: input.only,
|
|
34
|
+
from: input.from
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** pgpm change-path folder segment → transform routing namespace. */
|
|
38
|
+
const PATH_KIND_NS = {
|
|
39
|
+
tables: 'relation',
|
|
40
|
+
views: 'relation',
|
|
41
|
+
procedures: 'function',
|
|
42
|
+
functions: 'function',
|
|
43
|
+
types: 'type'
|
|
44
|
+
};
|
|
45
|
+
/** Object route `kind` → the {@link SchemaRoute} bucket it belongs in. */
|
|
46
|
+
const ROUTE_KIND_BUCKET = {
|
|
47
|
+
table: 'relations',
|
|
48
|
+
view: 'relations',
|
|
49
|
+
function: 'functions',
|
|
50
|
+
procedure: 'functions',
|
|
51
|
+
type: 'types'
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Build a {@link SchemaRouter} from a schema-level default map plus object
|
|
55
|
+
* routes. Object routes are grouped into the router's relation/function/type
|
|
56
|
+
* buckets; schema-level entries become each route's default target.
|
|
57
|
+
*/
|
|
58
|
+
function buildSchemaRouter(options) {
|
|
59
|
+
const spec = {};
|
|
60
|
+
const ensure = (schema) => (spec[schema] ??= {});
|
|
61
|
+
for (const [from, to] of Object.entries(options.schemaMap ?? {})) {
|
|
62
|
+
ensure(from).schema = to;
|
|
63
|
+
}
|
|
64
|
+
for (const route of options.routes ?? []) {
|
|
65
|
+
const bucketKey = ROUTE_KIND_BUCKET[route.kind];
|
|
66
|
+
const target = ensure(route.fromSchema);
|
|
67
|
+
(target[bucketKey] ??= {})[route.name] = route.toSchema;
|
|
68
|
+
}
|
|
69
|
+
return new transform_2.SchemaRouter(spec);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Rewrite the schema segment of a pgpm change path to the object's routed
|
|
73
|
+
* target. Interprets `schemas/<schema>/<kind>/<name>...`: the bare
|
|
74
|
+
* `schemas/<schema>/schema` change resolves at the schema level; typed folders
|
|
75
|
+
* (`tables`, `procedures`, `types`, …) resolve the named object in its
|
|
76
|
+
* namespace, so object routes and the schema-level default both apply.
|
|
77
|
+
*/
|
|
78
|
+
function renameChangePath(name, router) {
|
|
79
|
+
const parts = name.split('/');
|
|
80
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
81
|
+
if (parts[i] !== 'schemas')
|
|
82
|
+
continue;
|
|
83
|
+
const schema = parts[i + 1];
|
|
84
|
+
if (!router.has(schema))
|
|
85
|
+
continue;
|
|
86
|
+
const folder = parts[i + 2];
|
|
87
|
+
let target;
|
|
88
|
+
if (folder === undefined || folder === 'schema') {
|
|
89
|
+
target = router.resolve(schema, undefined, 'schema');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const ns = PATH_KIND_NS[folder];
|
|
93
|
+
const objectName = parts[i + 3];
|
|
94
|
+
target = ns
|
|
95
|
+
? router.resolve(schema, objectName, ns)
|
|
96
|
+
: router.resolve(schema, undefined, 'schema');
|
|
97
|
+
}
|
|
98
|
+
if (target && target !== schema)
|
|
99
|
+
parts[i + 1] = target;
|
|
100
|
+
}
|
|
101
|
+
return parts.join('/');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Build the caller-supplied callbacks for `transpileBundle` from a schema map
|
|
105
|
+
* and/or object routes, so the folder/plan rename (change identity) and the
|
|
106
|
+
* in-SQL rewrite (AST) stay in lockstep on the exact same {@link SchemaRouter}.
|
|
20
107
|
*/
|
|
21
108
|
function makeSchemaTranspiler(options) {
|
|
22
|
-
const
|
|
109
|
+
const router = buildSchemaRouter(options);
|
|
23
110
|
const result = {
|
|
24
111
|
schemasFound: new Set(),
|
|
25
112
|
schemasTransformed: new Map(),
|
|
26
113
|
errors: []
|
|
27
114
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
115
|
+
// Extension/role routing are additional, orthogonal AST dimensions applied
|
|
116
|
+
// after schema routing on each script. Each is a self-contained parse →
|
|
117
|
+
// rewrite → deparse pass, so they compose by threading the SQL through.
|
|
118
|
+
const extRouter = options.extensions ? buildExtensionRouter(options.extensions) : undefined;
|
|
119
|
+
const roleRouter = options.roles ? transform_2.RoleRouter.from(options.roles) : undefined;
|
|
120
|
+
const extensionResult = extRouter ? (0, transform_2.createExtensionResult)() : undefined;
|
|
121
|
+
const roleResult = roleRouter ? (0, transform_2.createRoleResult)() : undefined;
|
|
122
|
+
const renameChange = (name) => renameChangePath(name, router);
|
|
123
|
+
const transformScript = (sql, _ctx) => {
|
|
124
|
+
let out = (0, transform_2.transformSql)(sql, router, options.transform, result).content;
|
|
125
|
+
if (extRouter) {
|
|
126
|
+
const r = (0, transform_2.transformExtensions)(out, extRouter);
|
|
127
|
+
out = r.sql;
|
|
128
|
+
for (const [name, schema] of r.result.installsMoved) {
|
|
129
|
+
extensionResult.installsMoved.set(name, schema);
|
|
130
|
+
}
|
|
131
|
+
for (const [name, count] of r.result.symbolsRewritten) {
|
|
132
|
+
extensionResult.symbolsRewritten.set(name, (extensionResult.symbolsRewritten.get(name) ?? 0) + count);
|
|
33
133
|
}
|
|
34
134
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
135
|
+
if (roleRouter) {
|
|
136
|
+
const r = (0, transform_2.transformRoles)(out, roleRouter);
|
|
137
|
+
out = r.sql;
|
|
138
|
+
for (const [name, count] of r.result.rolesRenamed) {
|
|
139
|
+
roleResult.rolesRenamed.set(name, (roleResult.rolesRenamed.get(name) ?? 0) + count);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
39
143
|
};
|
|
40
|
-
return { renameChange, transformScript, result };
|
|
144
|
+
return { renameChange, transformScript, result, extensionResult, roleResult };
|
|
41
145
|
}
|
|
42
146
|
/**
|
|
43
147
|
* Build an `applyBundle`-compatible `validateReferences` callback: returns a
|
package/esm/bundle-driver.js
CHANGED
|
@@ -8,32 +8,134 @@
|
|
|
8
8
|
* stays a pure function factory over `transformSql` and `classifyStatements`.
|
|
9
9
|
*/
|
|
10
10
|
import { classifyStatements } from '@pgsql/transform';
|
|
11
|
-
import { transformSql } from '@pgsql/transform';
|
|
11
|
+
import { createExtensionResult, createRoleResult, ExtensionRouter, RoleRouter, SchemaRouter, transformExtensions, transformRoles, transformSql } from '@pgsql/transform';
|
|
12
12
|
/**
|
|
13
|
-
* Build
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* Build an {@link ExtensionRouter} from the declarative {@link ExtensionRoutingInput}:
|
|
14
|
+
* an explicit `routes` spec when given, otherwise the "move everything matched
|
|
15
|
+
* to one schema" shortcut via `ExtensionRouter.toSchema`.
|
|
16
|
+
*/
|
|
17
|
+
export function buildExtensionRouter(input) {
|
|
18
|
+
const opts = {};
|
|
19
|
+
if (input.serverVersion !== undefined)
|
|
20
|
+
opts.serverVersion = input.serverVersion;
|
|
21
|
+
if (input.inventory)
|
|
22
|
+
opts.inventory = input.inventory;
|
|
23
|
+
if (input.routes)
|
|
24
|
+
return new ExtensionRouter(input.routes, opts);
|
|
25
|
+
return ExtensionRouter.toSchema(input.toSchema ?? null, {
|
|
26
|
+
...opts,
|
|
27
|
+
extensions: input.only,
|
|
28
|
+
from: input.from
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** pgpm change-path folder segment → transform routing namespace. */
|
|
32
|
+
const PATH_KIND_NS = {
|
|
33
|
+
tables: 'relation',
|
|
34
|
+
views: 'relation',
|
|
35
|
+
procedures: 'function',
|
|
36
|
+
functions: 'function',
|
|
37
|
+
types: 'type'
|
|
38
|
+
};
|
|
39
|
+
/** Object route `kind` → the {@link SchemaRoute} bucket it belongs in. */
|
|
40
|
+
const ROUTE_KIND_BUCKET = {
|
|
41
|
+
table: 'relations',
|
|
42
|
+
view: 'relations',
|
|
43
|
+
function: 'functions',
|
|
44
|
+
procedure: 'functions',
|
|
45
|
+
type: 'types'
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Build a {@link SchemaRouter} from a schema-level default map plus object
|
|
49
|
+
* routes. Object routes are grouped into the router's relation/function/type
|
|
50
|
+
* buckets; schema-level entries become each route's default target.
|
|
51
|
+
*/
|
|
52
|
+
export function buildSchemaRouter(options) {
|
|
53
|
+
const spec = {};
|
|
54
|
+
const ensure = (schema) => (spec[schema] ??= {});
|
|
55
|
+
for (const [from, to] of Object.entries(options.schemaMap ?? {})) {
|
|
56
|
+
ensure(from).schema = to;
|
|
57
|
+
}
|
|
58
|
+
for (const route of options.routes ?? []) {
|
|
59
|
+
const bucketKey = ROUTE_KIND_BUCKET[route.kind];
|
|
60
|
+
const target = ensure(route.fromSchema);
|
|
61
|
+
(target[bucketKey] ??= {})[route.name] = route.toSchema;
|
|
62
|
+
}
|
|
63
|
+
return new SchemaRouter(spec);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Rewrite the schema segment of a pgpm change path to the object's routed
|
|
67
|
+
* target. Interprets `schemas/<schema>/<kind>/<name>...`: the bare
|
|
68
|
+
* `schemas/<schema>/schema` change resolves at the schema level; typed folders
|
|
69
|
+
* (`tables`, `procedures`, `types`, …) resolve the named object in its
|
|
70
|
+
* namespace, so object routes and the schema-level default both apply.
|
|
71
|
+
*/
|
|
72
|
+
function renameChangePath(name, router) {
|
|
73
|
+
const parts = name.split('/');
|
|
74
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
75
|
+
if (parts[i] !== 'schemas')
|
|
76
|
+
continue;
|
|
77
|
+
const schema = parts[i + 1];
|
|
78
|
+
if (!router.has(schema))
|
|
79
|
+
continue;
|
|
80
|
+
const folder = parts[i + 2];
|
|
81
|
+
let target;
|
|
82
|
+
if (folder === undefined || folder === 'schema') {
|
|
83
|
+
target = router.resolve(schema, undefined, 'schema');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const ns = PATH_KIND_NS[folder];
|
|
87
|
+
const objectName = parts[i + 3];
|
|
88
|
+
target = ns
|
|
89
|
+
? router.resolve(schema, objectName, ns)
|
|
90
|
+
: router.resolve(schema, undefined, 'schema');
|
|
91
|
+
}
|
|
92
|
+
if (target && target !== schema)
|
|
93
|
+
parts[i + 1] = target;
|
|
94
|
+
}
|
|
95
|
+
return parts.join('/');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build the caller-supplied callbacks for `transpileBundle` from a schema map
|
|
99
|
+
* and/or object routes, so the folder/plan rename (change identity) and the
|
|
100
|
+
* in-SQL rewrite (AST) stay in lockstep on the exact same {@link SchemaRouter}.
|
|
16
101
|
*/
|
|
17
102
|
export function makeSchemaTranspiler(options) {
|
|
18
|
-
const
|
|
103
|
+
const router = buildSchemaRouter(options);
|
|
19
104
|
const result = {
|
|
20
105
|
schemasFound: new Set(),
|
|
21
106
|
schemasTransformed: new Map(),
|
|
22
107
|
errors: []
|
|
23
108
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
109
|
+
// Extension/role routing are additional, orthogonal AST dimensions applied
|
|
110
|
+
// after schema routing on each script. Each is a self-contained parse →
|
|
111
|
+
// rewrite → deparse pass, so they compose by threading the SQL through.
|
|
112
|
+
const extRouter = options.extensions ? buildExtensionRouter(options.extensions) : undefined;
|
|
113
|
+
const roleRouter = options.roles ? RoleRouter.from(options.roles) : undefined;
|
|
114
|
+
const extensionResult = extRouter ? createExtensionResult() : undefined;
|
|
115
|
+
const roleResult = roleRouter ? createRoleResult() : undefined;
|
|
116
|
+
const renameChange = (name) => renameChangePath(name, router);
|
|
117
|
+
const transformScript = (sql, _ctx) => {
|
|
118
|
+
let out = transformSql(sql, router, options.transform, result).content;
|
|
119
|
+
if (extRouter) {
|
|
120
|
+
const r = transformExtensions(out, extRouter);
|
|
121
|
+
out = r.sql;
|
|
122
|
+
for (const [name, schema] of r.result.installsMoved) {
|
|
123
|
+
extensionResult.installsMoved.set(name, schema);
|
|
124
|
+
}
|
|
125
|
+
for (const [name, count] of r.result.symbolsRewritten) {
|
|
126
|
+
extensionResult.symbolsRewritten.set(name, (extensionResult.symbolsRewritten.get(name) ?? 0) + count);
|
|
29
127
|
}
|
|
30
128
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
129
|
+
if (roleRouter) {
|
|
130
|
+
const r = transformRoles(out, roleRouter);
|
|
131
|
+
out = r.sql;
|
|
132
|
+
for (const [name, count] of r.result.rolesRenamed) {
|
|
133
|
+
roleResult.rolesRenamed.set(name, (roleResult.rolesRenamed.get(name) ?? 0) + count);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
35
137
|
};
|
|
36
|
-
return { renameChange, transformScript, result };
|
|
138
|
+
return { renameChange, transformScript, result, extensionResult, roleResult };
|
|
37
139
|
}
|
|
38
140
|
/**
|
|
39
141
|
* Build an `applyBundle`-compatible `validateReferences` callback: returns a
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from '@pgsql/transform';
|
|
2
|
-
export {
|
|
2
|
+
export { loadModule } from 'plpgsql-parser';
|
|
3
|
+
export { buildExtensionRouter, buildSchemaRouter, makeNamespaceValidator, makeSchemaTranspiler, } from './bundle-driver';
|
|
3
4
|
export { buildCategoryOf, categorizeChange, TIER_PROFILE, } from './categorize';
|
|
4
5
|
export { resolveFixtureClosure } from './fixture-closure';
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from '@pgsql/transform';
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
2
|
+
export { loadModule } from 'plpgsql-parser';
|
|
3
|
+
export type { BundleScriptContext, ExtensionRoutingInput, NamespaceValidatorOptions, SchemaObjectRoute, SchemaTranspiler, SchemaTranspilerOptions, } from './bundle-driver';
|
|
4
|
+
export { buildExtensionRouter, buildSchemaRouter, makeNamespaceValidator, makeSchemaTranspiler, } from './bundle-driver';
|
|
4
5
|
export type { CategoryProfile, ChangeCategory, } from './categorize';
|
|
5
6
|
export { buildCategoryOf, categorizeChange, TIER_PROFILE, } from './categorize';
|
|
6
7
|
export type { ClosureChange, ClosureInputChange, ClosureReason, FixtureClosure, ResolveFixtureClosureOptions, } from './fixture-closure';
|
package/index.js
CHANGED
|
@@ -14,9 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.resolveFixtureClosure = exports.TIER_PROFILE = exports.categorizeChange = exports.buildCategoryOf = exports.makeSchemaTranspiler = exports.makeNamespaceValidator = void 0;
|
|
17
|
+
exports.resolveFixtureClosure = exports.TIER_PROFILE = exports.categorizeChange = exports.buildCategoryOf = exports.makeSchemaTranspiler = exports.makeNamespaceValidator = exports.buildSchemaRouter = exports.buildExtensionRouter = exports.loadModule = void 0;
|
|
18
18
|
__exportStar(require("@pgsql/transform"), exports);
|
|
19
|
+
var plpgsql_parser_1 = require("plpgsql-parser");
|
|
20
|
+
Object.defineProperty(exports, "loadModule", { enumerable: true, get: function () { return plpgsql_parser_1.loadModule; } });
|
|
19
21
|
var bundle_driver_1 = require("./bundle-driver");
|
|
22
|
+
Object.defineProperty(exports, "buildExtensionRouter", { enumerable: true, get: function () { return bundle_driver_1.buildExtensionRouter; } });
|
|
23
|
+
Object.defineProperty(exports, "buildSchemaRouter", { enumerable: true, get: function () { return bundle_driver_1.buildSchemaRouter; } });
|
|
20
24
|
Object.defineProperty(exports, "makeNamespaceValidator", { enumerable: true, get: function () { return bundle_driver_1.makeNamespaceValidator; } });
|
|
21
25
|
Object.defineProperty(exports, "makeSchemaTranspiler", { enumerable: true, get: function () { return bundle_driver_1.makeSchemaTranspiler; } });
|
|
22
26
|
var categorize_1 = require("./categorize");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgpmjs/transform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Change-aware SQL transformation for PGPM — superset of @pgsql/transform plus change categorization, fixture closure, and bundle transpile/apply drivers",
|
|
6
6
|
"main": "index.js",
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"plpgsql"
|
|
40
40
|
],
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@pgpmjs/bundle": "^0.
|
|
42
|
+
"@pgpmjs/bundle": "^0.12.0",
|
|
43
43
|
"makage": "^0.3.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@pgsql/transform": "^18.
|
|
46
|
+
"@pgsql/transform": "^18.6.0",
|
|
47
47
|
"plpgsql-parser": "^18.2.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "5ef8341033a8fbd85841b770e996e468dd15333b"
|
|
50
50
|
}
|