Skip to content

Commit

Permalink
Drop Snapshot transform in favor of a new Snapshot plugin (#4638)
Browse files Browse the repository at this point in the history
* Drop Snapshot transform and introduce a new Snapshot plugin

* Respect if
  • Loading branch information
ardatan authored Oct 6, 2022
1 parent 6d40631 commit dd831a7
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 2,129 deletions.
6 changes: 6 additions & 0 deletions .changeset/little-plants-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-mesh/plugin-snapshot': patch
'@graphql-mesh/types': patch
---

Drop Snapshot transform in favor of Snapshot plugin
14 changes: 7 additions & 7 deletions examples/soap-country-info/.meshrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ sources:
handler:
soap:
wsdl: http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL
transforms:
- snapshot:
if: "process.env.NODE_ENV != 'production'"
apply:
- Query.*
- Mutation.*
outputDir: snapshots

plugins:
- snapshot:
if: "process.env.NODE_ENV != 'production'"
apply:
- http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso
outputDir: snapshots

documents:
- list-of-languages-by-name.graphql
2 changes: 1 addition & 1 deletion examples/soap-country-info/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dependencies": {
"@graphql-mesh/cli": "0.78.29",
"@graphql-mesh/soap": "0.14.19",
"@graphql-mesh/transform-snapshot": "0.14.65",
"@graphql-mesh/plugin-snapshot": "0.0.0",
"graphql": "16.6.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphql-mesh/transform-snapshot",
"version": "0.14.65",
"name": "@graphql-mesh/plugin-snapshot",
"version": "0.0.0",
"sideEffects": false,
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand All @@ -22,22 +22,18 @@
"repository": {
"type": "git",
"url": "Urigo/graphql-mesh",
"directory": "packages/transforms/snapshot"
"directory": "packages/plugins/snapshot"
},
"peerDependencies": {
"graphql": "*"
},
"devDependencies": {
"graphql-fields": "2.0.3"
},
"dependencies": {
"@graphql-mesh/string-interpolation": "0.3.2",
"@graphql-mesh/utils": "0.41.19",
"@graphql-mesh/cross-helpers": "0.2.6",
"@graphql-mesh/types": "0.84.8",
"@graphql-mesh/utils": "0.41.19",
"@graphql-tools/resolvers-composition": "6.5.6",
"@graphql-tools/schema": "9.0.4",
"@graphql-tools/utils": "8.12.0",
"object-hash": "3.0.0",
"@whatwg-node/fetch": "0.4.7",
"minimatch": "5.1.0",
"tslib": "^2.4.0"
},
"publishConfig": {
Expand Down
75 changes: 75 additions & 0 deletions packages/plugins/snapshot/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { hashObject } from '@graphql-mesh/string-interpolation';
import { MeshPlugin, MeshPluginOptions, YamlConfig } from '@graphql-mesh/types';
import { getHeadersObj, pathExists, writeJSON } from '@graphql-mesh/utils';
import minimatch from 'minimatch';
import { fs, path, process } from '@graphql-mesh/cross-helpers';
import { Response } from '@whatwg-node/fetch';

function calculateCacheKey(url: string, options: RequestInit) {
return hashObject({
url,
options,
});
}

interface SnapshotEntry {
text: string;
headersObj: Record<string, string>;
status: number;
statusText: string;
}

export default function useSnapshot(
pluginOptions: MeshPluginOptions<YamlConfig.SnapshotPluginConfig>
): MeshPlugin<any> {
if (typeof pluginOptions.if === 'boolean') {
if (!pluginOptions.if) {
return {};
}
}
if (typeof pluginOptions.if === 'string') {
// eslint-disable-next-line no-new-func
if (new Function('return ' + pluginOptions.if, 'env')(process.env)) {
return {};
}
}
const matches = pluginOptions.apply.map(glob => new minimatch.Minimatch(glob));
const snapshotsDir = pluginOptions.outputDir || '__snapshots__';
return {
async onFetch({ url, options, setFetchFn }) {
if (matches.some(matcher => matcher.match(url))) {
const snapshotFileName = calculateCacheKey(url, options);
const snapshotPath = path.join(pluginOptions.baseDir, snapshotsDir, `${snapshotFileName}.json`);
if (await pathExists(snapshotPath)) {
setFetchFn(async () => {
const snapshotFile = await fs.promises.readFile(snapshotPath, 'utf-8');
const snapshot: SnapshotEntry = JSON.parse(snapshotFile);
return new Response(snapshot.text, {
headers: snapshot.headersObj,
status: snapshot.status,
statusText: snapshot.statusText,
});
});
return () => {};
}
return async ({ response, setResponse }) => {
const snapshot: SnapshotEntry = {
text: await response.text(),
headersObj: getHeadersObj(response.headers),
status: response.status,
statusText: response.statusText,
};
await writeJSON(snapshotPath, snapshot);
setResponse(
new Response(snapshot.text, {
headers: snapshot.headersObj,
status: snapshot.status,
statusText: snapshot.statusText,
})
);
};
}
return () => {};
},
};
}
27 changes: 27 additions & 0 deletions packages/plugins/snapshot/yaml-config.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
extend type Plugin {
"""
Configuration for Snapshot extension
"""
snapshot: SnapshotPluginConfig
}

type SnapshotPluginConfig @md {
"""
Expression for when to activate this extension.
Value can be a valid JS expression string or a boolean
"""
if: If
"""
HTTP URL pattern to be applied
For example;
apply:
- http://my-remote-api.com/* \<- * will apply this extension to all paths of remote API
"""
apply: [String!]!
"""
Path to the directory of the generated snapshot files
"""
outputDir: String!
}

union If = String | Boolean
Loading

0 comments on commit dd831a7

Please sign in to comment.