@constructive-io/graphql-server 5.32.1 → 5.32.2
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.
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { resolvePreset } from 'graphile-config';
|
|
2
|
+
import { ScopedIntrospectionPreset } from 'graphile-scoped-introspection';
|
|
2
3
|
import { makePgService } from 'graphile-settings';
|
|
3
|
-
const
|
|
4
|
-
let scopedIntrospectionPresetPromise;
|
|
5
|
-
const loadScopedIntrospectionPreset = () => {
|
|
6
|
-
scopedIntrospectionPresetPromise ??=
|
|
7
|
-
import('graphile-scoped-introspection').then(({ ScopedIntrospectionPreset }) => ScopedIntrospectionPreset);
|
|
8
|
-
return scopedIntrospectionPresetPromise;
|
|
9
|
-
};
|
|
4
|
+
const SERVICE_NAME = 'main';
|
|
10
5
|
/**
|
|
11
|
-
* Resolve caller-provided Graphile configuration
|
|
12
|
-
*
|
|
13
|
-
* nested `extends` entries before the containing preset, so this preserves the
|
|
14
|
-
* same precedence used by the eventual schema build.
|
|
6
|
+
* Resolve caller-provided Graphile configuration with the same `extends`
|
|
7
|
+
* precedence used by the eventual schema build.
|
|
15
8
|
*/
|
|
16
9
|
export const resolveCallerPreset = (graphileOptions) => {
|
|
17
10
|
const preset = graphileOptions?.preset;
|
|
@@ -21,45 +14,29 @@ export const resolveCallerPreset = (graphileOptions) => {
|
|
|
21
14
|
];
|
|
22
15
|
return presets.length > 0 ? resolvePreset({ extends: presets }) : undefined;
|
|
23
16
|
};
|
|
24
|
-
const
|
|
25
|
-
false;
|
|
26
|
-
const hasUpstreamIntrospectionDisabled = (preset) => preset?.disablePlugins.includes('PgIntrospectionPlugin') ?? false;
|
|
17
|
+
const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
27
18
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
19
|
+
* Every server handler introspects only its API's schemas and their dependency
|
|
20
|
+
* closure. Stock introspection reads the whole database into each cached
|
|
21
|
+
* handler, so it is not an option here: `main: false` is rejected. Caller
|
|
22
|
+
* options for `main` (catalog policy, capability extensions) are kept.
|
|
31
23
|
*/
|
|
32
|
-
export const makeIntrospectionWiring =
|
|
24
|
+
export const makeIntrospectionWiring = (pool, schemas, graphileOptions, introspectionRole) => {
|
|
33
25
|
const pgSettingsForIntrospection = introspectionRole ? { role: introspectionRole } : undefined;
|
|
34
26
|
const pgService = makePgService({ pool, schemas, pgSettingsForIntrospection });
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
};
|
|
27
|
+
const configured = resolveCallerPreset(graphileOptions)?.gather?.pgScopedIntrospection;
|
|
28
|
+
if (configured !== undefined && !isPlainObject(configured)) {
|
|
29
|
+
throw new Error('pgScopedIntrospection must be an object keyed by PostgreSQL service name');
|
|
49
30
|
}
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
presets: [],
|
|
53
|
-
pgService
|
|
54
|
-
};
|
|
31
|
+
if (configured?.[SERVICE_NAME] === false) {
|
|
32
|
+
throw new Error(`Schema-scoped introspection cannot be disabled for the server's '${SERVICE_NAME}' service: stock introspection retains the whole database in every cached handler`);
|
|
55
33
|
}
|
|
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
34
|
return {
|
|
62
|
-
presets: [
|
|
63
|
-
pgService
|
|
35
|
+
presets: [ScopedIntrospectionPreset],
|
|
36
|
+
pgService,
|
|
37
|
+
pgScopedIntrospection: {
|
|
38
|
+
...configured,
|
|
39
|
+
[SERVICE_NAME]: configured?.[SERVICE_NAME] ?? true
|
|
40
|
+
}
|
|
64
41
|
};
|
|
65
42
|
};
|
|
@@ -2,7 +2,7 @@ import './types'; // for Request type
|
|
|
2
2
|
import { errors } from '@constructive-io/errors';
|
|
3
3
|
import { DEFAULT_REQUEST_PROTECTION, protectionPgSettings } from '@constructive-io/express-context';
|
|
4
4
|
import { Logger } from '@pgpmjs/logger';
|
|
5
|
-
import { createGraphileInstance, graphileCache } from 'graphile-cache';
|
|
5
|
+
import { cacheGraphileInstance, createGraphileInstance, graphileCache } from 'graphile-cache';
|
|
6
6
|
import { createFunctionBindingsPlugin } from 'graphile-function-bindings';
|
|
7
7
|
import { createConstructivePreset, createGrafastCacheLimitsPreset } from 'graphile-settings';
|
|
8
8
|
import { getPgPool } from 'pg-cache';
|
|
@@ -56,8 +56,8 @@ const reqLabel = (req) => (req.requestId ? `[${req.requestId}]` : '[req]');
|
|
|
56
56
|
* plugin preset. Without settings the default preset is used
|
|
57
57
|
* (everything on except aggregates).
|
|
58
58
|
*/
|
|
59
|
-
const buildPreset =
|
|
60
|
-
const introspection =
|
|
59
|
+
const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, graphileOptions, databaseSettings, apiId, compute, webauthn) => {
|
|
60
|
+
const introspection = makeIntrospectionWiring(pool, schemas, graphileOptions, introspectionRole);
|
|
61
61
|
const configuredPreset = graphileOptions?.preset ?? {};
|
|
62
62
|
const grafastCachePreset = createGrafastCacheLimitsPreset(graphileOptions?.grafastCache);
|
|
63
63
|
return {
|
|
@@ -100,6 +100,10 @@ const buildPreset = async (pool, schemas, anonRole, roleName, introspectionRole,
|
|
|
100
100
|
: [])
|
|
101
101
|
],
|
|
102
102
|
pgServices: [introspection.pgService],
|
|
103
|
+
gather: {
|
|
104
|
+
...configuredPreset.gather,
|
|
105
|
+
pgScopedIntrospection: introspection.pgScopedIntrospection
|
|
106
|
+
},
|
|
103
107
|
grafserv: {
|
|
104
108
|
graphqlPath: '/graphql',
|
|
105
109
|
graphiqlPath: '/graphiql',
|
|
@@ -279,7 +283,7 @@ export const graphile = (opts) => {
|
|
|
279
283
|
return instance.handler(req, res, next);
|
|
280
284
|
}
|
|
281
285
|
catch (error) {
|
|
282
|
-
log.warn(`${label} Coalesced request failed for PostGraphile[${key}], retrying
|
|
286
|
+
log.warn(`${label} Coalesced request failed for PostGraphile[${key}], retrying`, error);
|
|
283
287
|
// Fall through to Phase C to retry creation
|
|
284
288
|
}
|
|
285
289
|
}
|
|
@@ -311,8 +315,8 @@ export const graphile = (opts) => {
|
|
|
311
315
|
// concurrent requests coalesce while optional plugin modules load.
|
|
312
316
|
const creationPromise = (async () => {
|
|
313
317
|
const compute = api.apiId ? await req.constructive?.useModule('compute') : undefined;
|
|
314
|
-
const preset =
|
|
315
|
-
|
|
318
|
+
const preset = buildPreset(pool, schema || [], anonRole, roleName, opts.api?.introspectionRole, opts.graphile, api.databaseSettings, api.apiId, compute, Boolean(api.webauthnSettings));
|
|
319
|
+
const instance = await observeGraphileBuild({
|
|
316
320
|
cacheKey: key,
|
|
317
321
|
serviceKey: key,
|
|
318
322
|
databaseId: api.databaseId ?? null
|
|
@@ -321,11 +325,14 @@ export const graphile = (opts) => {
|
|
|
321
325
|
cacheKey: key,
|
|
322
326
|
enableRealtime: api.databaseSettings?.enableRealtime
|
|
323
327
|
}), { enabled: observabilityEnabled });
|
|
328
|
+
// Admission is part of the shared promise: a handler the cache rejects
|
|
329
|
+
// has been released, so coalesced waiters must not be handed it.
|
|
330
|
+
await cacheGraphileInstance(key, instance);
|
|
331
|
+
return instance;
|
|
324
332
|
})();
|
|
325
333
|
creating.set(key, creationPromise);
|
|
326
334
|
try {
|
|
327
335
|
const instance = await creationPromise;
|
|
328
|
-
graphileCache.set(key, instance);
|
|
329
336
|
log.info(`${label} Cached PostGraphile v5 handler key=${key} db=${dbname}`);
|
|
330
337
|
return instance.handler(req, res, next);
|
|
331
338
|
}
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import type { GraphileOptions } from '@constructive-io/graphql-types';
|
|
1
|
+
import type { GraphileOptions, PgScopedIntrospectionConfig } from '@constructive-io/graphql-types';
|
|
2
2
|
import { type GraphileConfig } from 'graphile-config';
|
|
3
3
|
import type { Pool } from 'pg';
|
|
4
4
|
export interface IntrospectionWiring {
|
|
5
5
|
presets: GraphileConfig.Preset[];
|
|
6
6
|
pgService: GraphileConfig.PgServiceConfiguration;
|
|
7
|
+
pgScopedIntrospection: PgScopedIntrospectionConfig;
|
|
7
8
|
}
|
|
8
|
-
export type ScopedIntrospectionPresetLoader = () => Promise<GraphileConfig.Preset>;
|
|
9
9
|
type ResolvedCallerPreset = GraphileConfig.ResolvedPreset | undefined;
|
|
10
10
|
/**
|
|
11
|
-
* Resolve caller-provided Graphile configuration
|
|
12
|
-
*
|
|
13
|
-
* nested `extends` entries before the containing preset, so this preserves the
|
|
14
|
-
* same precedence used by the eventual schema build.
|
|
11
|
+
* Resolve caller-provided Graphile configuration with the same `extends`
|
|
12
|
+
* precedence used by the eventual schema build.
|
|
15
13
|
*/
|
|
16
14
|
export declare const resolveCallerPreset: (graphileOptions: GraphileOptions | undefined) => ResolvedCallerPreset;
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* Every server handler introspects only its API's schemas and their dependency
|
|
17
|
+
* closure. Stock introspection reads the whole database into each cached
|
|
18
|
+
* handler, so it is not an option here: `main: false` is rejected. Caller
|
|
19
|
+
* options for `main` (catalog policy, capability extensions) are kept.
|
|
21
20
|
*/
|
|
22
|
-
export declare const makeIntrospectionWiring: (pool: Pool, schemas: string[], graphileOptions: GraphileOptions | undefined,
|
|
21
|
+
export declare const makeIntrospectionWiring: (pool: Pool, schemas: string[], graphileOptions: GraphileOptions | undefined, introspectionRole?: string) => IntrospectionWiring;
|
|
23
22
|
export {};
|
|
@@ -2,19 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeIntrospectionWiring = exports.resolveCallerPreset = void 0;
|
|
4
4
|
const graphile_config_1 = require("graphile-config");
|
|
5
|
+
const graphile_scoped_introspection_1 = require("graphile-scoped-introspection");
|
|
5
6
|
const graphile_settings_1 = require("graphile-settings");
|
|
6
|
-
const
|
|
7
|
-
let scopedIntrospectionPresetPromise;
|
|
8
|
-
const loadScopedIntrospectionPreset = () => {
|
|
9
|
-
scopedIntrospectionPresetPromise ??=
|
|
10
|
-
import('graphile-scoped-introspection').then(({ ScopedIntrospectionPreset }) => ScopedIntrospectionPreset);
|
|
11
|
-
return scopedIntrospectionPresetPromise;
|
|
12
|
-
};
|
|
7
|
+
const SERVICE_NAME = 'main';
|
|
13
8
|
/**
|
|
14
|
-
* Resolve caller-provided Graphile configuration
|
|
15
|
-
*
|
|
16
|
-
* nested `extends` entries before the containing preset, so this preserves the
|
|
17
|
-
* same precedence used by the eventual schema build.
|
|
9
|
+
* Resolve caller-provided Graphile configuration with the same `extends`
|
|
10
|
+
* precedence used by the eventual schema build.
|
|
18
11
|
*/
|
|
19
12
|
const resolveCallerPreset = (graphileOptions) => {
|
|
20
13
|
const preset = graphileOptions?.preset;
|
|
@@ -25,46 +18,30 @@ const resolveCallerPreset = (graphileOptions) => {
|
|
|
25
18
|
return presets.length > 0 ? (0, graphile_config_1.resolvePreset)({ extends: presets }) : undefined;
|
|
26
19
|
};
|
|
27
20
|
exports.resolveCallerPreset = resolveCallerPreset;
|
|
28
|
-
const
|
|
29
|
-
false;
|
|
30
|
-
const hasUpstreamIntrospectionDisabled = (preset) => preset?.disablePlugins.includes('PgIntrospectionPlugin') ?? false;
|
|
21
|
+
const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
31
22
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
23
|
+
* Every server handler introspects only its API's schemas and their dependency
|
|
24
|
+
* closure. Stock introspection reads the whole database into each cached
|
|
25
|
+
* handler, so it is not an option here: `main: false` is rejected. Caller
|
|
26
|
+
* options for `main` (catalog policy, capability extensions) are kept.
|
|
35
27
|
*/
|
|
36
|
-
const makeIntrospectionWiring =
|
|
28
|
+
const makeIntrospectionWiring = (pool, schemas, graphileOptions, introspectionRole) => {
|
|
37
29
|
const pgSettingsForIntrospection = introspectionRole ? { role: introspectionRole } : undefined;
|
|
38
30
|
const pgService = (0, graphile_settings_1.makePgService)({ pool, schemas, pgSettingsForIntrospection });
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
};
|
|
31
|
+
const configured = (0, exports.resolveCallerPreset)(graphileOptions)?.gather?.pgScopedIntrospection;
|
|
32
|
+
if (configured !== undefined && !isPlainObject(configured)) {
|
|
33
|
+
throw new Error('pgScopedIntrospection must be an object keyed by PostgreSQL service name');
|
|
53
34
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
presets: [],
|
|
57
|
-
pgService
|
|
58
|
-
};
|
|
35
|
+
if (configured?.[SERVICE_NAME] === false) {
|
|
36
|
+
throw new Error(`Schema-scoped introspection cannot be disabled for the server's '${SERVICE_NAME}' service: stock introspection retains the whole database in every cached handler`);
|
|
59
37
|
}
|
|
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
38
|
return {
|
|
66
|
-
presets: [
|
|
67
|
-
pgService
|
|
39
|
+
presets: [graphile_scoped_introspection_1.ScopedIntrospectionPreset],
|
|
40
|
+
pgService,
|
|
41
|
+
pgScopedIntrospection: {
|
|
42
|
+
...configured,
|
|
43
|
+
[SERVICE_NAME]: configured?.[SERVICE_NAME] ?? true
|
|
44
|
+
}
|
|
68
45
|
};
|
|
69
46
|
};
|
|
70
47
|
exports.makeIntrospectionWiring = makeIntrospectionWiring;
|
package/middleware/graphile.js
CHANGED
|
@@ -62,8 +62,8 @@ const reqLabel = (req) => (req.requestId ? `[${req.requestId}]` : '[req]');
|
|
|
62
62
|
* plugin preset. Without settings the default preset is used
|
|
63
63
|
* (everything on except aggregates).
|
|
64
64
|
*/
|
|
65
|
-
const buildPreset =
|
|
66
|
-
const introspection =
|
|
65
|
+
const buildPreset = (pool, schemas, anonRole, roleName, introspectionRole, graphileOptions, databaseSettings, apiId, compute, webauthn) => {
|
|
66
|
+
const introspection = (0, graphile_introspection_1.makeIntrospectionWiring)(pool, schemas, graphileOptions, introspectionRole);
|
|
67
67
|
const configuredPreset = graphileOptions?.preset ?? {};
|
|
68
68
|
const grafastCachePreset = (0, graphile_settings_1.createGrafastCacheLimitsPreset)(graphileOptions?.grafastCache);
|
|
69
69
|
return {
|
|
@@ -106,6 +106,10 @@ const buildPreset = async (pool, schemas, anonRole, roleName, introspectionRole,
|
|
|
106
106
|
: [])
|
|
107
107
|
],
|
|
108
108
|
pgServices: [introspection.pgService],
|
|
109
|
+
gather: {
|
|
110
|
+
...configuredPreset.gather,
|
|
111
|
+
pgScopedIntrospection: introspection.pgScopedIntrospection
|
|
112
|
+
},
|
|
109
113
|
grafserv: {
|
|
110
114
|
graphqlPath: '/graphql',
|
|
111
115
|
graphiqlPath: '/graphiql',
|
|
@@ -285,7 +289,7 @@ const graphile = (opts) => {
|
|
|
285
289
|
return instance.handler(req, res, next);
|
|
286
290
|
}
|
|
287
291
|
catch (error) {
|
|
288
|
-
log.warn(`${label} Coalesced request failed for PostGraphile[${key}], retrying
|
|
292
|
+
log.warn(`${label} Coalesced request failed for PostGraphile[${key}], retrying`, error);
|
|
289
293
|
// Fall through to Phase C to retry creation
|
|
290
294
|
}
|
|
291
295
|
}
|
|
@@ -317,8 +321,8 @@ const graphile = (opts) => {
|
|
|
317
321
|
// concurrent requests coalesce while optional plugin modules load.
|
|
318
322
|
const creationPromise = (async () => {
|
|
319
323
|
const compute = api.apiId ? await req.constructive?.useModule('compute') : undefined;
|
|
320
|
-
const preset =
|
|
321
|
-
|
|
324
|
+
const preset = buildPreset(pool, schema || [], anonRole, roleName, opts.api?.introspectionRole, opts.graphile, api.databaseSettings, api.apiId, compute, Boolean(api.webauthnSettings));
|
|
325
|
+
const instance = await (0, graphile_build_stats_1.observeGraphileBuild)({
|
|
322
326
|
cacheKey: key,
|
|
323
327
|
serviceKey: key,
|
|
324
328
|
databaseId: api.databaseId ?? null
|
|
@@ -327,11 +331,14 @@ const graphile = (opts) => {
|
|
|
327
331
|
cacheKey: key,
|
|
328
332
|
enableRealtime: api.databaseSettings?.enableRealtime
|
|
329
333
|
}), { enabled: observabilityEnabled });
|
|
334
|
+
// Admission is part of the shared promise: a handler the cache rejects
|
|
335
|
+
// has been released, so coalesced waiters must not be handed it.
|
|
336
|
+
await (0, graphile_cache_1.cacheGraphileInstance)(key, instance);
|
|
337
|
+
return instance;
|
|
330
338
|
})();
|
|
331
339
|
creating.set(key, creationPromise);
|
|
332
340
|
try {
|
|
333
341
|
const instance = await creationPromise;
|
|
334
|
-
graphile_cache_1.graphileCache.set(key, instance);
|
|
335
342
|
log.info(`${label} Cached PostGraphile v5 handler key=${key} db=${dbname}`);
|
|
336
343
|
return instance.handler(req, res, next);
|
|
337
344
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-server",
|
|
3
|
-
"version": "5.32.
|
|
3
|
+
"version": "5.32.2",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive GraphQL Server",
|
|
6
6
|
"main": "index.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@constructive-io/csrf": "^0.31.0",
|
|
45
45
|
"@constructive-io/errors": "^0.25.0",
|
|
46
46
|
"@constructive-io/express-context": "^0.35.0",
|
|
47
|
-
"@constructive-io/graphql-env": "^3.37.
|
|
47
|
+
"@constructive-io/graphql-env": "^3.37.1",
|
|
48
48
|
"@constructive-io/graphql-types": "^3.36.0",
|
|
49
49
|
"@constructive-io/llm-env": "^0.16.0",
|
|
50
50
|
"@constructive-io/query-builder": "^3.17.0",
|
|
@@ -65,13 +65,13 @@
|
|
|
65
65
|
"grafserv": "1.0.1",
|
|
66
66
|
"graphile-build": "5.1.1",
|
|
67
67
|
"graphile-build-pg": "5.1.3",
|
|
68
|
-
"graphile-cache": "^4.16.
|
|
68
|
+
"graphile-cache": "^4.16.1",
|
|
69
69
|
"graphile-config": "1.1.0",
|
|
70
|
-
"graphile-function-bindings": "^1.18.
|
|
70
|
+
"graphile-function-bindings": "^1.18.1",
|
|
71
71
|
"graphile-plugin-utils": "^1.14.0",
|
|
72
72
|
"graphile-presigned-url-plugin": "^1.23.1",
|
|
73
73
|
"graphile-scoped-introspection": "^0.5.0",
|
|
74
|
-
"graphile-settings": "^6.26.
|
|
74
|
+
"graphile-settings": "^6.26.2",
|
|
75
75
|
"graphile-utils": "5.0.3",
|
|
76
76
|
"graphql": "16.13.0",
|
|
77
77
|
"graphql-upload": "^13.0.0",
|
|
@@ -94,11 +94,11 @@
|
|
|
94
94
|
"@types/request-ip": "^0.0.41",
|
|
95
95
|
"@types/supertest": "^7.2.1",
|
|
96
96
|
"cookie-parser": "^1.4.7",
|
|
97
|
-
"graphile-test": "5.18.
|
|
97
|
+
"graphile-test": "5.18.1",
|
|
98
98
|
"makage": "^0.8.0",
|
|
99
99
|
"nodemon": "^3.1.14",
|
|
100
100
|
"supertest": "^7.2.2",
|
|
101
101
|
"ts-node": "^10.9.2"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "91e18cc80da92331fb3aadd5baa43251c8934bc8"
|
|
104
104
|
}
|