Skip to content

Commit b2d8c65

Browse files
authored
fix(smart-tags): enable using Smart Tags with @foreignkey and @PrimaryKey (#586)
* Turn flow off * Fix smart tags problem
1 parent cd6b52a commit b2d8c65

4 files changed

Lines changed: 92 additions & 49 deletions

File tree

.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<PROJECT_ROOT>/packages/.*/index\.js\.flow
44
<PROJECT_ROOT>/packages/.*/node8plus/.*\.flow
55
<PROJECT_ROOT>/postgraphile
6+
<PROJECT_ROOT>/packages
67

78
[include]
89

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ export default (function PgBasicsPlugin(
321321
pgIgnoreIndexes = true, // TODO:v5: change this to false
322322
pgHideIndexWarnings = false,
323323
pgLegacyJsonUuid = false, // TODO:v5: remove this
324+
pgAugmentIntrospectionResults,
324325
}
325326
) {
326327
let pgOmit = baseOmit;
@@ -354,6 +355,7 @@ export default (function PgBasicsPlugin(
354355
pgField,
355356
sqlCommentByAddingTags,
356357
pgPrepareAndRun,
358+
pgAugmentIntrospectionResults,
357359
});
358360
},
359361
["PgBasics"]

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

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,20 @@ function smartCommentConstraints(introspectionResults) {
444444
});
445445
}
446446

447+
/* The argument to this must not contain cyclic references! */
448+
const deepClone = value => {
449+
if (Array.isArray(value)) {
450+
return value.map(val => deepClone(val));
451+
} else if (typeof value === "object" && value) {
452+
return Object.keys(value).reduce((memo, k) => {
453+
memo[k] = deepClone(value[k]);
454+
return memo;
455+
}, {});
456+
} else {
457+
return value;
458+
}
459+
};
460+
447461
export default (async function PgIntrospectionPlugin(
448462
builder,
449463
{
@@ -455,15 +469,9 @@ export default (async function PgIntrospectionPlugin(
455469
pgIncludeExtensionResources = false,
456470
pgLegacyFunctionsOnly = false,
457471
pgSkipInstallingWatchFixtures = false,
458-
pgAugmentIntrospectionResults,
459472
pgOwnerConnectionString,
460473
}
461474
) {
462-
const augment = introspectionResults => {
463-
[pgAugmentIntrospectionResults, smartCommentConstraints].forEach(fn =>
464-
fn ? fn(introspectionResults) : null
465-
);
466-
};
467475
/**
468476
* @summary introspect database and get the table/view/constraints.
469477
* @returns {Promise<PgIntrospectionResultsByKind>}
@@ -474,14 +482,7 @@ export default (async function PgIntrospectionPlugin(
474482
throw new Error("Argument 'schemas' (array) is required");
475483
}
476484
const cacheKey = `PgIntrospectionPlugin-introspectionResultsByKind-v${version}`;
477-
const cloneResults = obj => {
478-
const result = Object.keys(obj).reduce((memo, k) => {
479-
memo[k] = Array.isArray(obj[k]) ? obj[k].map(v => ({ ...v })) : obj[k];
480-
return memo;
481-
}, {});
482-
return result;
483-
};
484-
const introspectionResultsByKind = cloneResults(
485+
const introspectionResultsByKind = deepClone(
485486
await persistentMemoizeWithKey(cacheKey, () =>
486487
withPgClient(pgConfig, async pgClient => {
487488
const versionResult = await pgClient.query(
@@ -579,6 +580,14 @@ export default (async function PgIntrospectionPlugin(
579580
console.warn("⚠️ WARNING⚠️ " + errorMessage); // eslint-disable-line no-console
580581
}
581582
}
583+
return introspectionResultsByKind;
584+
}
585+
586+
function introspectionResultsFromRaw(
587+
rawResults,
588+
pgAugmentIntrospectionResults
589+
) {
590+
const introspectionResultsByKind = deepClone(rawResults);
582591

583592
const xByY = (arrayOfX, attrKey) =>
584593
arrayOfX.reduce((memo, x) => {
@@ -650,6 +659,11 @@ export default (async function PgIntrospectionPlugin(
650659
});
651660
};
652661

662+
const augment = introspectionResults => {
663+
[pgAugmentIntrospectionResults, smartCommentConstraints].forEach(fn =>
664+
fn ? fn(introspectionResults) : null
665+
);
666+
};
653667
augment(introspectionResultsByKind);
654668

655669
relate(
@@ -826,7 +840,7 @@ export default (async function PgIntrospectionPlugin(
826840
return introspectionResultsByKind;
827841
}
828842

829-
let introspectionResultsByKind = await introspect();
843+
let rawIntrospectionResultsByKind = await introspect();
830844

831845
let listener;
832846

@@ -842,7 +856,7 @@ export default (async function PgIntrospectionPlugin(
842856
async () => {
843857
debug(`Schema change detected: re-inspecting schema...`);
844858
try {
845-
introspectionResultsByKind = await introspect();
859+
rawIntrospectionResultsByKind = await introspect();
846860
debug(`Schema change detected: re-inspecting schema complete`);
847861
triggerRebuild();
848862
} catch (e) {
@@ -1037,6 +1051,10 @@ export default (async function PgIntrospectionPlugin(
10371051
builder.hook(
10381052
"build",
10391053
build => {
1054+
const introspectionResultsByKind = introspectionResultsFromRaw(
1055+
rawIntrospectionResultsByKind,
1056+
build.pgAugmentIntrospectionResults
1057+
);
10401058
if (introspectionResultsByKind.__pgVersion < 90500) {
10411059
// TODO:v5: remove this workaround
10421060
// This is a bit of a hack, but until we have plugin priorities it's the

packages/graphile-utils/src/makePgSmartTagsPlugin.ts

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { Build, Plugin } from "graphile-build";
2-
import { PgEntityKind, PgEntity } from "graphile-build-pg";
1+
import { Plugin } from "graphile-build";
2+
import {
3+
PgEntityKind,
4+
PgEntity,
5+
PgIntrospectionResultsByKind,
6+
} from "graphile-build-pg";
37
import { inspect } from "util";
48
import { entityIsIdentifiedBy } from "./introspectionHelpers";
59

@@ -116,39 +120,57 @@ export function makePgSmartTagsPlugin(
116120
);
117121
}
118122

119-
builder.hook("build", (build: Build) => {
120-
const { pgIntrospectionResultsByKind } = build;
121-
rules.forEach((rule, idx) => {
122-
const relevantIntrospectionResults: PgEntity[] =
123-
pgIntrospectionResultsByKind[rule.kind];
124-
125-
let hits = 0;
126-
relevantIntrospectionResults.forEach(entity => {
127-
if (!rule.match(entity)) {
128-
return;
129-
}
130-
hits++;
131-
if (rule.tags) {
132-
// Overwrite relevant tags
133-
Object.assign(entity.tags, rule.tags);
134-
}
135-
if (rule.description != null) {
136-
// Overwrite comment if specified
137-
entity.description = rule.description;
123+
builder.hook(
124+
"build",
125+
build => {
126+
const oldPgAugmentIntrospectionResults =
127+
build.pgAugmentIntrospectionResults;
128+
build.pgAugmentIntrospectionResults = (
129+
inIntrospectionResult: PgIntrospectionResultsByKind
130+
): PgIntrospectionResultsByKind => {
131+
let pgIntrospectionResultsByKind = inIntrospectionResult;
132+
if (oldPgAugmentIntrospectionResults) {
133+
pgIntrospectionResultsByKind = oldPgAugmentIntrospectionResults(
134+
pgIntrospectionResultsByKind
135+
);
138136
}
139-
});
137+
rules.forEach((rule, idx) => {
138+
const relevantIntrospectionResults: PgEntity[] =
139+
pgIntrospectionResultsByKind[rule.kind];
140140

141-
// Let people know if their rules don't match; it's probably a mistake.
142-
if (hits === 0) {
143-
console.warn(
144-
`WARNING: there were no matches for makePgSmartTagsPlugin rule ${idx} - ${inspect(
145-
rawRules[idx]
146-
)}`
147-
);
148-
}
149-
});
150-
return build;
151-
});
141+
let hits = 0;
142+
relevantIntrospectionResults.forEach(entity => {
143+
if (!rule.match(entity)) {
144+
return;
145+
}
146+
hits++;
147+
if (rule.tags) {
148+
// Overwrite relevant tags
149+
Object.assign(entity.tags, rule.tags);
150+
}
151+
if (rule.description != null) {
152+
// Overwrite comment if specified
153+
entity.description = rule.description;
154+
}
155+
});
156+
157+
// Let people know if their rules don't match; it's probably a mistake.
158+
if (hits === 0) {
159+
console.warn(
160+
`WARNING: there were no matches for makePgSmartTagsPlugin rule ${idx} - ${inspect(
161+
rawRules[idx]
162+
)}`
163+
);
164+
}
165+
});
166+
return pgIntrospectionResultsByKind;
167+
};
168+
return build;
169+
},
170+
[],
171+
["PgIntrospection"],
172+
["PgBasics"]
173+
);
152174
};
153175
return plugin;
154176
}

0 commit comments

Comments
 (0)