graphile-schema 2.10.4 → 2.10.5

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.
@@ -4,9 +4,10 @@ export type { BuildSchemaOptions as BuildIntrospectionOptions };
4
4
  /**
5
5
  * Build introspection metadata for all tables visible in the given schemas.
6
6
  *
7
- * Internally calls `buildSchemaSDL()` which triggers the MetaSchemaPlugin
8
- * gather hook, populating `_cachedTablesMeta` as a side-effect. The cached
9
- * metadata is then returned as a plain array of `TableMeta` objects.
7
+ * Internally calls `buildSchemaArtifacts()`, which returns SDL and `_meta`
8
+ * metadata from one correlated build boundary both derived from the same
9
+ * final executable `GraphQLSchema` so concurrent builds in one process
10
+ * cannot return each other's metadata.
10
11
  *
11
12
  * The result includes every table's fields, types, constraints, indexes,
12
13
  * relations, inflection names, and query entry-points — the same data
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildIntrospectionJSON = buildIntrospectionJSON;
4
- const graphile_settings_1 = require("graphile-settings");
5
4
  const build_schema_1 = require("./build-schema");
6
5
  /**
7
6
  * Build introspection metadata for all tables visible in the given schemas.
8
7
  *
9
- * Internally calls `buildSchemaSDL()` which triggers the MetaSchemaPlugin
10
- * gather hook, populating `_cachedTablesMeta` as a side-effect. The cached
11
- * metadata is then returned as a plain array of `TableMeta` objects.
8
+ * Internally calls `buildSchemaArtifacts()`, which returns SDL and `_meta`
9
+ * metadata from one correlated build boundary both derived from the same
10
+ * final executable `GraphQLSchema` so concurrent builds in one process
11
+ * cannot return each other's metadata.
12
12
  *
13
13
  * The result includes every table's fields, types, constraints, indexes,
14
14
  * relations, inflection names, and query entry-points — the same data
@@ -27,6 +27,5 @@ const build_schema_1 = require("./build-schema");
27
27
  * ```
28
28
  */
29
29
  async function buildIntrospectionJSON(opts) {
30
- await (0, build_schema_1.buildSchemaSDL)(opts);
31
- return [...graphile_settings_1._cachedTablesMeta];
30
+ return (await (0, build_schema_1.buildSchemaArtifacts)(opts)).tablesMeta;
32
31
  }
package/build-schema.d.ts CHANGED
@@ -1,7 +1,30 @@
1
1
  import type { GraphileConfig } from 'graphile-config';
2
+ import type { TableMeta } from 'graphile-settings';
2
3
  export type BuildSchemaOptions = {
3
4
  database?: string;
4
5
  schemas: string[];
5
6
  graphile?: Partial<GraphileConfig.Preset>;
7
+ /**
8
+ * @internal Test-only. Awaited after the schema's `_meta` metadata has been
9
+ * collected and before artifacts are returned, so regression tests can
10
+ * deterministically interleave concurrent builds.
11
+ */
12
+ _onMetaCollected?: () => Promise<void>;
6
13
  };
14
+ export type BuildSchemaArtifacts = {
15
+ /** SDL printed from the final executable schema. */
16
+ sdl: string;
17
+ /**
18
+ * `_meta` table metadata belonging to the same `GraphQLSchema` the SDL was
19
+ * printed from. Empty when the meta plugin is disabled (no `_meta` field).
20
+ */
21
+ tablesMeta: TableMeta[];
22
+ };
23
+ /**
24
+ * Build the GraphQL schema for a database and return its SDL together with
25
+ * the `_meta` table metadata from one correlated build boundary. Both values
26
+ * are derived from the same final executable `GraphQLSchema` instance, so
27
+ * concurrent builds in one process can never cross-contaminate results.
28
+ */
29
+ export declare function buildSchemaArtifacts(opts: BuildSchemaOptions): Promise<BuildSchemaArtifacts>;
7
30
  export declare function buildSchemaSDL(opts: BuildSchemaOptions): Promise<string>;
package/build-schema.js CHANGED
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildSchemaArtifacts = buildSchemaArtifacts;
6
7
  exports.buildSchemaSDL = buildSchemaSDL;
7
8
  const deepmerge_1 = __importDefault(require("deepmerge"));
8
9
  const graphql_1 = require("graphql");
@@ -10,7 +11,13 @@ const graphile_settings_1 = require("graphile-settings");
10
11
  const graphile_build_1 = require("graphile-build");
11
12
  const pg_cache_1 = require("pg-cache");
12
13
  const pg_env_1 = require("pg-env");
13
- async function buildSchemaSDL(opts) {
14
+ /**
15
+ * Build the GraphQL schema for a database and return its SDL together with
16
+ * the `_meta` table metadata from one correlated build boundary. Both values
17
+ * are derived from the same final executable `GraphQLSchema` instance, so
18
+ * concurrent builds in one process can never cross-contaminate results.
19
+ */
20
+ async function buildSchemaArtifacts(opts) {
14
21
  const database = opts.database ?? 'constructive';
15
22
  const schemas = Array.isArray(opts.schemas) ? opts.schemas : [];
16
23
  const config = (0, pg_env_1.getPgEnvOptions)({ database });
@@ -41,5 +48,28 @@ async function buildSchemaSDL(opts) {
41
48
  ],
42
49
  };
43
50
  const { schema } = await (0, graphile_build_1.makeSchema)(preset);
44
- return (0, graphql_1.printSchema)((0, graphql_1.lexicographicSortSchema)(schema));
51
+ // MetaSchemaPlugin validates executable names lazily against the schema that
52
+ // will actually be executed. Trigger that resolver after every finalizer has
53
+ // run, then read the metadata memoized for this exact GraphQLSchema instance.
54
+ let tablesMeta = [];
55
+ if (schema.getQueryType()?.getFields()._meta) {
56
+ const result = await (0, graphql_1.graphql)({
57
+ schema,
58
+ source: '{ _meta { tables { name } } }',
59
+ });
60
+ if (result.errors?.length) {
61
+ throw new AggregateError(result.errors, 'Failed to build schema metadata');
62
+ }
63
+ tablesMeta = (0, graphile_settings_1.getTablesMetaForSchema)(schema) ?? [];
64
+ }
65
+ if (opts._onMetaCollected) {
66
+ await opts._onMetaCollected();
67
+ }
68
+ return {
69
+ sdl: (0, graphql_1.printSchema)((0, graphql_1.lexicographicSortSchema)(schema)),
70
+ tablesMeta
71
+ };
72
+ }
73
+ async function buildSchemaSDL(opts) {
74
+ return (await buildSchemaArtifacts(opts)).sdl;
45
75
  }
@@ -4,9 +4,10 @@ export type { BuildSchemaOptions as BuildIntrospectionOptions };
4
4
  /**
5
5
  * Build introspection metadata for all tables visible in the given schemas.
6
6
  *
7
- * Internally calls `buildSchemaSDL()` which triggers the MetaSchemaPlugin
8
- * gather hook, populating `_cachedTablesMeta` as a side-effect. The cached
9
- * metadata is then returned as a plain array of `TableMeta` objects.
7
+ * Internally calls `buildSchemaArtifacts()`, which returns SDL and `_meta`
8
+ * metadata from one correlated build boundary both derived from the same
9
+ * final executable `GraphQLSchema` so concurrent builds in one process
10
+ * cannot return each other's metadata.
10
11
  *
11
12
  * The result includes every table's fields, types, constraints, indexes,
12
13
  * relations, inflection names, and query entry-points — the same data
@@ -1,11 +1,11 @@
1
- import { _cachedTablesMeta } from 'graphile-settings';
2
- import { buildSchemaSDL } from './build-schema';
1
+ import { buildSchemaArtifacts } from './build-schema';
3
2
  /**
4
3
  * Build introspection metadata for all tables visible in the given schemas.
5
4
  *
6
- * Internally calls `buildSchemaSDL()` which triggers the MetaSchemaPlugin
7
- * gather hook, populating `_cachedTablesMeta` as a side-effect. The cached
8
- * metadata is then returned as a plain array of `TableMeta` objects.
5
+ * Internally calls `buildSchemaArtifacts()`, which returns SDL and `_meta`
6
+ * metadata from one correlated build boundary both derived from the same
7
+ * final executable `GraphQLSchema` so concurrent builds in one process
8
+ * cannot return each other's metadata.
9
9
  *
10
10
  * The result includes every table's fields, types, constraints, indexes,
11
11
  * relations, inflection names, and query entry-points — the same data
@@ -24,6 +24,5 @@ import { buildSchemaSDL } from './build-schema';
24
24
  * ```
25
25
  */
26
26
  export async function buildIntrospectionJSON(opts) {
27
- await buildSchemaSDL(opts);
28
- return [..._cachedTablesMeta];
27
+ return (await buildSchemaArtifacts(opts)).tablesMeta;
29
28
  }
@@ -1,7 +1,30 @@
1
1
  import type { GraphileConfig } from 'graphile-config';
2
+ import type { TableMeta } from 'graphile-settings';
2
3
  export type BuildSchemaOptions = {
3
4
  database?: string;
4
5
  schemas: string[];
5
6
  graphile?: Partial<GraphileConfig.Preset>;
7
+ /**
8
+ * @internal Test-only. Awaited after the schema's `_meta` metadata has been
9
+ * collected and before artifacts are returned, so regression tests can
10
+ * deterministically interleave concurrent builds.
11
+ */
12
+ _onMetaCollected?: () => Promise<void>;
6
13
  };
14
+ export type BuildSchemaArtifacts = {
15
+ /** SDL printed from the final executable schema. */
16
+ sdl: string;
17
+ /**
18
+ * `_meta` table metadata belonging to the same `GraphQLSchema` the SDL was
19
+ * printed from. Empty when the meta plugin is disabled (no `_meta` field).
20
+ */
21
+ tablesMeta: TableMeta[];
22
+ };
23
+ /**
24
+ * Build the GraphQL schema for a database and return its SDL together with
25
+ * the `_meta` table metadata from one correlated build boundary. Both values
26
+ * are derived from the same final executable `GraphQLSchema` instance, so
27
+ * concurrent builds in one process can never cross-contaminate results.
28
+ */
29
+ export declare function buildSchemaArtifacts(opts: BuildSchemaOptions): Promise<BuildSchemaArtifacts>;
7
30
  export declare function buildSchemaSDL(opts: BuildSchemaOptions): Promise<string>;
@@ -1,10 +1,16 @@
1
1
  import deepmerge from 'deepmerge';
2
- import { lexicographicSortSchema, printSchema } from 'graphql';
3
- import { ConstructivePreset, makePgService } from 'graphile-settings';
2
+ import { graphql, lexicographicSortSchema, printSchema } from 'graphql';
3
+ import { ConstructivePreset, getTablesMetaForSchema, makePgService } from 'graphile-settings';
4
4
  import { makeSchema } from 'graphile-build';
5
5
  import { getPgPool } from 'pg-cache';
6
6
  import { getPgEnvOptions } from 'pg-env';
7
- export async function buildSchemaSDL(opts) {
7
+ /**
8
+ * Build the GraphQL schema for a database and return its SDL together with
9
+ * the `_meta` table metadata from one correlated build boundary. Both values
10
+ * are derived from the same final executable `GraphQLSchema` instance, so
11
+ * concurrent builds in one process can never cross-contaminate results.
12
+ */
13
+ export async function buildSchemaArtifacts(opts) {
8
14
  const database = opts.database ?? 'constructive';
9
15
  const schemas = Array.isArray(opts.schemas) ? opts.schemas : [];
10
16
  const config = getPgEnvOptions({ database });
@@ -35,5 +41,28 @@ export async function buildSchemaSDL(opts) {
35
41
  ],
36
42
  };
37
43
  const { schema } = await makeSchema(preset);
38
- return printSchema(lexicographicSortSchema(schema));
44
+ // MetaSchemaPlugin validates executable names lazily against the schema that
45
+ // will actually be executed. Trigger that resolver after every finalizer has
46
+ // run, then read the metadata memoized for this exact GraphQLSchema instance.
47
+ let tablesMeta = [];
48
+ if (schema.getQueryType()?.getFields()._meta) {
49
+ const result = await graphql({
50
+ schema,
51
+ source: '{ _meta { tables { name } } }',
52
+ });
53
+ if (result.errors?.length) {
54
+ throw new AggregateError(result.errors, 'Failed to build schema metadata');
55
+ }
56
+ tablesMeta = getTablesMetaForSchema(schema) ?? [];
57
+ }
58
+ if (opts._onMetaCollected) {
59
+ await opts._onMetaCollected();
60
+ }
61
+ return {
62
+ sdl: printSchema(lexicographicSortSchema(schema)),
63
+ tablesMeta
64
+ };
65
+ }
66
+ export async function buildSchemaSDL(opts) {
67
+ return (await buildSchemaArtifacts(opts)).sdl;
39
68
  }
package/esm/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- export { buildSchemaSDL } from './build-schema';
2
- export type { BuildSchemaOptions } from './build-schema';
1
+ export { buildSchemaArtifacts, buildSchemaSDL } from './build-schema';
2
+ export type { BuildSchemaArtifacts, BuildSchemaOptions } from './build-schema';
3
3
  export { buildIntrospectionJSON } from './build-introspection';
4
- export { _cachedTablesMeta } from 'graphile-settings';
5
4
  export type { TableMeta, FieldMeta, TypeMeta, IndexMeta, ConstraintsMeta, PrimaryKeyConstraintMeta, UniqueConstraintMeta, ForeignKeyConstraintMeta, RelationsMeta, BelongsToRelation, HasRelation, ManyToManyRelation, InflectionMeta, QueryMeta, } from 'graphile-settings';
6
5
  export { fetchEndpointSchemaSDL } from './fetch-endpoint-schema';
7
6
  export type { FetchEndpointSchemaOptions } from './fetch-endpoint-schema';
package/esm/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export { buildSchemaSDL } from './build-schema';
1
+ export { buildSchemaArtifacts, buildSchemaSDL } from './build-schema';
2
2
  export { buildIntrospectionJSON } from './build-introspection';
3
- export { _cachedTablesMeta } from 'graphile-settings';
4
3
  export { fetchEndpointSchemaSDL } from './fetch-endpoint-schema';
package/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- export { buildSchemaSDL } from './build-schema';
2
- export type { BuildSchemaOptions } from './build-schema';
1
+ export { buildSchemaArtifacts, buildSchemaSDL } from './build-schema';
2
+ export type { BuildSchemaArtifacts, BuildSchemaOptions } from './build-schema';
3
3
  export { buildIntrospectionJSON } from './build-introspection';
4
- export { _cachedTablesMeta } from 'graphile-settings';
5
4
  export type { TableMeta, FieldMeta, TypeMeta, IndexMeta, ConstraintsMeta, PrimaryKeyConstraintMeta, UniqueConstraintMeta, ForeignKeyConstraintMeta, RelationsMeta, BelongsToRelation, HasRelation, ManyToManyRelation, InflectionMeta, QueryMeta, } from 'graphile-settings';
6
5
  export { fetchEndpointSchemaSDL } from './fetch-endpoint-schema';
7
6
  export type { FetchEndpointSchemaOptions } from './fetch-endpoint-schema';
package/index.js CHANGED
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchEndpointSchemaSDL = exports._cachedTablesMeta = exports.buildIntrospectionJSON = exports.buildSchemaSDL = void 0;
3
+ exports.fetchEndpointSchemaSDL = exports.buildIntrospectionJSON = exports.buildSchemaSDL = exports.buildSchemaArtifacts = void 0;
4
4
  var build_schema_1 = require("./build-schema");
5
+ Object.defineProperty(exports, "buildSchemaArtifacts", { enumerable: true, get: function () { return build_schema_1.buildSchemaArtifacts; } });
5
6
  Object.defineProperty(exports, "buildSchemaSDL", { enumerable: true, get: function () { return build_schema_1.buildSchemaSDL; } });
6
7
  var build_introspection_1 = require("./build-introspection");
7
8
  Object.defineProperty(exports, "buildIntrospectionJSON", { enumerable: true, get: function () { return build_introspection_1.buildIntrospectionJSON; } });
8
- var graphile_settings_1 = require("graphile-settings");
9
- Object.defineProperty(exports, "_cachedTablesMeta", { enumerable: true, get: function () { return graphile_settings_1._cachedTablesMeta; } });
10
9
  var fetch_endpoint_schema_1 = require("./fetch-endpoint-schema");
11
10
  Object.defineProperty(exports, "fetchEndpointSchemaSDL", { enumerable: true, get: function () { return fetch_endpoint_schema_1.fetchEndpointSchemaSDL; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphile-schema",
3
- "version": "2.10.4",
3
+ "version": "2.10.5",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Build GraphQL SDL from PostgreSQL databases using PostGraphile v5",
6
6
  "main": "index.js",
@@ -32,13 +32,14 @@
32
32
  "deepmerge": "^4.3.1",
33
33
  "graphile-build": "5.0.2",
34
34
  "graphile-config": "1.0.1",
35
- "graphile-settings": "^6.11.4",
35
+ "graphile-settings": "^6.11.5",
36
36
  "graphql": "16.13.0",
37
37
  "pg-cache": "^3.24.2",
38
38
  "pg-env": "^1.27.2"
39
39
  },
40
40
  "devDependencies": {
41
41
  "makage": "^0.3.0",
42
+ "pgsql-test": "^5.9.5",
42
43
  "ts-node": "^10.9.2"
43
44
  },
44
45
  "keywords": [
@@ -50,5 +51,5 @@
50
51
  "introspection",
51
52
  "constructive"
52
53
  ],
53
- "gitHead": "90f447482b056a4949134565db2665f21d11aca3"
54
+ "gitHead": "7a37da1f5655c36813343f09c6efa62ca0d7a855"
54
55
  }