Skip to content
This repository was archived by the owner on Jun 29, 2021. It is now read-only.

Commit d76ff38

Browse files
committed
add generateId option to graphql-mini-transforms
1 parent 9d2b862 commit d76ff38

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

packages/graphql-mini-transforms/src/document.ts

+19-7
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,26 @@ import {
1414
const IMPORT_REGEX = /^#import\s+['"]([^'"]*)['"];?[\s\n]*/gm;
1515
const DEFAULT_NAME = 'Operation';
1616

17+
function defaultGenerateId(normalizedSource: string) {
18+
// This ID is a hash of the full file contents that are part of the document,
19+
// including other documents that are injected in, but excluding any unused
20+
// fragments. This is useful for things like persisted queries.
21+
return createHash('sha256')
22+
.update(minifySource(normalizedSource))
23+
.digest('hex');
24+
}
25+
26+
export interface CleanDocumentOptions {
27+
removeUnused?: boolean;
28+
generateId?: (normalizedSource: string) => string;
29+
}
30+
1731
export function cleanDocument(
1832
document: DocumentNode,
19-
{removeUnused = true} = {},
33+
{
34+
removeUnused = true,
35+
generateId = defaultGenerateId,
36+
}: CleanDocumentOptions = {},
2037
) {
2138
if (removeUnused) {
2239
removeUnusedDefinitions(document);
@@ -33,12 +50,7 @@ export function cleanDocument(
3350
stripLoc(definition);
3451
}
3552

36-
// This ID is a hash of the full file contents that are part of the document,
37-
// including other documents that are injected in, but excluding any unused
38-
// fragments. This is useful for things like persisted queries.
39-
const id = createHash('sha256')
40-
.update(normalizedSource)
41-
.digest('hex');
53+
const id = generateId(print(document));
4254

4355
Reflect.defineProperty(normalizedDocument, 'id', {
4456
value: id,

packages/graphql-mini-transforms/src/webpack.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ import {dirname} from 'path';
33
import {loader} from 'webpack';
44
import {parse, DocumentNode} from 'graphql';
55

6-
import {cleanDocument, extractImports} from './document';
6+
import {cleanDocument, extractImports, CleanDocumentOptions} from './document';
77

88
export default async function graphQLLoader(
99
this: loader.LoaderContext,
1010
source: string | Buffer,
1111
) {
1212
this.cacheable();
1313

14+
const options = this.query;
15+
16+
if (options && typeof options !== 'object') {
17+
throw new Error(
18+
'@shopify/graphql-mini-transforms only supports options as an object',
19+
);
20+
}
21+
1422
const done = this.async();
1523

1624
if (done == null) {
@@ -20,8 +28,19 @@ export default async function graphQLLoader(
2028
}
2129

2230
try {
31+
const cleanDocumentOptions = {} as CleanDocumentOptions;
32+
33+
if (options) {
34+
cleanDocumentOptions.generateId = options.generateId;
35+
}
36+
2337
const document = await loadDocument(source, this.context, this);
24-
done(null, `export default ${JSON.stringify(cleanDocument(document))};`);
38+
done(
39+
null,
40+
`export default ${JSON.stringify(
41+
cleanDocument(document, cleanDocumentOptions),
42+
)};`,
43+
);
2544
} catch (error) {
2645
done(error);
2746
}

packages/graphql-mini-transforms/tests/webpack.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ describe('graphql-mini-transforms/webpack', () => {
7272
);
7373
});
7474

75+
it('has option for custom ID generate function', async () => {
76+
const result = await extractDocumentExport(
77+
`query Shop { shop { id } }`,
78+
createLoaderContext({loaderOptions: {generateId: () => 'foo'}}),
79+
);
80+
expect(result).toHaveProperty('id', 'foo');
81+
});
82+
7583
describe('import', () => {
7684
it('adds the resolved import as a dependency', async () => {
7785
const context = '/app/';
@@ -208,6 +216,7 @@ interface Options {
208216
context?: string;
209217
resolve?(context: string, imported: string): string | Error;
210218
readFile?(file: string): string | Error;
219+
loaderOptions?: object;
211220
}
212221

213222
// This is a limited subset of the loader API that we actually use in our
@@ -216,6 +225,7 @@ function createLoaderContext({
216225
context = __dirname,
217226
readFile = () => '',
218227
resolve = (context, imported) => path.resolve(context, imported),
228+
loaderOptions = undefined,
219229
}: Options = {}): loader.LoaderContext {
220230
return {
221231
context,
@@ -251,6 +261,7 @@ function createLoaderContext({
251261
}
252262
},
253263
addDependency() {},
264+
query: loaderOptions,
254265
} as any;
255266
}
256267

0 commit comments

Comments
 (0)