@constructive-io/graphql-server 5.25.2 → 5.27.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/esm/middleware/graphile-introspection.js +65 -0
- package/esm/middleware/graphile.js +29 -29
- package/middleware/graphile-introspection.d.ts +23 -0
- package/middleware/graphile-introspection.js +70 -0
- package/middleware/graphile.js +28 -28
- package/middleware/types.d.ts +2 -14
- package/package.json +25 -24
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { resolvePreset } from 'graphile-config';
|
|
2
|
+
import { makePgService } from 'graphile-settings';
|
|
3
|
+
const SCOPED_INTROSPECTION_PLUGIN = 'ConstructivePgIntrospectionPlugin';
|
|
4
|
+
let scopedIntrospectionPresetPromise;
|
|
5
|
+
const loadScopedIntrospectionPreset = () => {
|
|
6
|
+
scopedIntrospectionPresetPromise ??=
|
|
7
|
+
import('graphile-scoped-introspection').then(({ ScopedIntrospectionPreset }) => ScopedIntrospectionPreset);
|
|
8
|
+
return scopedIntrospectionPresetPromise;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Resolve caller-provided Graphile configuration before deciding whether the
|
|
12
|
+
* optional scoped introspection package is needed. Graphile config applies
|
|
13
|
+
* nested `extends` entries before the containing preset, so this preserves the
|
|
14
|
+
* same precedence used by the eventual schema build.
|
|
15
|
+
*/
|
|
16
|
+
export const resolveCallerPreset = (graphileOptions) => {
|
|
17
|
+
const preset = graphileOptions?.preset;
|
|
18
|
+
const presets = [
|
|
19
|
+
...(graphileOptions?.extends ?? []),
|
|
20
|
+
...(preset ? [preset] : [])
|
|
21
|
+
];
|
|
22
|
+
return presets.length > 0 ? resolvePreset({ extends: presets }) : undefined;
|
|
23
|
+
};
|
|
24
|
+
const hasLocalScopedIntrospectionPreset = (preset) => preset?.plugins.some((plugin) => plugin.name === SCOPED_INTROSPECTION_PLUGIN) ??
|
|
25
|
+
false;
|
|
26
|
+
const hasUpstreamIntrospectionDisabled = (preset) => preset?.disablePlugins.includes('PgIntrospectionPlugin') ?? false;
|
|
27
|
+
/**
|
|
28
|
+
* Select the stock or scoped introspection wiring once, while constructing a
|
|
29
|
+
* server-owned schema handler. The stock branch returns before the scoped
|
|
30
|
+
* package (and its upstream contract sentinel) is loaded.
|
|
31
|
+
*/
|
|
32
|
+
export const makeIntrospectionWiring = async (pool, schemas, graphileOptions, loadScopedPreset = loadScopedIntrospectionPreset, introspectionRole) => {
|
|
33
|
+
const pgSettingsForIntrospection = introspectionRole ? { role: introspectionRole } : undefined;
|
|
34
|
+
const pgService = makePgService({ pool, schemas, pgSettingsForIntrospection });
|
|
35
|
+
const callerPreset = resolveCallerPreset(graphileOptions);
|
|
36
|
+
const scopedConfig = callerPreset?.gather?.pgScopedIntrospection;
|
|
37
|
+
const hasScopedConfiguration = scopedConfig !== undefined;
|
|
38
|
+
// An explicitly supplied local preset already installs the replacement
|
|
39
|
+
// plugin. Keep that path synchronous and avoid importing the optional
|
|
40
|
+
// package a second time. A raw plugin entry may omit the stock plugin's
|
|
41
|
+
// disablement, so add that narrow preset to keep the replacement atomic.
|
|
42
|
+
if (hasLocalScopedIntrospectionPreset(callerPreset)) {
|
|
43
|
+
return {
|
|
44
|
+
presets: hasUpstreamIntrospectionDisabled(callerPreset)
|
|
45
|
+
? []
|
|
46
|
+
: [{ disablePlugins: ['PgIntrospectionPlugin'] }],
|
|
47
|
+
pgService
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (!hasScopedConfiguration) {
|
|
51
|
+
return {
|
|
52
|
+
presets: [],
|
|
53
|
+
pgService
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Load the replacement whenever the map is supplied, including an empty map,
|
|
57
|
+
// entries set to false, or entries keyed by an unknown service. The
|
|
58
|
+
// replacement owns validation; leaving it out would cause Graphile's stock
|
|
59
|
+
// plugin to silently ignore the gather option in those cases.
|
|
60
|
+
const scopedPreset = await loadScopedPreset();
|
|
61
|
+
return {
|
|
62
|
+
presets: [scopedPreset],
|
|
63
|
+
pgService
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -5,7 +5,7 @@ import { getNodeEnv } from '@pgpmjs/env';
|
|
|
5
5
|
import { Logger } from '@pgpmjs/logger';
|
|
6
6
|
import { createGraphileInstance, graphileCache } from 'graphile-cache';
|
|
7
7
|
import { createFunctionBindingsPlugin } from 'graphile-function-bindings';
|
|
8
|
-
import { createConstructivePreset
|
|
8
|
+
import { createConstructivePreset } from 'graphile-settings';
|
|
9
9
|
import { getPgPool } from 'pg-cache';
|
|
10
10
|
import { getPgEnvOptions } from 'pg-env';
|
|
11
11
|
import { isGraphqlObservabilityEnabled } from '../diagnostics/observability';
|
|
@@ -14,6 +14,7 @@ import { respondWithGraphQLError } from '../errors/graphql-response';
|
|
|
14
14
|
import { AuthCookiePlugin } from '../plugins/auth-cookie-plugin';
|
|
15
15
|
import { createErrorEventsPlugin } from '../plugins/error-events-plugin';
|
|
16
16
|
import { RequestProtectionPlugin } from '../plugins/request-protection-plugin';
|
|
17
|
+
import { makeIntrospectionWiring } from './graphile-introspection';
|
|
17
18
|
import { maskError } from './mask-error';
|
|
18
19
|
import { observeGraphileBuild } from './observability/graphile-build-stats';
|
|
19
20
|
const isDev = () => getNodeEnv() === 'development';
|
|
@@ -56,10 +57,19 @@ const reqLabel = (req) => (req.requestId ? `[${req.requestId}]` : '[req]');
|
|
|
56
57
|
* plugin preset. Without settings the default preset is used
|
|
57
58
|
* (everything on except aggregates).
|
|
58
59
|
*/
|
|
59
|
-
const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, databaseSettings, apiId, compute) => {
|
|
60
|
+
const buildPreset = async (pool, schemas, anonRole, roleName, introspectionRole, graphileOptions, databaseSettings, apiId, compute) => {
|
|
61
|
+
const introspection = await makeIntrospectionWiring(pool, schemas, graphileOptions, undefined, introspectionRole);
|
|
62
|
+
const configuredPreset = graphileOptions?.preset ?? {};
|
|
60
63
|
return {
|
|
61
|
-
|
|
64
|
+
...configuredPreset,
|
|
65
|
+
extends: [
|
|
66
|
+
createConstructivePreset(databaseSettings),
|
|
67
|
+
...(graphileOptions?.extends ?? []),
|
|
68
|
+
...(configuredPreset.extends ?? []),
|
|
69
|
+
...introspection.presets
|
|
70
|
+
],
|
|
62
71
|
plugins: [
|
|
72
|
+
...(configuredPreset.plugins ?? []),
|
|
63
73
|
AuthCookiePlugin,
|
|
64
74
|
RequestProtectionPlugin,
|
|
65
75
|
createErrorEventsPlugin(pool),
|
|
@@ -83,20 +93,7 @@ const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, datab
|
|
|
83
93
|
]
|
|
84
94
|
: [])
|
|
85
95
|
],
|
|
86
|
-
pgServices: [
|
|
87
|
-
makePgService({
|
|
88
|
-
pool,
|
|
89
|
-
schemas,
|
|
90
|
-
// Introspection runs outside any request, so it has no served role to
|
|
91
|
-
// inherit: unset, it reads the catalog as whatever role the pool
|
|
92
|
-
// connected as (a superuser in most deployments) and the schema
|
|
93
|
-
// advertises that role's reach. Naming the role keeps schema shape
|
|
94
|
-
// tied to a bounded role's grants.
|
|
95
|
-
...(introspectionRole && {
|
|
96
|
-
pgSettingsForIntrospection: { role: introspectionRole }
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
],
|
|
96
|
+
pgServices: [introspection.pgService],
|
|
100
97
|
grafserv: {
|
|
101
98
|
graphqlPath: '/graphql',
|
|
102
99
|
graphiqlPath: '/graphiql',
|
|
@@ -304,18 +301,21 @@ export const graphile = (opts) => {
|
|
|
304
301
|
// Route through pg-cache so the pool is tracked and can be cleaned up
|
|
305
302
|
// properly, preventing leaked connections during database teardown.
|
|
306
303
|
const pool = getPgPool(pgConfig);
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
304
|
+
// Register the creation promise before any asynchronous preset work so
|
|
305
|
+
// concurrent requests coalesce while optional plugin modules load.
|
|
306
|
+
const creationPromise = (async () => {
|
|
307
|
+
const compute = api.apiId ? await req.constructive?.useModule('compute') : undefined;
|
|
308
|
+
const preset = await buildPreset(pool, schema || [], anonRole, roleName, opts.api?.introspectionRole, opts.graphile, api.databaseSettings, api.apiId, compute);
|
|
309
|
+
return observeGraphileBuild({
|
|
310
|
+
cacheKey: key,
|
|
311
|
+
serviceKey: key,
|
|
312
|
+
databaseId: api.databaseId ?? null
|
|
313
|
+
}, () => createGraphileInstance({
|
|
314
|
+
preset,
|
|
315
|
+
cacheKey: key,
|
|
316
|
+
enableRealtime: api.databaseSettings?.enableRealtime
|
|
317
|
+
}), { enabled: observabilityEnabled });
|
|
318
|
+
})();
|
|
319
319
|
creating.set(key, creationPromise);
|
|
320
320
|
try {
|
|
321
321
|
const instance = await creationPromise;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { GraphileOptions } from '@constructive-io/graphql-types';
|
|
2
|
+
import { type GraphileConfig } from 'graphile-config';
|
|
3
|
+
import type { Pool } from 'pg';
|
|
4
|
+
export interface IntrospectionWiring {
|
|
5
|
+
presets: GraphileConfig.Preset[];
|
|
6
|
+
pgService: GraphileConfig.PgServiceConfiguration;
|
|
7
|
+
}
|
|
8
|
+
export type ScopedIntrospectionPresetLoader = () => Promise<GraphileConfig.Preset>;
|
|
9
|
+
type ResolvedCallerPreset = GraphileConfig.ResolvedPreset | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve caller-provided Graphile configuration before deciding whether the
|
|
12
|
+
* optional scoped introspection package is needed. Graphile config applies
|
|
13
|
+
* nested `extends` entries before the containing preset, so this preserves the
|
|
14
|
+
* same precedence used by the eventual schema build.
|
|
15
|
+
*/
|
|
16
|
+
export declare const resolveCallerPreset: (graphileOptions: GraphileOptions | undefined) => ResolvedCallerPreset;
|
|
17
|
+
/**
|
|
18
|
+
* Select the stock or scoped introspection wiring once, while constructing a
|
|
19
|
+
* server-owned schema handler. The stock branch returns before the scoped
|
|
20
|
+
* package (and its upstream contract sentinel) is loaded.
|
|
21
|
+
*/
|
|
22
|
+
export declare const makeIntrospectionWiring: (pool: Pool, schemas: string[], graphileOptions: GraphileOptions | undefined, loadScopedPreset?: ScopedIntrospectionPresetLoader, introspectionRole?: string) => Promise<IntrospectionWiring>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeIntrospectionWiring = exports.resolveCallerPreset = void 0;
|
|
4
|
+
const graphile_config_1 = require("graphile-config");
|
|
5
|
+
const graphile_settings_1 = require("graphile-settings");
|
|
6
|
+
const SCOPED_INTROSPECTION_PLUGIN = 'ConstructivePgIntrospectionPlugin';
|
|
7
|
+
let scopedIntrospectionPresetPromise;
|
|
8
|
+
const loadScopedIntrospectionPreset = () => {
|
|
9
|
+
scopedIntrospectionPresetPromise ??=
|
|
10
|
+
import('graphile-scoped-introspection').then(({ ScopedIntrospectionPreset }) => ScopedIntrospectionPreset);
|
|
11
|
+
return scopedIntrospectionPresetPromise;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Resolve caller-provided Graphile configuration before deciding whether the
|
|
15
|
+
* optional scoped introspection package is needed. Graphile config applies
|
|
16
|
+
* nested `extends` entries before the containing preset, so this preserves the
|
|
17
|
+
* same precedence used by the eventual schema build.
|
|
18
|
+
*/
|
|
19
|
+
const resolveCallerPreset = (graphileOptions) => {
|
|
20
|
+
const preset = graphileOptions?.preset;
|
|
21
|
+
const presets = [
|
|
22
|
+
...(graphileOptions?.extends ?? []),
|
|
23
|
+
...(preset ? [preset] : [])
|
|
24
|
+
];
|
|
25
|
+
return presets.length > 0 ? (0, graphile_config_1.resolvePreset)({ extends: presets }) : undefined;
|
|
26
|
+
};
|
|
27
|
+
exports.resolveCallerPreset = resolveCallerPreset;
|
|
28
|
+
const hasLocalScopedIntrospectionPreset = (preset) => preset?.plugins.some((plugin) => plugin.name === SCOPED_INTROSPECTION_PLUGIN) ??
|
|
29
|
+
false;
|
|
30
|
+
const hasUpstreamIntrospectionDisabled = (preset) => preset?.disablePlugins.includes('PgIntrospectionPlugin') ?? false;
|
|
31
|
+
/**
|
|
32
|
+
* Select the stock or scoped introspection wiring once, while constructing a
|
|
33
|
+
* server-owned schema handler. The stock branch returns before the scoped
|
|
34
|
+
* package (and its upstream contract sentinel) is loaded.
|
|
35
|
+
*/
|
|
36
|
+
const makeIntrospectionWiring = async (pool, schemas, graphileOptions, loadScopedPreset = loadScopedIntrospectionPreset, introspectionRole) => {
|
|
37
|
+
const pgSettingsForIntrospection = introspectionRole ? { role: introspectionRole } : undefined;
|
|
38
|
+
const pgService = (0, graphile_settings_1.makePgService)({ pool, schemas, pgSettingsForIntrospection });
|
|
39
|
+
const callerPreset = (0, exports.resolveCallerPreset)(graphileOptions);
|
|
40
|
+
const scopedConfig = callerPreset?.gather?.pgScopedIntrospection;
|
|
41
|
+
const hasScopedConfiguration = scopedConfig !== undefined;
|
|
42
|
+
// An explicitly supplied local preset already installs the replacement
|
|
43
|
+
// plugin. Keep that path synchronous and avoid importing the optional
|
|
44
|
+
// package a second time. A raw plugin entry may omit the stock plugin's
|
|
45
|
+
// disablement, so add that narrow preset to keep the replacement atomic.
|
|
46
|
+
if (hasLocalScopedIntrospectionPreset(callerPreset)) {
|
|
47
|
+
return {
|
|
48
|
+
presets: hasUpstreamIntrospectionDisabled(callerPreset)
|
|
49
|
+
? []
|
|
50
|
+
: [{ disablePlugins: ['PgIntrospectionPlugin'] }],
|
|
51
|
+
pgService
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!hasScopedConfiguration) {
|
|
55
|
+
return {
|
|
56
|
+
presets: [],
|
|
57
|
+
pgService
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Load the replacement whenever the map is supplied, including an empty map,
|
|
61
|
+
// entries set to false, or entries keyed by an unknown service. The
|
|
62
|
+
// replacement owns validation; leaving it out would cause Graphile's stock
|
|
63
|
+
// plugin to silently ignore the gather option in those cases.
|
|
64
|
+
const scopedPreset = await loadScopedPreset();
|
|
65
|
+
return {
|
|
66
|
+
presets: [scopedPreset],
|
|
67
|
+
pgService
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
exports.makeIntrospectionWiring = makeIntrospectionWiring;
|
package/middleware/graphile.js
CHANGED
|
@@ -20,6 +20,7 @@ const graphql_response_1 = require("../errors/graphql-response");
|
|
|
20
20
|
const auth_cookie_plugin_1 = require("../plugins/auth-cookie-plugin");
|
|
21
21
|
const error_events_plugin_1 = require("../plugins/error-events-plugin");
|
|
22
22
|
const request_protection_plugin_1 = require("../plugins/request-protection-plugin");
|
|
23
|
+
const graphile_introspection_1 = require("./graphile-introspection");
|
|
23
24
|
const mask_error_1 = require("./mask-error");
|
|
24
25
|
const graphile_build_stats_1 = require("./observability/graphile-build-stats");
|
|
25
26
|
const isDev = () => (0, env_1.getNodeEnv)() === 'development';
|
|
@@ -62,10 +63,19 @@ const reqLabel = (req) => (req.requestId ? `[${req.requestId}]` : '[req]');
|
|
|
62
63
|
* plugin preset. Without settings the default preset is used
|
|
63
64
|
* (everything on except aggregates).
|
|
64
65
|
*/
|
|
65
|
-
const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, databaseSettings, apiId, compute) => {
|
|
66
|
+
const buildPreset = async (pool, schemas, anonRole, roleName, introspectionRole, graphileOptions, databaseSettings, apiId, compute) => {
|
|
67
|
+
const introspection = await (0, graphile_introspection_1.makeIntrospectionWiring)(pool, schemas, graphileOptions, undefined, introspectionRole);
|
|
68
|
+
const configuredPreset = graphileOptions?.preset ?? {};
|
|
66
69
|
return {
|
|
67
|
-
|
|
70
|
+
...configuredPreset,
|
|
71
|
+
extends: [
|
|
72
|
+
(0, graphile_settings_1.createConstructivePreset)(databaseSettings),
|
|
73
|
+
...(graphileOptions?.extends ?? []),
|
|
74
|
+
...(configuredPreset.extends ?? []),
|
|
75
|
+
...introspection.presets
|
|
76
|
+
],
|
|
68
77
|
plugins: [
|
|
78
|
+
...(configuredPreset.plugins ?? []),
|
|
69
79
|
auth_cookie_plugin_1.AuthCookiePlugin,
|
|
70
80
|
request_protection_plugin_1.RequestProtectionPlugin,
|
|
71
81
|
(0, error_events_plugin_1.createErrorEventsPlugin)(pool),
|
|
@@ -89,20 +99,7 @@ const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, datab
|
|
|
89
99
|
]
|
|
90
100
|
: [])
|
|
91
101
|
],
|
|
92
|
-
pgServices: [
|
|
93
|
-
(0, graphile_settings_1.makePgService)({
|
|
94
|
-
pool,
|
|
95
|
-
schemas,
|
|
96
|
-
// Introspection runs outside any request, so it has no served role to
|
|
97
|
-
// inherit: unset, it reads the catalog as whatever role the pool
|
|
98
|
-
// connected as (a superuser in most deployments) and the schema
|
|
99
|
-
// advertises that role's reach. Naming the role keeps schema shape
|
|
100
|
-
// tied to a bounded role's grants.
|
|
101
|
-
...(introspectionRole && {
|
|
102
|
-
pgSettingsForIntrospection: { role: introspectionRole }
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
],
|
|
102
|
+
pgServices: [introspection.pgService],
|
|
106
103
|
grafserv: {
|
|
107
104
|
graphqlPath: '/graphql',
|
|
108
105
|
graphiqlPath: '/graphiql',
|
|
@@ -310,18 +307,21 @@ const graphile = (opts) => {
|
|
|
310
307
|
// Route through pg-cache so the pool is tracked and can be cleaned up
|
|
311
308
|
// properly, preventing leaked connections during database teardown.
|
|
312
309
|
const pool = (0, pg_cache_1.getPgPool)(pgConfig);
|
|
313
|
-
//
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
310
|
+
// Register the creation promise before any asynchronous preset work so
|
|
311
|
+
// concurrent requests coalesce while optional plugin modules load.
|
|
312
|
+
const creationPromise = (async () => {
|
|
313
|
+
const compute = api.apiId ? await req.constructive?.useModule('compute') : undefined;
|
|
314
|
+
const preset = await buildPreset(pool, schema || [], anonRole, roleName, opts.api?.introspectionRole, opts.graphile, api.databaseSettings, api.apiId, compute);
|
|
315
|
+
return (0, graphile_build_stats_1.observeGraphileBuild)({
|
|
316
|
+
cacheKey: key,
|
|
317
|
+
serviceKey: key,
|
|
318
|
+
databaseId: api.databaseId ?? null
|
|
319
|
+
}, () => (0, graphile_cache_1.createGraphileInstance)({
|
|
320
|
+
preset,
|
|
321
|
+
cacheKey: key,
|
|
322
|
+
enableRealtime: api.databaseSettings?.enableRealtime
|
|
323
|
+
}), { enabled: observabilityEnabled });
|
|
324
|
+
})();
|
|
325
325
|
creating.set(key, creationPromise);
|
|
326
326
|
try {
|
|
327
327
|
const instance = await creationPromise;
|
package/middleware/types.d.ts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
import type { RequestProtection } from '@constructive-io/express-context';
|
|
2
|
-
|
|
3
|
-
export type ConstructiveAPIToken = {
|
|
4
|
-
id?: string;
|
|
5
|
-
user_id?: string;
|
|
6
|
-
principal_id?: string;
|
|
7
|
-
session_id?: string;
|
|
8
|
-
access_level?: string;
|
|
9
|
-
kind?: string;
|
|
10
|
-
root_session_id?: string;
|
|
11
|
-
parent_session_id?: string;
|
|
12
|
-
intent?: string;
|
|
13
|
-
[key: string]: unknown;
|
|
14
|
-
};
|
|
1
|
+
import type { ApiStructure, ConstructiveAPIToken, RequestProtection } from '@constructive-io/express-context';
|
|
2
|
+
export type { ConstructiveAPIToken } from '@constructive-io/express-context';
|
|
15
3
|
declare global {
|
|
16
4
|
namespace Express {
|
|
17
5
|
interface Request {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-server",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.27.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive GraphQL Server",
|
|
6
6
|
"main": "index.js",
|
|
@@ -41,41 +41,42 @@
|
|
|
41
41
|
"backend"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@agentic-kit/ollama": "2.
|
|
45
|
-
"@constructive-io/csrf": "^0.
|
|
46
|
-
"@constructive-io/errors": "^0.
|
|
47
|
-
"@constructive-io/express-context": "^0.
|
|
48
|
-
"@constructive-io/graphql-env": "^3.
|
|
49
|
-
"@constructive-io/graphql-types": "^3.
|
|
50
|
-
"@constructive-io/llm-env": "^0.
|
|
51
|
-
"@constructive-io/query-builder": "^3.
|
|
52
|
-
"@constructive-io/s3-utils": "^2.
|
|
53
|
-
"@constructive-io/url-domains": "^2.
|
|
44
|
+
"@agentic-kit/ollama": "2.15.0",
|
|
45
|
+
"@constructive-io/csrf": "^0.30.0",
|
|
46
|
+
"@constructive-io/errors": "^0.18.0",
|
|
47
|
+
"@constructive-io/express-context": "^0.33.0",
|
|
48
|
+
"@constructive-io/graphql-env": "^3.34.0",
|
|
49
|
+
"@constructive-io/graphql-types": "^3.33.0",
|
|
50
|
+
"@constructive-io/llm-env": "^0.15.0",
|
|
51
|
+
"@constructive-io/query-builder": "^3.15.0",
|
|
52
|
+
"@constructive-io/s3-utils": "^2.34.0",
|
|
53
|
+
"@constructive-io/url-domains": "^2.31.0",
|
|
54
54
|
"@graphile-contrib/pg-many-to-many": "2.0.0-rc.2",
|
|
55
|
-
"@pgpmjs/env": "^2.
|
|
56
|
-
"@pgpmjs/logger": "^2.
|
|
57
|
-
"@pgpmjs/server-utils": "^3.
|
|
58
|
-
"@pgpmjs/types": "^2.
|
|
55
|
+
"@pgpmjs/env": "^2.45.0",
|
|
56
|
+
"@pgpmjs/logger": "^2.26.0",
|
|
57
|
+
"@pgpmjs/server-utils": "^3.29.0",
|
|
58
|
+
"@pgpmjs/types": "^2.55.0",
|
|
59
59
|
"cors": "^2.8.6",
|
|
60
60
|
"deepmerge": "^4.3.1",
|
|
61
61
|
"express": "^5.2.1",
|
|
62
|
-
"gql-ast": "^3.
|
|
62
|
+
"gql-ast": "^3.25.0",
|
|
63
63
|
"grafast": "1.1.2",
|
|
64
64
|
"grafserv": "1.0.1",
|
|
65
65
|
"graphile-build": "5.1.1",
|
|
66
66
|
"graphile-build-pg": "5.1.3",
|
|
67
|
-
"graphile-cache": "^4.
|
|
67
|
+
"graphile-cache": "^4.14.0",
|
|
68
68
|
"graphile-config": "1.1.0",
|
|
69
|
-
"graphile-function-bindings": "^1.
|
|
70
|
-
"graphile-
|
|
69
|
+
"graphile-function-bindings": "^1.16.0",
|
|
70
|
+
"graphile-scoped-introspection": "^0.3.0",
|
|
71
|
+
"graphile-settings": "^6.23.0",
|
|
71
72
|
"graphile-utils": "5.0.3",
|
|
72
73
|
"graphql": "16.13.0",
|
|
73
74
|
"graphql-upload": "^13.0.0",
|
|
74
75
|
"lru-cache": "^11.2.7",
|
|
75
76
|
"pg": "^8.21.0",
|
|
76
|
-
"pg-cache": "^3.
|
|
77
|
-
"pg-env": "^1.
|
|
78
|
-
"pg-query-context": "^2.
|
|
77
|
+
"pg-cache": "^3.29.0",
|
|
78
|
+
"pg-env": "^1.32.0",
|
|
79
|
+
"pg-query-context": "^2.31.0",
|
|
79
80
|
"pg-sql2": "5.0.1",
|
|
80
81
|
"postgraphile": "5.1.4",
|
|
81
82
|
"request-ip": "^3.3.0"
|
|
@@ -90,11 +91,11 @@
|
|
|
90
91
|
"@types/request-ip": "^0.0.41",
|
|
91
92
|
"@types/supertest": "^7.2.1",
|
|
92
93
|
"cookie-parser": "^1.4.7",
|
|
93
|
-
"graphile-test": "5.
|
|
94
|
+
"graphile-test": "5.16.0",
|
|
94
95
|
"makage": "^0.8.0",
|
|
95
96
|
"nodemon": "^3.1.14",
|
|
96
97
|
"supertest": "^7.2.2",
|
|
97
98
|
"ts-node": "^10.9.2"
|
|
98
99
|
},
|
|
99
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "baa84094b8541eb5000701b0060aa5b298032dc7"
|
|
100
101
|
}
|