Skip to content

Update queries for latest 2.3 schema and add validator script #318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ Follow these steps to install the dependencies for all the packages in the proje
5. To run the Venia theme development experience, run `npm run watch:venia` from package root.
6. To run the full PWA Studio deeloper experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root.

## Troubleshooting

### When I run the developer mode, I get validation errors

Make sure you have created a `.env` file in `packages/venia-concept` which specifies variables for your local development environment. You can copy from the template `packages/venia-concept/.env.dist`.

### Venia queries to GraphQL produce validation errors

Venia and its GraphQL queries may be out of sync with the schema of your connected Magento instance. Make sure the Magento instance is up to date with the 2.3 development branch, and your copy of this repository (or your dependency on it) is up to date.

**To test whether your queries are up to date, run `npm run validate:venia:gql` at project root.**

## Things not to do

When using a monorepo and lerna, it's important that you break some common habits that are common when developing front-end packages.
Expand Down
615 changes: 358 additions & 257 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"test:ci": "npm run -s test -- -i --json --outputFile=test-results.json",
"test:debug": "node --inspect-brk node_modules/.bin/jest -i --watch",
"test:dev": "jest --watch",
"validate:venia:gql": "cd packages/venia-concept && npm run -s validate-queries; cd - >/dev/null",
"watch:all": "concurrently -c yellow.dim,green.dim,cyan.dim -n ␢,℗,☄︎ 'npm run watch:buildpack' 'npm run watch:peregrine' 'npm run watch:venia-dev-server'",
"watch:buildpack": "cd packages/pwa-buildpack && npm run -s watch; cd - >/dev/null",
"watch:peregrine": "cd packages/peregrine && npm run -s watch; cd - >/dev/null",
Expand Down Expand Up @@ -62,6 +63,7 @@
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^5.2.0",
"eslint-plugin-babel": "^5.1.0",
"eslint-plugin-graphql": "^2.1.1",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-node": "^7.0.1",
"eslint-plugin-react": "^7.9.1",
Expand Down
8 changes: 6 additions & 2 deletions packages/peregrine/src/List/__tests__/items.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const items = [
{
id: '001',
name: 'Test Product 1',
small_image: '/test/product/1.png',
small_image: {
path: '/test/product/1.png'
},
price: {
regularPrice: {
amount: {
Expand All @@ -22,7 +24,9 @@ const items = [
{
id: '002',
name: 'Test Product 2',
small_image: '/test/product/2.png',
small_image: {
path: '/test/product/2.png'
},
price: {
regularPrice: {
amount: {
Expand Down
8 changes: 6 additions & 2 deletions packages/peregrine/src/List/__tests__/list.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ const items = [
{
id: '001',
name: 'Test Product 1',
small_image: '/test/product/1.png',
small_image: {
path: '/test/product/1.png'
},
price: {
regularPrice: {
amount: {
Expand All @@ -26,7 +28,9 @@ const items = [
{
id: '002',
name: 'Test Product 2',
small_image: '/test/product/2.png',
small_image: {
path: '/test/product/2.png'
},
price: {
regularPrice: {
amount: {
Expand Down
1 change: 1 addition & 0 deletions packages/venia-concept/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"prepare": "npm-merge-driver install",
"start": "webpack-dev-server --progress --color --env.phase development",
"start:debug": "node --inspect-brk ./node_modules/.bin/webpack-dev-server --progress --color --env.phase development",
"validate-queries": "node ./validate-queries.js",
"watch": "npm run -s start"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const categoryQuery = gql`
items {
id
name
small_image
small_image {
path
}
url_key
price {
regularPrice {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const items = [
{
id: 1,
name: 'Test Product 1',
small_image: '/test/product/1.png',
small_image: {
path: '/test/product/1.png'
},
price: {
regularPrice: {
amount: {
Expand All @@ -24,7 +26,9 @@ const items = [
{
id: 2,
name: 'Test Product 2',
small_image: '/test/product/2.png',
small_image: {
path: '/test/product/2.png'
},
price: {
regularPrice: {
amount: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ const items = [
{
id: 1,
name: 'Test Product 1',
small_image: '/test/product/1.png',
small_image: {
path: '/test/product/1.png'
},
price: {
regularPrice: {
amount: {
Expand All @@ -22,7 +24,9 @@ const items = [
{
id: 2,
name: 'Test Product 2',
small_image: '/test/product/2.png',
small_image: {
path: '/test/product/2.png'
},
price: {
regularPrice: {
amount: {
Expand Down
4 changes: 3 additions & 1 deletion packages/venia-concept/src/components/Gallery/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class Gallery extends Component {
shape({
id: number.isRequired,
name: string.isRequired,
small_image: string.isRequired,
small_image: shape({
path: string.isRequired
}).isRequired,
price: shape({
regularPrice: shape({
amount: shape({
Expand Down
6 changes: 4 additions & 2 deletions packages/venia-concept/src/components/Gallery/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ class GalleryItem extends Component {
item: shape({
id: number.isRequired,
name: string.isRequired,
small_image: string.isRequired,
small_image: shape({
path: string.isRequired
}).isRequired,
url_key: string.isRequired,
price: shape({
regularPrice: shape({
Expand Down Expand Up @@ -138,7 +140,7 @@ class GalleryItem extends Component {
return (
<img
className={className}
src={makeProductMediaPath(small_image)}
src={makeProductMediaPath(small_image.path)}
alt={name}
width={imageWidth}
height={imageHeight}
Expand Down
4 changes: 3 additions & 1 deletion packages/venia-concept/src/components/Gallery/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class GalleryItems extends Component {
shape({
id: number.isRequired,
name: string.isRequired,
small_image: string.isRequired,
small_image: shape({
path: string.isRequired
}).isRequired,
price: shape({
regularPrice: shape({
amount: shape({
Expand Down
96 changes: 96 additions & 0 deletions packages/venia-concept/validate-queries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require('dotenv').config();
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
const magentoDomainVarName = 'MAGENTO_BACKEND_DOMAIN';
const magentoDomain = process.env[magentoDomainVarName];
if (!magentoDomain) {
console.error(
`No ${magentoDomainVarName} environment variable specified. Have you created a .env file?`
);
process.exit(1);
}

const { URL } = require('url');
let uri;
try {
uri = new URL('/graphql', magentoDomain);
} catch (e) {
console.error(
`Could not build a GraphQL endpoint URL from env var ${magentoDomainVarName}: '${magentoDomain}'.`
);
process.exit(1);
}

const { gql, HttpLink, makePromise, execute } = require('apollo-boost');
const { getIntrospectionQuery, introspectionQuery } = require('graphql');

const query = gql(
getIntrospectionQuery ? getIntrospectionQuery() : introspectionQuery
);

const link = new HttpLink({ uri, fetch: require('node-fetch') });

async function getSchema() {
console.log(`Validating queries based on schema at ${uri.href}...`);
return makePromise(execute(link, { query }));
}

async function getRuleConfig() {
const schemaJson = await getSchema();
console.log(`Retrieved introspection query. Configuring validator...`);
return [
'error',
{
env: 'apollo',
projectName: 'magento',
schemaJson
},
{
env: 'literal',
projectName: 'magento',
schemaJson
}
];
}

async function getLinterConfig() {
const ruleConfig = await getRuleConfig();
console.log(`Validator configured. Running validator...`);
return {
parser: 'babel-eslint',
rules: {
'graphql/template-strings': ruleConfig
},
plugins: ['graphql'],
useEslintrc: false
};
}

async function validateQueries() {
const linterConfig = await getLinterConfig();
const CLIEngine = require('eslint').CLIEngine;
const cli = new CLIEngine(linterConfig);
const files = cli.resolveFileGlobPatterns(['src/**/*.{js,graphql,gql}']);
const report = cli.executeOnFiles(files);
if (report.errorCount > 0) {
console.error(`Errors found!`);
const formatter = cli.getFormatter();
process.stderr.write(formatter(report.results));
console.error(
`
These errors may indicate:
- an out-of-date Magento 2.3 codebase running at "${magentoDomain}"
- an out-of-date project codebase whose queries need updating

Use GraphiQL or another schema exploration tool on the Magento store to learn more.
`
);
process.exit(1);
} else {
console.log(
`Validation passed! All queries found are valid for schema.`
);
process.exit(0);
}
}

validateQueries();