@snowtop/ent 0.2.8 → 0.2.10
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/action/index.d.ts +7 -4
- package/action/index.js +1 -0
- package/auth/index.d.ts +2 -1
- package/core/base.d.ts +1 -1
- package/core/config.d.ts +4 -0
- package/core/config.js +5 -1
- package/core/convert.d.ts +4 -0
- package/core/convert.js +70 -2
- package/core/date.js +5 -2
- package/core/db.d.ts +45 -3
- package/core/db.js +260 -24
- package/core/ent.js +9 -5
- package/core/extensions.d.ts +8 -3
- package/core/extensions.js +10 -1
- package/core/global_schema.js +1 -1
- package/core/loaders/loader.d.ts +4 -4
- package/core/logger.js +4 -2
- package/core/privacy.d.ts +2 -6
- package/core/privacy.js +8 -2
- package/core/query/index.d.ts +4 -2
- package/graphql/graphql.d.ts +2 -0
- package/graphql/graphql.js +91 -22
- package/graphql/index.d.ts +6 -3
- package/index.d.ts +10 -5
- package/package.json +1 -1
- package/schema/base_schema.d.ts +1 -1
- package/schema/index.d.ts +5 -4
- package/schema/schema.d.ts +3 -1
- package/scripts/custom_graphql.js +47 -34
- package/scripts/parse_args.d.ts +3 -0
- package/scripts/parse_args.js +74 -0
- package/testutils/ent-graphql-tests/index.d.ts +6 -0
- package/testutils/ent-graphql-tests/index.js +142 -54
|
@@ -41,6 +41,7 @@ const glob = __importStar(require("glob"));
|
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const typescript_1 = __importDefault(require("typescript"));
|
|
44
|
+
const url_1 = require("url");
|
|
44
45
|
const graphql_1 = require("../graphql/graphql");
|
|
45
46
|
const readline = __importStar(require("readline"));
|
|
46
47
|
const imports_1 = require("../imports");
|
|
@@ -52,6 +53,9 @@ const { parseArgs } = require("./parse_args");
|
|
|
52
53
|
// we're affecting the local paths as opposed to a different instance
|
|
53
54
|
// life is hard
|
|
54
55
|
const MODULE_PATH = const_1.GRAPHQL_PATH;
|
|
56
|
+
function isBunRuntime() {
|
|
57
|
+
return process.env.ENT_RUNTIME === "bun" || process.versions.bun;
|
|
58
|
+
}
|
|
55
59
|
function parseJSONC(fileName, text) {
|
|
56
60
|
const { config, error } = typescript_1.default.parseConfigFileTextToJson(fileName, text);
|
|
57
61
|
if (error) {
|
|
@@ -171,22 +175,28 @@ async function captureDynamic(filePath, gqlCapture) {
|
|
|
171
175
|
return;
|
|
172
176
|
}
|
|
173
177
|
return new Promise((resolve, reject) => {
|
|
174
|
-
let cmd = "";
|
|
175
|
-
const args = [];
|
|
176
178
|
const env = {
|
|
177
179
|
...process.env,
|
|
178
180
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
let cmd = "ts-node";
|
|
182
|
+
const args = [];
|
|
183
|
+
const runtime = isBunRuntime() ? "bun" : "node";
|
|
184
|
+
if (runtime === "bun") {
|
|
185
|
+
cmd = "bun";
|
|
186
|
+
args.push(filePath);
|
|
184
187
|
}
|
|
185
188
|
else {
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
if (process.env.ENABLE_SWC) {
|
|
190
|
+
cmd = "node";
|
|
191
|
+
// we seem to get tsconfig-paths by default because child process but not 100% sure...
|
|
192
|
+
args.push("-r", "@swc-node/register");
|
|
193
|
+
env.SWCRC = "true";
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
args.push("--transpileOnly");
|
|
197
|
+
}
|
|
198
|
+
args.push(filePath);
|
|
188
199
|
}
|
|
189
|
-
args.push(filePath);
|
|
190
200
|
const r = (0, child_process_1.spawn)(cmd, args, {
|
|
191
201
|
env,
|
|
192
202
|
});
|
|
@@ -253,13 +263,6 @@ async function captureCustom(filePath, filesCsv, jsonPath, gqlCapture) {
|
|
|
253
263
|
// TODO delete all of this eventually
|
|
254
264
|
// TODO configurable paths eventually
|
|
255
265
|
// for now only files that are in the include path of the roots are allowed
|
|
256
|
-
const rootFiles = [
|
|
257
|
-
// right now, currently expecting all custom ent stuff to be in the ent object
|
|
258
|
-
// eventually, create a path we check e.g. ent/custom_gql/ ent/graphql?
|
|
259
|
-
// for now can just go in graphql/resolvers/ (not generated)
|
|
260
|
-
path.join(filePath, "ent/index.ts"),
|
|
261
|
-
path.join(filePath, "/graphql/resolvers/index.ts"),
|
|
262
|
-
];
|
|
263
266
|
const ignore = [
|
|
264
267
|
"**/generated/**",
|
|
265
268
|
"**/tests/**",
|
|
@@ -268,35 +271,44 @@ async function captureCustom(filePath, filesCsv, jsonPath, gqlCapture) {
|
|
|
268
271
|
// ignore test files.
|
|
269
272
|
"**/*.test.ts",
|
|
270
273
|
];
|
|
274
|
+
const customGraphQLEntFiles = glob.sync(path.join(filePath, "/ent/**/*.ts"), {
|
|
275
|
+
// not in action files since we can't customize payloads (yet?)
|
|
276
|
+
ignore: [...ignore, "**/actions/**"],
|
|
277
|
+
});
|
|
271
278
|
const customGQLResolvers = glob.sync(path.join(filePath, "/graphql/resolvers/**/*.ts"), {
|
|
272
|
-
// no actions for now to speed things up
|
|
273
|
-
// no index.ts or internal file.
|
|
274
279
|
ignore: ignore,
|
|
275
280
|
});
|
|
276
281
|
const customGQLMutations = glob.sync(path.join(filePath, "/graphql/mutations/**/*.ts"), {
|
|
277
|
-
// no actions for now to speed things up
|
|
278
|
-
// no index.ts or internal file.
|
|
279
282
|
ignore: ignore,
|
|
280
283
|
});
|
|
281
|
-
const files =
|
|
284
|
+
const files = customGraphQLEntFiles
|
|
285
|
+
.concat(customGQLResolvers, customGQLMutations)
|
|
286
|
+
.filter(fileImportsGraphQLDecorators);
|
|
282
287
|
await requireFiles(files);
|
|
283
288
|
}
|
|
289
|
+
function fileImportsGraphQLDecorators(file) {
|
|
290
|
+
const contents = fs.readFileSync(file, {
|
|
291
|
+
encoding: "utf8",
|
|
292
|
+
});
|
|
293
|
+
return /@snowtop\/ent\/graphql(?:\/graphql)?/.test(contents);
|
|
294
|
+
}
|
|
284
295
|
async function requireFiles(files) {
|
|
285
|
-
|
|
286
|
-
if (fs.existsSync(file)) {
|
|
287
|
-
|
|
288
|
-
|
|
296
|
+
for (const file of files) {
|
|
297
|
+
if (!fs.existsSync(file)) {
|
|
298
|
+
throw new Error(`file ${file} doesn't exist`);
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
if (isBunRuntime()) {
|
|
302
|
+
await Promise.resolve(`${(0, url_1.pathToFileURL)(file).href}`).then(s => __importStar(require(s)));
|
|
289
303
|
}
|
|
290
|
-
|
|
291
|
-
|
|
304
|
+
else {
|
|
305
|
+
await require(file);
|
|
292
306
|
}
|
|
293
307
|
}
|
|
294
|
-
|
|
295
|
-
throw new Error(
|
|
308
|
+
catch (e) {
|
|
309
|
+
throw new Error(`${e.message} loading ${file}`);
|
|
296
310
|
}
|
|
297
|
-
}
|
|
298
|
-
throw new Error(err);
|
|
299
|
-
});
|
|
311
|
+
}
|
|
300
312
|
}
|
|
301
313
|
// filePath is path-to-src
|
|
302
314
|
async function parseImports(filePath) {
|
|
@@ -350,9 +362,10 @@ async function main() {
|
|
|
350
362
|
// for local dev, get the one from the file system. otherwise, get the one
|
|
351
363
|
// from node_modules
|
|
352
364
|
let gqlCapture;
|
|
353
|
-
if (process.env.LOCAL_SCRIPT_PATH) {
|
|
365
|
+
if (process.env.LOCAL_SCRIPT_PATH || isBunRuntime()) {
|
|
354
366
|
const r = require("../graphql/graphql");
|
|
355
367
|
gqlCapture = r.GQLCapture;
|
|
368
|
+
gqlCapture.enable(true);
|
|
356
369
|
}
|
|
357
370
|
else {
|
|
358
371
|
const r = require(gqlPath);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function coerceValue(value) {
|
|
3
|
+
if (value === "true") {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
if (value === "false") {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function normalizeKey(key) {
|
|
12
|
+
return key.replace(/-/g, "_");
|
|
13
|
+
}
|
|
14
|
+
function setOption(result, key, value) {
|
|
15
|
+
result[key] = value;
|
|
16
|
+
const normalized = normalizeKey(key);
|
|
17
|
+
if (normalized !== key) {
|
|
18
|
+
result[normalized] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function parseArgs(argv) {
|
|
22
|
+
const result = { _: [] };
|
|
23
|
+
const args = argv || process.argv.slice(2);
|
|
24
|
+
for (let i = 0; i < args.length; i++) {
|
|
25
|
+
const arg = args[i];
|
|
26
|
+
if (arg === "--") {
|
|
27
|
+
result._.push(...args.slice(i + 1));
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
if (!arg.startsWith("-") || arg === "-") {
|
|
31
|
+
result._.push(arg);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (arg.startsWith("--no-")) {
|
|
35
|
+
setOption(result, normalizeKey(arg.slice(5)), false);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (arg.startsWith("--")) {
|
|
39
|
+
const body = arg.slice(2);
|
|
40
|
+
const idx = body.indexOf("=");
|
|
41
|
+
if (idx !== -1) {
|
|
42
|
+
setOption(result, normalizeKey(body.slice(0, idx)), coerceValue(body.slice(idx + 1)));
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const key = normalizeKey(body);
|
|
46
|
+
const next = args[i + 1];
|
|
47
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
48
|
+
setOption(result, key, coerceValue(next));
|
|
49
|
+
i++;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
setOption(result, key, true);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const shorts = arg.slice(1);
|
|
57
|
+
if (shorts.length === 1) {
|
|
58
|
+
const next = args[i + 1];
|
|
59
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
60
|
+
setOption(result, shorts, coerceValue(next));
|
|
61
|
+
i++;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setOption(result, shorts, true);
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const ch of shorts) {
|
|
69
|
+
setOption(result, ch, true);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
module.exports = { parseArgs };
|
|
@@ -2,11 +2,17 @@ import { Express, RequestHandler } from "express";
|
|
|
2
2
|
import { GraphQLSchema } from "graphql";
|
|
3
3
|
import supertest from "supertest";
|
|
4
4
|
import { Viewer } from "../../core/base";
|
|
5
|
+
export declare function cleanupBunGraphQLTestAgent(agent: any): Promise<void>;
|
|
6
|
+
type BunTestTarget = {
|
|
7
|
+
app: Express;
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
5
10
|
export type Option = [string, any] | [string, any, string];
|
|
6
11
|
interface queryConfig {
|
|
7
12
|
viewer?: Viewer;
|
|
8
13
|
init?: (app: Express) => void;
|
|
9
14
|
test?: supertest.Agent | ((express: Express) => supertest.Agent);
|
|
15
|
+
bunTest?: (target: BunTestTarget) => supertest.Agent;
|
|
10
16
|
schema: GraphQLSchema;
|
|
11
17
|
headers?: object;
|
|
12
18
|
debugMode?: boolean;
|
|
@@ -1,52 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.cleanupBunGraphQLTestAgent = cleanupBunGraphQLTestAgent;
|
|
39
7
|
exports.expectQueryFromRoot = expectQueryFromRoot;
|
|
40
8
|
exports.expectMutation = expectMutation;
|
|
41
9
|
// NB: this is copied from ent-graphql-tests package until I have time to figure out how to share code here effectively
|
|
42
10
|
// the circular dependencies btw this package and ent-graphql-tests seems to imply something needs to change
|
|
43
11
|
const express_1 = __importDefault(require("express"));
|
|
44
|
-
const fs = __importStar(require("fs"));
|
|
45
|
-
const graphql_1 = require("graphql");
|
|
46
12
|
const graphql_helix_1 = require("graphql-helix");
|
|
47
13
|
const supertest_1 = __importDefault(require("supertest"));
|
|
48
14
|
const util_1 = require("util");
|
|
49
15
|
const auth_1 = require("../../auth");
|
|
16
|
+
const bunAgentServerClose = Symbol("bunAgentServerClose");
|
|
17
|
+
const bunAgentServerCleanups = new Set();
|
|
18
|
+
let bunAgentServerCleanupRegistered = false;
|
|
19
|
+
function registerBunAgentServerCleanup(cleanup) {
|
|
20
|
+
let cleanupPromise;
|
|
21
|
+
const cleanupOnce = () => {
|
|
22
|
+
cleanupPromise = cleanupPromise || cleanup();
|
|
23
|
+
return cleanupPromise;
|
|
24
|
+
};
|
|
25
|
+
bunAgentServerCleanups.add(cleanupOnce);
|
|
26
|
+
const afterAllFn = globalThis
|
|
27
|
+
.afterAll;
|
|
28
|
+
if (!bunAgentServerCleanupRegistered && typeof afterAllFn === "function") {
|
|
29
|
+
bunAgentServerCleanupRegistered = true;
|
|
30
|
+
afterAllFn(async () => {
|
|
31
|
+
const cleanups = [...bunAgentServerCleanups];
|
|
32
|
+
bunAgentServerCleanups.clear();
|
|
33
|
+
await Promise.all(cleanups.map((cleanup) => cleanup()));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return cleanupOnce;
|
|
37
|
+
}
|
|
38
|
+
async function cleanupBunGraphQLTestAgent(agent) {
|
|
39
|
+
const cleanup = agent?.[bunAgentServerClose];
|
|
40
|
+
if (cleanup) {
|
|
41
|
+
await cleanup();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
50
44
|
function server(config) {
|
|
51
45
|
const viewer = config.viewer;
|
|
52
46
|
if (viewer) {
|
|
@@ -83,25 +77,113 @@ function server(config) {
|
|
|
83
77
|
app.use(config.graphQLPath || "/graphql", ...handlers);
|
|
84
78
|
return app;
|
|
85
79
|
}
|
|
80
|
+
// Bun can load GraphQL types from a different module realm than the schema under test,
|
|
81
|
+
// so constructor identity checks are not reliable here.
|
|
82
|
+
function isWrappingTypeLike(typ) {
|
|
83
|
+
return !!typ && typeof typ === "object" && "ofType" in typ;
|
|
84
|
+
}
|
|
85
|
+
function isListTypeLike(typ) {
|
|
86
|
+
return (isWrappingTypeLike(typ) &&
|
|
87
|
+
(typ.constructor?.name === "GraphQLList" || /^\[.*\]$/.test(String(typ))));
|
|
88
|
+
}
|
|
89
|
+
function isObjectTypeLike(typ) {
|
|
90
|
+
return (!!typ && typeof typ === "object" && typeof typ.getFields === "function");
|
|
91
|
+
}
|
|
92
|
+
function isScalarTypeLike(typ) {
|
|
93
|
+
return (!!typ &&
|
|
94
|
+
typeof typ === "object" &&
|
|
95
|
+
typeof typ.serialize === "function" &&
|
|
96
|
+
typeof typ.parseValue === "function" &&
|
|
97
|
+
typeof typ.parseLiteral === "function");
|
|
98
|
+
}
|
|
99
|
+
function isEnumTypeLike(typ) {
|
|
100
|
+
return (!!typ &&
|
|
101
|
+
typeof typ === "object" &&
|
|
102
|
+
typeof typ.getValues === "function" &&
|
|
103
|
+
typeof typ.toConfig === "function");
|
|
104
|
+
}
|
|
86
105
|
function getInnerType(typ, list) {
|
|
87
|
-
if ((
|
|
88
|
-
if (typ
|
|
106
|
+
if (isWrappingTypeLike(typ)) {
|
|
107
|
+
if (isListTypeLike(typ)) {
|
|
89
108
|
return getInnerType(typ.ofType, true);
|
|
90
109
|
}
|
|
91
110
|
return getInnerType(typ.ofType, list);
|
|
92
111
|
}
|
|
93
112
|
return [typ, list];
|
|
94
113
|
}
|
|
95
|
-
function
|
|
114
|
+
async function createBunTestHarness(config, persistentAgent, testFactory) {
|
|
115
|
+
const app = config.server ? config.server : server(config);
|
|
116
|
+
const httpServer = await new Promise((resolve) => {
|
|
117
|
+
const srv = app.listen(0, () => resolve(srv));
|
|
118
|
+
});
|
|
119
|
+
const address = httpServer.address();
|
|
120
|
+
if (!address || typeof address === "string") {
|
|
121
|
+
throw new Error("could not determine test server address");
|
|
122
|
+
}
|
|
123
|
+
const url = `http://127.0.0.1:${address.port}`;
|
|
124
|
+
let closePromise;
|
|
125
|
+
const close = () => {
|
|
126
|
+
closePromise =
|
|
127
|
+
closePromise ||
|
|
128
|
+
new Promise((resolve, reject) => {
|
|
129
|
+
httpServer.close((err) => (err ? reject(err) : resolve()));
|
|
130
|
+
});
|
|
131
|
+
return closePromise;
|
|
132
|
+
};
|
|
133
|
+
if (persistentAgent) {
|
|
134
|
+
try {
|
|
135
|
+
let agent;
|
|
136
|
+
// Keep the existing Express app factory contract. If bunTest is present,
|
|
137
|
+
// it owns the URL-backed agent and testFactory still runs against the app.
|
|
138
|
+
const factoryAgent = testFactory?.(app);
|
|
139
|
+
if (config.bunTest) {
|
|
140
|
+
agent = config.bunTest({ app, url });
|
|
141
|
+
}
|
|
142
|
+
else if (factoryAgent) {
|
|
143
|
+
agent = factoryAgent;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
agent = supertest_1.default.agent(url);
|
|
147
|
+
}
|
|
148
|
+
agent[bunAgentServerClose] = registerBunAgentServerCleanup(close);
|
|
149
|
+
return { agent };
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
await close();
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
agent: (0, supertest_1.default)(url),
|
|
158
|
+
cleanup: close,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async function makeGraphQLRequest(config, query, fieldArgs) {
|
|
96
162
|
let agent;
|
|
163
|
+
let cleanup;
|
|
97
164
|
if (config.test) {
|
|
98
165
|
if (typeof config.test === "function") {
|
|
99
|
-
|
|
166
|
+
if (process.versions.bun) {
|
|
167
|
+
({ agent } = await createBunTestHarness(config, true, config.test));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const factoryAgent = config.test(config.server ? config.server : server(config));
|
|
171
|
+
if (!factoryAgent) {
|
|
172
|
+
throw new Error("config.test must return a supertest agent");
|
|
173
|
+
}
|
|
174
|
+
agent = factoryAgent;
|
|
175
|
+
}
|
|
100
176
|
}
|
|
101
177
|
else {
|
|
102
178
|
agent = config.test;
|
|
103
179
|
}
|
|
104
180
|
}
|
|
181
|
+
else if (process.versions.bun && config.bunTest) {
|
|
182
|
+
({ agent } = await createBunTestHarness(config, true));
|
|
183
|
+
}
|
|
184
|
+
else if (process.versions.bun) {
|
|
185
|
+
({ agent, cleanup } = await createBunTestHarness(config, false));
|
|
186
|
+
}
|
|
105
187
|
else {
|
|
106
188
|
agent = (0, supertest_1.default)(config.server ? config.server : server(config));
|
|
107
189
|
}
|
|
@@ -109,7 +191,7 @@ function makeGraphQLRequest(config, query, fieldArgs) {
|
|
|
109
191
|
// handle files
|
|
110
192
|
fieldArgs.forEach((fieldArg) => {
|
|
111
193
|
let [typ, list] = getInnerType(fieldArg.type, false);
|
|
112
|
-
if (typ
|
|
194
|
+
if (isScalarTypeLike(typ) && typ.name == "Upload") {
|
|
113
195
|
let value = config.args[fieldArg.name];
|
|
114
196
|
if (list) {
|
|
115
197
|
expect(Array.isArray(value)).toBe(true);
|
|
@@ -150,31 +232,29 @@ function makeGraphQLRequest(config, query, fieldArgs) {
|
|
|
150
232
|
ret.field("map", JSON.stringify(m));
|
|
151
233
|
idx = 0;
|
|
152
234
|
for (let [key, val] of files) {
|
|
153
|
-
if (typeof val === "string") {
|
|
154
|
-
val = fs.createReadStream(val);
|
|
155
|
-
}
|
|
156
235
|
ret.attach(`${idx}`, val, key);
|
|
157
236
|
idx++;
|
|
158
237
|
}
|
|
159
|
-
return
|
|
238
|
+
return { agent, request: ret, cleanup };
|
|
160
239
|
}
|
|
161
240
|
else {
|
|
162
|
-
return
|
|
241
|
+
return {
|
|
163
242
|
agent,
|
|
164
|
-
agent
|
|
243
|
+
request: agent
|
|
165
244
|
.post(config.graphQLPath || "/graphql")
|
|
166
245
|
.set((config.headers || {}))
|
|
167
246
|
.send({
|
|
168
247
|
query: query,
|
|
169
|
-
variables
|
|
248
|
+
variables,
|
|
170
249
|
}),
|
|
171
|
-
|
|
250
|
+
cleanup,
|
|
251
|
+
};
|
|
172
252
|
}
|
|
173
253
|
}
|
|
174
254
|
function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
175
255
|
let fields;
|
|
176
256
|
const [typ] = getInnerType(fieldType, false);
|
|
177
|
-
if (typ
|
|
257
|
+
if (isObjectTypeLike(typ)) {
|
|
178
258
|
fields = typ.getFields();
|
|
179
259
|
}
|
|
180
260
|
let topLevelTree = {};
|
|
@@ -189,7 +269,7 @@ function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
|
189
269
|
if (!typ) {
|
|
190
270
|
throw new Error(`can't find type for ${match[1]} in schema`);
|
|
191
271
|
}
|
|
192
|
-
if (typ
|
|
272
|
+
if (isObjectTypeLike(typ)) {
|
|
193
273
|
fields = typ.getFields();
|
|
194
274
|
}
|
|
195
275
|
}
|
|
@@ -243,7 +323,7 @@ function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
|
243
323
|
subField = root?.[p];
|
|
244
324
|
if (subField) {
|
|
245
325
|
[subField] = getInnerType(subField.type, false);
|
|
246
|
-
if (subField
|
|
326
|
+
if (isObjectTypeLike(subField)) {
|
|
247
327
|
root = subField.getFields();
|
|
248
328
|
}
|
|
249
329
|
}
|
|
@@ -251,7 +331,7 @@ function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
|
251
331
|
if (!subField) {
|
|
252
332
|
return false;
|
|
253
333
|
}
|
|
254
|
-
return (
|
|
334
|
+
return isScalarTypeLike(subField) || isEnumTypeLike(subField);
|
|
255
335
|
}
|
|
256
336
|
if (i === parts.length - 1 && typeof option[1] === "object") {
|
|
257
337
|
if (!scalarFieldAtLeaf(parts)) {
|
|
@@ -382,8 +462,16 @@ async function expectFromRoot(config, ...options) {
|
|
|
382
462
|
if (config.debugMode) {
|
|
383
463
|
console.log(q);
|
|
384
464
|
}
|
|
385
|
-
|
|
386
|
-
|
|
465
|
+
const { agent: st, request, cleanup, } = await makeGraphQLRequest(config, q, fieldArgs);
|
|
466
|
+
let res;
|
|
467
|
+
try {
|
|
468
|
+
res = await request.expect("Content-Type", /json/);
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
if (cleanup) {
|
|
472
|
+
await cleanup();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
387
475
|
if (config.debugMode) {
|
|
388
476
|
console.log((0, util_1.inspect)(res.body, false, 3));
|
|
389
477
|
}
|