graphql-jerky 1.0.0 → 1.0.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.
- package/build/bin/jerky.mjs +1 -0
- package/build/lib.cjs +84 -39
- package/build/lib.d.ts +5 -3
- package/build/lib.mjs +84 -39
- package/package.json +3 -1
package/build/bin/jerky.mjs
CHANGED
package/build/lib.cjs
CHANGED
|
@@ -10,6 +10,7 @@ var url = require('url');
|
|
|
10
10
|
var fs = require('fs/promises');
|
|
11
11
|
var ts = require('typescript');
|
|
12
12
|
var glob = require('glob');
|
|
13
|
+
var pm = require('picomatch');
|
|
13
14
|
var zip = require('just-zip-it');
|
|
14
15
|
|
|
15
16
|
async function parseSource(filepath) {
|
|
@@ -363,38 +364,41 @@ class GeneratorContext {
|
|
|
363
364
|
_renderArgumentNodes(nodes) {
|
|
364
365
|
return jen.obj(...Array.from(nodes ?? [], (arg) => jen.prop(arg.name.value, this._renderValueNode(arg.value))));
|
|
365
366
|
}
|
|
366
|
-
_renderFieldObject(type, f, inputFieldDirectives) {
|
|
367
|
-
let
|
|
368
|
-
if (
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
367
|
+
_renderFieldObject(type, f, inputFieldDirectives, noresolver) {
|
|
368
|
+
let resolveFn;
|
|
369
|
+
if (!noresolver) {
|
|
370
|
+
let resolver = this._resolversInfo[type.name]?.[f.name];
|
|
371
|
+
if (type instanceof graphql.GraphQLObjectType && !resolver) {
|
|
372
|
+
// try to find resolver in interface in the declaration order
|
|
373
|
+
for (const iface of type.getInterfaces()) {
|
|
374
|
+
if ((resolver = this._resolversInfo[iface.name]?.[f.name])) {
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
373
377
|
}
|
|
374
378
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
379
|
+
resolveFn = resolver && renderSymbolReference(this._pkgs, resolver);
|
|
380
|
+
if (f.astNode?.directives?.length) {
|
|
381
|
+
// apply directives in reverse order
|
|
382
|
+
for (const directive of Array.from(f.astNode.directives).reverse()) {
|
|
383
|
+
const ref = this._fieldDirectivesInfo[directive.name.value];
|
|
384
|
+
if (!ref) {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
if (!resolveFn) {
|
|
388
|
+
resolveFn = jen.arrow(jen.id("source").op(":").any).id("source").dot(f.name);
|
|
389
|
+
}
|
|
390
|
+
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length ? [this._renderArgumentNodes(directive.arguments)] : []));
|
|
386
391
|
}
|
|
387
|
-
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length ? [this._renderArgumentNodes(directive.arguments)] : []));
|
|
388
392
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
393
|
+
if (resolveFn) {
|
|
394
|
+
// args probably don't need to be transformed if there's no resolver
|
|
395
|
+
const argsWithDirectives = truthify(f.args?.map((arg) => this._findInputDirectiveInfoFromArgOrField(arg, inputFieldDirectives)) ?? []);
|
|
396
|
+
if (argsWithDirectives.length) {
|
|
397
|
+
resolveFn = jen.parens(jen.params(jen.prop("next", this._gql("GraphQLFieldResolver").types(jen.any, jen.any))).op(":")
|
|
398
|
+
.add(this._gql("GraphQLFieldResolver"))
|
|
399
|
+
.types(jen.any, jen.any, jen.id(type.name).dot(pascalCase(f.name + "_args")))
|
|
400
|
+
.op("=>").arrow(jen.id("source"), jen.id("args"), jen.id("context"), jen.id("info")).id("next").call(jen.id("source"), this._renderInputFieldsWithDirectives(jen.id("args"), argsWithDirectives, argsWithDirectives.length < f.args.length), jen.id("context"), jen.id("info"))).call(resolveFn);
|
|
401
|
+
}
|
|
398
402
|
}
|
|
399
403
|
}
|
|
400
404
|
// NOTE: The way subscribers work in the graphql-js is by calling `subscribe` on the top level fields, and then
|
|
@@ -416,13 +420,13 @@ class GeneratorContext {
|
|
|
416
420
|
// NOTE: Resolver functions on interface definitions are not used by the default graphql-js
|
|
417
421
|
// executor implementation, but nonetheless accessible by a potential alternate implementation.
|
|
418
422
|
resolveFn && jen.prop("resolve", jen.parens(resolveFn).as.any),
|
|
419
|
-
subscriber && jen.prop("subscribe", renderSymbolReference(this._pkgs, subscriber)),
|
|
423
|
+
subscriber && jen.prop("subscribe", jen.parens(renderSymbolReference(this._pkgs, subscriber)).as.any),
|
|
420
424
|
]));
|
|
421
425
|
}
|
|
422
|
-
_renderFieldsThunk(type, inputFieldDirectives) {
|
|
426
|
+
_renderFieldsThunk(type, inputFieldDirectives, noresolver) {
|
|
423
427
|
return jen.arrow().parens(jen.obj(...Object.values(type.getFields())
|
|
424
428
|
.sort(compareName)
|
|
425
|
-
.map((field) => jen.prop(field.name, this._renderFieldObject(type, field, inputFieldDirectives)))));
|
|
429
|
+
.map((field) => jen.prop(field.name, this._renderFieldObject(type, field, inputFieldDirectives, noresolver)))));
|
|
426
430
|
}
|
|
427
431
|
_renderOptionalGraphQLTypeType(type) {
|
|
428
432
|
if (type instanceof graphql.GraphQLNonNull) {
|
|
@@ -498,7 +502,7 @@ class GeneratorContext {
|
|
|
498
502
|
}
|
|
499
503
|
_renderGraphQLObjectTypeDefinition(type, { inputFieldDirectives }) {
|
|
500
504
|
const typeInterfaces = type.getInterfaces();
|
|
501
|
-
return jen.new.add(this._gql("GraphQLObjectType")).call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives)), ...truthify([
|
|
505
|
+
return jen.new.add(this._gql("GraphQLObjectType")).call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, type.name === "Subscription")), ...truthify([
|
|
502
506
|
type.description && jen.prop("description", jen.lit(type.description)),
|
|
503
507
|
typeInterfaces.length && jen.prop("interfaces", jen.arrow().arr(
|
|
504
508
|
// do not sort interfaces, the declaration order may be important
|
|
@@ -623,7 +627,7 @@ class GeneratorContext {
|
|
|
623
627
|
}));
|
|
624
628
|
}
|
|
625
629
|
_renderGraphQLInputObjectTypeDefinition(type, { inputFieldDirectives }) {
|
|
626
|
-
return jen.new.add(this._gql("GraphQLInputObjectType")).call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives)), ...truthify([
|
|
630
|
+
return jen.new.add(this._gql("GraphQLInputObjectType")).call(jen.obj(jen.prop("name", jen.lit(type.name)), jen.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, true)), ...truthify([
|
|
627
631
|
type.description && jen.prop("description", jen.lit(type.description)),
|
|
628
632
|
])));
|
|
629
633
|
}
|
|
@@ -877,6 +881,41 @@ function generate(schema, outfile, options = {}) {
|
|
|
877
881
|
return createGenerator(schema, options).generate(outfile);
|
|
878
882
|
}
|
|
879
883
|
|
|
884
|
+
function createMatcher(pattern) {
|
|
885
|
+
if (!pattern) {
|
|
886
|
+
return () => false;
|
|
887
|
+
}
|
|
888
|
+
if (typeof pattern === "function") {
|
|
889
|
+
return pattern;
|
|
890
|
+
}
|
|
891
|
+
if (pattern instanceof RegExp) {
|
|
892
|
+
return (s) => pattern.test(s);
|
|
893
|
+
}
|
|
894
|
+
if (typeof pattern === "string") {
|
|
895
|
+
return pm(pattern);
|
|
896
|
+
}
|
|
897
|
+
let matchers = [];
|
|
898
|
+
let globs = [];
|
|
899
|
+
for (const p of Array.isArray(pattern) ? pattern : [pattern]) {
|
|
900
|
+
if (typeof p === "string") {
|
|
901
|
+
globs.push(p);
|
|
902
|
+
}
|
|
903
|
+
else if (typeof p === "function") {
|
|
904
|
+
matchers.push(p);
|
|
905
|
+
}
|
|
906
|
+
else if (p instanceof RegExp) {
|
|
907
|
+
matchers.push(RegExp.prototype.test.bind(p));
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
throw new TypeError(`Invalid pattern: ${p}`);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
if (globs.length) {
|
|
914
|
+
matchers.push(pm(globs));
|
|
915
|
+
}
|
|
916
|
+
return (s) => matchers.some((m) => m(s));
|
|
917
|
+
}
|
|
918
|
+
|
|
880
919
|
async function parseResolverFile(path) {
|
|
881
920
|
return Object.fromEntries(Object.entries((await parseModule(path)).exports)
|
|
882
921
|
.flatMap(([name, { declaration }]) => {
|
|
@@ -894,11 +933,12 @@ async function parseResolverFile(path) {
|
|
|
894
933
|
return [];
|
|
895
934
|
}));
|
|
896
935
|
}
|
|
897
|
-
async function parseTypeResolvers(typeName, glob$1) {
|
|
936
|
+
async function parseTypeResolvers(typeName, glob$1, ignore) {
|
|
937
|
+
const shouldIgnore = createMatcher(ignore);
|
|
898
938
|
const result = {};
|
|
899
939
|
for await (const entry of glob.globIterate(glob$1, { withFileTypes: true })) {
|
|
900
940
|
const fullpath = entry.fullpath();
|
|
901
|
-
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
941
|
+
if (!shouldIgnore(fullpath) && entry.isFile() && entry.name.endsWith(".ts")) {
|
|
902
942
|
for (const [name, reference] of Object.entries(await parseResolverFile(fullpath))) {
|
|
903
943
|
let realName = name;
|
|
904
944
|
if (realName === "default") {
|
|
@@ -913,7 +953,7 @@ async function parseTypeResolvers(typeName, glob$1) {
|
|
|
913
953
|
}
|
|
914
954
|
return result;
|
|
915
955
|
}
|
|
916
|
-
async function parse$2(dirpath) {
|
|
956
|
+
async function parse$2(dirpath, ignore) {
|
|
917
957
|
const dir = await fs.stat(dirpath);
|
|
918
958
|
if (!dir.isDirectory()) {
|
|
919
959
|
throw new Error(`Expected ${dirpath} to be a directory`);
|
|
@@ -922,14 +962,15 @@ async function parse$2(dirpath) {
|
|
|
922
962
|
dirpath += "/";
|
|
923
963
|
}
|
|
924
964
|
const out = {};
|
|
965
|
+
const shouldIgnore = createMatcher(ignore);
|
|
925
966
|
for await (const name of await fs.readdir(dirpath)) {
|
|
926
967
|
const file = path.join(dirpath, name);
|
|
927
968
|
const entry = await fs.stat(file);
|
|
928
969
|
if (entry.isDirectory()) {
|
|
929
|
-
out[name] = await parseTypeResolvers(name, file + "/*.ts");
|
|
970
|
+
out[name] = await parseTypeResolvers(name, file + "/*.ts", shouldIgnore);
|
|
930
971
|
}
|
|
931
972
|
else if (entry.isFile() && name.endsWith(".ts")) {
|
|
932
|
-
out[name.slice(0, -3)] = await parseTypeResolvers(name.slice(0, -3), file);
|
|
973
|
+
out[name.slice(0, -3)] = await parseTypeResolvers(name.slice(0, -3), file, shouldIgnore);
|
|
933
974
|
}
|
|
934
975
|
}
|
|
935
976
|
return out;
|
|
@@ -1514,9 +1555,13 @@ async function* findSchemaFiles(glob$1) {
|
|
|
1514
1555
|
}
|
|
1515
1556
|
}
|
|
1516
1557
|
}
|
|
1517
|
-
async function parse(glob) {
|
|
1558
|
+
async function parse(glob, ignore) {
|
|
1559
|
+
const shouldIgnore = createMatcher(ignore);
|
|
1518
1560
|
const documentNodes = [];
|
|
1519
1561
|
for await (const entry of findSchemaFiles(glob)) {
|
|
1562
|
+
if (shouldIgnore(entry)) {
|
|
1563
|
+
continue;
|
|
1564
|
+
}
|
|
1520
1565
|
documentNodes.push(graphql.parse(new graphql.Source(await fs.readFile(entry, "utf-8"), entry)));
|
|
1521
1566
|
}
|
|
1522
1567
|
if (!documentNodes.length) {
|
package/build/lib.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import { GraphQLSchema } from 'graphql';
|
|
3
3
|
|
|
4
|
+
type MatchPattern = string | RegExp | ((s: string) => boolean) | Array<string | RegExp | ((s: string) => boolean)>;
|
|
5
|
+
|
|
4
6
|
interface SymbolReference {
|
|
5
7
|
module?: string;
|
|
6
8
|
symbol: string;
|
|
@@ -8,8 +10,8 @@ interface SymbolReference {
|
|
|
8
10
|
property?: string;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
declare function parseTypeResolvers(typeName: string, glob: string | string[]): Promise<Record<string, SymbolReference>>;
|
|
12
|
-
declare function parse$2(dirpath: string): Promise<Record<string, Record<string, SymbolReference>>>;
|
|
13
|
+
declare function parseTypeResolvers(typeName: string, glob: string | string[], ignore?: MatchPattern): Promise<Record<string, SymbolReference>>;
|
|
14
|
+
declare function parse$2(dirpath: string, ignore?: MatchPattern): Promise<Record<string, Record<string, SymbolReference>>>;
|
|
13
15
|
|
|
14
16
|
type FunctionDeclaration = ts.MethodDeclaration | ts.FunctionExpression | ts.ArrowFunction;
|
|
15
17
|
interface ScalarFnsInfo {
|
|
@@ -46,6 +48,6 @@ declare function generateSchema(schema: GraphQLSchema, outfile: string, options?
|
|
|
46
48
|
declare function generateTypes(schema: GraphQLSchema, outfile: string, options?: GenerateOptions): string;
|
|
47
49
|
declare function generate(schema: GraphQLSchema, outfile: string, options?: GenerateOptions): string;
|
|
48
50
|
|
|
49
|
-
declare function parse(glob: string | string[]): Promise<GraphQLSchema>;
|
|
51
|
+
declare function parse(glob: string | string[], ignore?: MatchPattern): Promise<GraphQLSchema>;
|
|
50
52
|
|
|
51
53
|
export { createGenerator, generate, generateSchema, generateTypes, parse$2 as parseResolvers, parse$1 as parseScalars, parse as parseSchema, parseTypeResolvers };
|
package/build/lib.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { pathToFileURL, fileURLToPath } from 'url';
|
|
|
8
8
|
import fs from 'fs/promises';
|
|
9
9
|
import ts, { getLineAndCharacterOfPosition } from 'typescript';
|
|
10
10
|
import { globIterate } from 'glob';
|
|
11
|
+
import pm from 'picomatch';
|
|
11
12
|
import zip from 'just-zip-it';
|
|
12
13
|
|
|
13
14
|
async function parseSource(filepath) {
|
|
@@ -361,38 +362,41 @@ class GeneratorContext {
|
|
|
361
362
|
_renderArgumentNodes(nodes) {
|
|
362
363
|
return jen$1.obj(...Array.from(nodes ?? [], (arg) => jen$1.prop(arg.name.value, this._renderValueNode(arg.value))));
|
|
363
364
|
}
|
|
364
|
-
_renderFieldObject(type, f, inputFieldDirectives) {
|
|
365
|
-
let
|
|
366
|
-
if (
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
365
|
+
_renderFieldObject(type, f, inputFieldDirectives, noresolver) {
|
|
366
|
+
let resolveFn;
|
|
367
|
+
if (!noresolver) {
|
|
368
|
+
let resolver = this._resolversInfo[type.name]?.[f.name];
|
|
369
|
+
if (type instanceof GraphQLObjectType && !resolver) {
|
|
370
|
+
// try to find resolver in interface in the declaration order
|
|
371
|
+
for (const iface of type.getInterfaces()) {
|
|
372
|
+
if ((resolver = this._resolversInfo[iface.name]?.[f.name])) {
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
371
375
|
}
|
|
372
376
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
377
|
+
resolveFn = resolver && renderSymbolReference(this._pkgs, resolver);
|
|
378
|
+
if (f.astNode?.directives?.length) {
|
|
379
|
+
// apply directives in reverse order
|
|
380
|
+
for (const directive of Array.from(f.astNode.directives).reverse()) {
|
|
381
|
+
const ref = this._fieldDirectivesInfo[directive.name.value];
|
|
382
|
+
if (!ref) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (!resolveFn) {
|
|
386
|
+
resolveFn = jen$1.arrow(jen$1.id("source").op(":").any).id("source").dot(f.name);
|
|
387
|
+
}
|
|
388
|
+
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length ? [this._renderArgumentNodes(directive.arguments)] : []));
|
|
384
389
|
}
|
|
385
|
-
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length ? [this._renderArgumentNodes(directive.arguments)] : []));
|
|
386
390
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
391
|
+
if (resolveFn) {
|
|
392
|
+
// args probably don't need to be transformed if there's no resolver
|
|
393
|
+
const argsWithDirectives = truthify(f.args?.map((arg) => this._findInputDirectiveInfoFromArgOrField(arg, inputFieldDirectives)) ?? []);
|
|
394
|
+
if (argsWithDirectives.length) {
|
|
395
|
+
resolveFn = jen$1.parens(jen$1.params(jen$1.prop("next", this._gql("GraphQLFieldResolver").types(jen$1.any, jen$1.any))).op(":")
|
|
396
|
+
.add(this._gql("GraphQLFieldResolver"))
|
|
397
|
+
.types(jen$1.any, jen$1.any, jen$1.id(type.name).dot(pascalCase(f.name + "_args")))
|
|
398
|
+
.op("=>").arrow(jen$1.id("source"), jen$1.id("args"), jen$1.id("context"), jen$1.id("info")).id("next").call(jen$1.id("source"), this._renderInputFieldsWithDirectives(jen$1.id("args"), argsWithDirectives, argsWithDirectives.length < f.args.length), jen$1.id("context"), jen$1.id("info"))).call(resolveFn);
|
|
399
|
+
}
|
|
396
400
|
}
|
|
397
401
|
}
|
|
398
402
|
// NOTE: The way subscribers work in the graphql-js is by calling `subscribe` on the top level fields, and then
|
|
@@ -414,13 +418,13 @@ class GeneratorContext {
|
|
|
414
418
|
// NOTE: Resolver functions on interface definitions are not used by the default graphql-js
|
|
415
419
|
// executor implementation, but nonetheless accessible by a potential alternate implementation.
|
|
416
420
|
resolveFn && jen$1.prop("resolve", jen$1.parens(resolveFn).as.any),
|
|
417
|
-
subscriber && jen$1.prop("subscribe", renderSymbolReference(this._pkgs, subscriber)),
|
|
421
|
+
subscriber && jen$1.prop("subscribe", jen$1.parens(renderSymbolReference(this._pkgs, subscriber)).as.any),
|
|
418
422
|
]));
|
|
419
423
|
}
|
|
420
|
-
_renderFieldsThunk(type, inputFieldDirectives) {
|
|
424
|
+
_renderFieldsThunk(type, inputFieldDirectives, noresolver) {
|
|
421
425
|
return jen$1.arrow().parens(jen$1.obj(...Object.values(type.getFields())
|
|
422
426
|
.sort(compareName)
|
|
423
|
-
.map((field) => jen$1.prop(field.name, this._renderFieldObject(type, field, inputFieldDirectives)))));
|
|
427
|
+
.map((field) => jen$1.prop(field.name, this._renderFieldObject(type, field, inputFieldDirectives, noresolver)))));
|
|
424
428
|
}
|
|
425
429
|
_renderOptionalGraphQLTypeType(type) {
|
|
426
430
|
if (type instanceof GraphQLNonNull) {
|
|
@@ -496,7 +500,7 @@ class GeneratorContext {
|
|
|
496
500
|
}
|
|
497
501
|
_renderGraphQLObjectTypeDefinition(type, { inputFieldDirectives }) {
|
|
498
502
|
const typeInterfaces = type.getInterfaces();
|
|
499
|
-
return jen$1.new.add(this._gql("GraphQLObjectType")).call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives)), ...truthify([
|
|
503
|
+
return jen$1.new.add(this._gql("GraphQLObjectType")).call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, type.name === "Subscription")), ...truthify([
|
|
500
504
|
type.description && jen$1.prop("description", jen$1.lit(type.description)),
|
|
501
505
|
typeInterfaces.length && jen$1.prop("interfaces", jen$1.arrow().arr(
|
|
502
506
|
// do not sort interfaces, the declaration order may be important
|
|
@@ -621,7 +625,7 @@ class GeneratorContext {
|
|
|
621
625
|
}));
|
|
622
626
|
}
|
|
623
627
|
_renderGraphQLInputObjectTypeDefinition(type, { inputFieldDirectives }) {
|
|
624
|
-
return jen$1.new.add(this._gql("GraphQLInputObjectType")).call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives)), ...truthify([
|
|
628
|
+
return jen$1.new.add(this._gql("GraphQLInputObjectType")).call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, true)), ...truthify([
|
|
625
629
|
type.description && jen$1.prop("description", jen$1.lit(type.description)),
|
|
626
630
|
])));
|
|
627
631
|
}
|
|
@@ -875,6 +879,41 @@ function generate(schema, outfile, options = {}) {
|
|
|
875
879
|
return createGenerator(schema, options).generate(outfile);
|
|
876
880
|
}
|
|
877
881
|
|
|
882
|
+
function createMatcher(pattern) {
|
|
883
|
+
if (!pattern) {
|
|
884
|
+
return () => false;
|
|
885
|
+
}
|
|
886
|
+
if (typeof pattern === "function") {
|
|
887
|
+
return pattern;
|
|
888
|
+
}
|
|
889
|
+
if (pattern instanceof RegExp) {
|
|
890
|
+
return (s) => pattern.test(s);
|
|
891
|
+
}
|
|
892
|
+
if (typeof pattern === "string") {
|
|
893
|
+
return pm(pattern);
|
|
894
|
+
}
|
|
895
|
+
let matchers = [];
|
|
896
|
+
let globs = [];
|
|
897
|
+
for (const p of Array.isArray(pattern) ? pattern : [pattern]) {
|
|
898
|
+
if (typeof p === "string") {
|
|
899
|
+
globs.push(p);
|
|
900
|
+
}
|
|
901
|
+
else if (typeof p === "function") {
|
|
902
|
+
matchers.push(p);
|
|
903
|
+
}
|
|
904
|
+
else if (p instanceof RegExp) {
|
|
905
|
+
matchers.push(RegExp.prototype.test.bind(p));
|
|
906
|
+
}
|
|
907
|
+
else {
|
|
908
|
+
throw new TypeError(`Invalid pattern: ${p}`);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
if (globs.length) {
|
|
912
|
+
matchers.push(pm(globs));
|
|
913
|
+
}
|
|
914
|
+
return (s) => matchers.some((m) => m(s));
|
|
915
|
+
}
|
|
916
|
+
|
|
878
917
|
async function parseResolverFile(path) {
|
|
879
918
|
return Object.fromEntries(Object.entries((await parseModule(path)).exports)
|
|
880
919
|
.flatMap(([name, { declaration }]) => {
|
|
@@ -892,11 +931,12 @@ async function parseResolverFile(path) {
|
|
|
892
931
|
return [];
|
|
893
932
|
}));
|
|
894
933
|
}
|
|
895
|
-
async function parseTypeResolvers(typeName, glob) {
|
|
934
|
+
async function parseTypeResolvers(typeName, glob, ignore) {
|
|
935
|
+
const shouldIgnore = createMatcher(ignore);
|
|
896
936
|
const result = {};
|
|
897
937
|
for await (const entry of globIterate(glob, { withFileTypes: true })) {
|
|
898
938
|
const fullpath = entry.fullpath();
|
|
899
|
-
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
939
|
+
if (!shouldIgnore(fullpath) && entry.isFile() && entry.name.endsWith(".ts")) {
|
|
900
940
|
for (const [name, reference] of Object.entries(await parseResolverFile(fullpath))) {
|
|
901
941
|
let realName = name;
|
|
902
942
|
if (realName === "default") {
|
|
@@ -911,7 +951,7 @@ async function parseTypeResolvers(typeName, glob) {
|
|
|
911
951
|
}
|
|
912
952
|
return result;
|
|
913
953
|
}
|
|
914
|
-
async function parse$2(dirpath) {
|
|
954
|
+
async function parse$2(dirpath, ignore) {
|
|
915
955
|
const dir = await fs.stat(dirpath);
|
|
916
956
|
if (!dir.isDirectory()) {
|
|
917
957
|
throw new Error(`Expected ${dirpath} to be a directory`);
|
|
@@ -920,14 +960,15 @@ async function parse$2(dirpath) {
|
|
|
920
960
|
dirpath += "/";
|
|
921
961
|
}
|
|
922
962
|
const out = {};
|
|
963
|
+
const shouldIgnore = createMatcher(ignore);
|
|
923
964
|
for await (const name of await fs.readdir(dirpath)) {
|
|
924
965
|
const file = join(dirpath, name);
|
|
925
966
|
const entry = await fs.stat(file);
|
|
926
967
|
if (entry.isDirectory()) {
|
|
927
|
-
out[name] = await parseTypeResolvers(name, file + "/*.ts");
|
|
968
|
+
out[name] = await parseTypeResolvers(name, file + "/*.ts", shouldIgnore);
|
|
928
969
|
}
|
|
929
970
|
else if (entry.isFile() && name.endsWith(".ts")) {
|
|
930
|
-
out[name.slice(0, -3)] = await parseTypeResolvers(name.slice(0, -3), file);
|
|
971
|
+
out[name.slice(0, -3)] = await parseTypeResolvers(name.slice(0, -3), file, shouldIgnore);
|
|
931
972
|
}
|
|
932
973
|
}
|
|
933
974
|
return out;
|
|
@@ -1512,9 +1553,13 @@ async function* findSchemaFiles(glob) {
|
|
|
1512
1553
|
}
|
|
1513
1554
|
}
|
|
1514
1555
|
}
|
|
1515
|
-
async function parse(glob) {
|
|
1556
|
+
async function parse(glob, ignore) {
|
|
1557
|
+
const shouldIgnore = createMatcher(ignore);
|
|
1516
1558
|
const documentNodes = [];
|
|
1517
1559
|
for await (const entry of findSchemaFiles(glob)) {
|
|
1560
|
+
if (shouldIgnore(entry)) {
|
|
1561
|
+
continue;
|
|
1562
|
+
}
|
|
1518
1563
|
documentNodes.push(parse$3(new Source(await fs.readFile(entry, "utf-8"), entry)));
|
|
1519
1564
|
}
|
|
1520
1565
|
if (!documentNodes.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphql-jerky",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Jerky is a schema-first static graphql schema lightweight code generator.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": "./build/bin/jerky.cjs",
|
|
@@ -19,11 +19,13 @@
|
|
|
19
19
|
"just-partition": "^2.2.0",
|
|
20
20
|
"just-pascal-case": "^3.2.0",
|
|
21
21
|
"just-zip-it": "^3.2.0",
|
|
22
|
+
"picomatch": "^2.3.1",
|
|
22
23
|
"typescript": "^5.1.3"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@rollup/plugin-typescript": "^11.1.1",
|
|
26
27
|
"@types/node": "^20.3.1",
|
|
28
|
+
"@types/picomatch": "^2.3.0",
|
|
27
29
|
"rollup": "^3.25.1",
|
|
28
30
|
"rollup-plugin-dts": "^5.3.0",
|
|
29
31
|
"tslib": "^2.5.3"
|