Skip to content

Commit 40a7bfa

Browse files
authored
feat(utils): add makePgSmartTagsPlugin (#541)
1 parent 907c8e6 commit 40a7bfa

File tree

8 files changed

+457
-9
lines changed

8 files changed

+457
-9
lines changed

packages/graphile-build-pg/src/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
PgExtension,
1010
PgIndex,
1111
PgIntrospectionResultsByKind,
12+
PgEntity,
13+
PgEntityKind,
1214
} from "./plugins/PgIntrospectionPlugin";
1315

1416
export {
@@ -21,6 +23,8 @@ export {
2123
PgExtension,
2224
PgIndex,
2325
PgIntrospectionResultsByKind,
26+
PgEntity,
27+
PgEntityKind,
2428
};
2529

2630
export function formatSQLForDebugging(sql: string): string;

packages/graphile-build-pg/src/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// @flow
22
import PgBasicsPlugin from "./plugins/PgBasicsPlugin";
3-
import PgIntrospectionPlugin from "./plugins/PgIntrospectionPlugin";
3+
import PgIntrospectionPlugin, {
4+
PgEntityKind,
5+
} from "./plugins/PgIntrospectionPlugin";
46
import PgTypesPlugin from "./plugins/PgTypesPlugin";
57
import PgJWTPlugin from "./plugins/PgJWTPlugin";
68
import PgTablesPlugin from "./plugins/PgTablesPlugin";
@@ -81,6 +83,9 @@ export const defaultPlugins = [
8183

8284
export { inflections };
8385

86+
// TypeScript compatibility
87+
export { PgEntityKind };
88+
8489
export {
8590
PgBasicsPlugin,
8691
PgIntrospectionPlugin,

packages/graphile-build-pg/src/plugins/PgIntrospectionPlugin.d.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import { SchemaBuilder, Options } from "graphile-build";
2+
export enum PgEntityKind {
3+
NAMESPACE = "namespace",
4+
PROCEDURE = "procedure",
5+
CLASS = "class",
6+
TYPE = "type",
7+
ATTRIBUTE = "attribute",
8+
CONSTRAINT = "constraint",
9+
EXTENSION = "extension",
10+
INDEX = "index",
11+
}
212

313
export interface PgNamespace {
4-
kind: "namespace";
14+
kind: PgEntityKind.NAMESPACE;
515
id: string;
616
name: string;
717
comment: string | void;
@@ -10,7 +20,7 @@ export interface PgNamespace {
1020
}
1121

1222
export interface PgProc {
13-
kind: "procedure";
23+
kind: PgEntityKind.PROCEDURE;
1424
id: string;
1525
name: string;
1626
comment: string | void;
@@ -34,7 +44,7 @@ export interface PgProc {
3444
}
3545

3646
export interface PgClass {
37-
kind: "class";
47+
kind: PgEntityKind.CLASS;
3848
id: string;
3949
name: string;
4050
comment: string | void;
@@ -63,7 +73,7 @@ export interface PgClass {
6373
}
6474

6575
export interface PgType {
66-
kind: "type";
76+
kind: PgEntityKind.TYPE;
6777
id: string;
6878
name: string;
6979
comment: string | void;
@@ -87,7 +97,7 @@ export interface PgType {
8797
}
8898

8999
export interface PgAttribute {
90-
kind: "attribute";
100+
kind: PgEntityKind.ATTRIBUTE;
91101
classId: string;
92102
num: number;
93103
name: string;
@@ -111,7 +121,7 @@ export interface PgAttribute {
111121
}
112122

113123
export interface PgConstraint {
114-
kind: "constraint";
124+
kind: PgEntityKind.CONSTRAINT;
115125
id: string;
116126
name: string;
117127
type: string;
@@ -131,7 +141,7 @@ export interface PgConstraint {
131141
}
132142

133143
export interface PgExtension {
134-
kind: "extension";
144+
kind: PgEntityKind.EXTENSION;
135145
id: string;
136146
name: string;
137147
namespaceId: string;
@@ -145,7 +155,7 @@ export interface PgExtension {
145155
}
146156

147157
export interface PgIndex {
148-
kind: "index";
158+
kind: PgEntityKind.INDEX;
149159
id: string;
150160
name: string;
151161
namespaceName: string;

packages/graphile-build-pg/src/plugins/PgIntrospectionPlugin.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,3 +1054,15 @@ export default (async function PgIntrospectionPlugin(
10541054
["PgBasics"]
10551055
);
10561056
}: Plugin);
1057+
1058+
// TypeScript compatibility
1059+
export const PgEntityKind = {
1060+
NAMESPACE: "namespace",
1061+
PROCEDURE: "procedure",
1062+
CLASS: "class",
1063+
TYPE: "type",
1064+
ATTRIBUTE: "attribute",
1065+
CONSTRAINT: "constraint",
1066+
EXTENSION: "extension",
1067+
INDEX: "index",
1068+
};

packages/graphile-utils/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export {
1919
Resolvers,
2020
ExtensionDefinition,
2121
} from "./makeExtendSchemaPlugin";
22+
export * from "./makePgSmartTagsPlugin";
2223
export {
2324
embed,
2425
gql,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {
2+
PgClass,
3+
PgEntityKind,
4+
PgConstraint,
5+
PgAttribute,
6+
PgEntity,
7+
PgProc,
8+
} from "graphile-build-pg";
9+
import parseIdentifierParts from "./parseIdentifierParts";
10+
11+
export function isAttribute(obj: PgEntity): obj is PgAttribute {
12+
return obj.kind === PgEntityKind.ATTRIBUTE;
13+
}
14+
15+
export function isConstraint(obj: PgEntity): obj is PgConstraint {
16+
return obj.kind === PgEntityKind.CONSTRAINT;
17+
}
18+
19+
export function isClass(obj: PgEntity): obj is PgClass {
20+
return obj.kind === PgEntityKind.CLASS;
21+
}
22+
23+
export function isProcedure(obj: PgEntity): obj is PgProc {
24+
return obj.kind === PgEntityKind.PROCEDURE;
25+
}
26+
27+
export function entityIsIdentifiedBy(
28+
obj: PgEntity,
29+
identifier: string
30+
): boolean {
31+
const parts = parseIdentifierParts(identifier);
32+
if (parts.length === 1) {
33+
const [expectedName] = parts;
34+
return obj.name === expectedName;
35+
} else if (parts.length === 2) {
36+
const [parentName, expectedName] = parts;
37+
if (isAttribute(obj) || isConstraint(obj)) {
38+
// Parent is a table
39+
return obj.name === expectedName && obj.class.name === parentName;
40+
} else if (isClass(obj) || isProcedure(obj)) {
41+
// Parent is a schema
42+
return obj.name === expectedName && obj.namespaceName === parentName;
43+
} else {
44+
throw new Error(
45+
`Type '${obj.kind}' not supported by makeSmartCommentsPlugin`
46+
);
47+
}
48+
} else if (parts.length === 3) {
49+
const [grandparentName, parentName, expectedName] = parts;
50+
if (isAttribute(obj) || isConstraint(obj)) {
51+
// Parent is a table, grandparent is a schema
52+
return (
53+
obj.name === expectedName &&
54+
obj.class.name === parentName &&
55+
obj.class.namespaceName === grandparentName
56+
);
57+
} else {
58+
// Parent is a schema; grandparent doesn't make sense
59+
throw new Error(
60+
`Identifier '${identifier}' does not make sense for a '${obj.kind}' entity`
61+
);
62+
}
63+
} else {
64+
throw new Error(
65+
`makeSmartCommentsPlugin did not know how to interpret match '${identifier}'`
66+
);
67+
}
68+
}

0 commit comments

Comments
 (0)