Skip to content
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

Hydrogen-ui storefront API schema and types #1122

Merged
merged 21 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
**/dist/**
packages/hydrogen/graphql.schema.json
**/vendor
packages/hydrogen-ui/storefront.schema.json
packages/hydrogen-ui/coverage/**
54 changes: 54 additions & 0 deletions packages/hydrogen-ui/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
# Hydrogen-UI

## Getting started

npm:

```bash
npm i --save @shopify/hydrogen-ui
```

Yarn:

```bash
yarn add @shopify/hydrogen-ui
```

Improve the developer experience:

- [Add autocompletion for the Storefront API](#storefront-api-graphql-autocompletion)
- [Add Typescript types for Storefront API objects](#typescript-types)

## Storefront API GraphQL autocompletion
Copy link
Contributor Author

@frehner frehner Apr 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cartogram What we talked about this morning


To enable GraphQL autocompletion for the Storefront API in your IDE:

1. Add `graphql` and [GraphQL-config](https://www.graphql-config.com/docs/user/user-installation) by running `yarn add --dev graphql graphql-config`
1. Create a [GraphQL config file](https://www.graphql-config.com/docs/user/user-usage) at the root of your code. For example, `.graphqlrc.yml`
1. Add a [`schema`](https://www.graphql-config.com/docs/user/user-schema) and point it to Hydrogen-UI's bundled schema for the Storefront API. For example:

```yml
# .graphqlrc.yml
schema: node_modules/@shopify/hydrogen-ui/storefront.schema.json
```

GraphQL autocompletion and validation will now work in `.graphql` files or in [`gql`](https://github.com/apollographql/graphql-tag) template literals!

## Typescript Types

To add Typescript types to your Storefront API objects, do the following:

```ts
import type {Product} from '@shopify/hydrogen-ui/storefront-api-types';

const product: Product = {};
```

You may also want to use Typescript's built-in helpers for creating your own object shapes, depending on needs. For example:

```ts
const partialProduct: Partial<Product> = {};

const productTitle: Pick<Product, 'title'> = '';

const productExceptTitle: Omit<Product, 'title'> = {};
```

## Common Problems

### jsx-runtime
Expand Down
37 changes: 37 additions & 0 deletions packages/hydrogen-ui/codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
overwrite: true
schema:
- https://hydrogen-preview.myshopify.com/api/2022-07/graphql.json:
headers:
X-Shopify-Storefront-Access-Token: 3b580e70970c4528da70c98e097c2fa0
content-type: application/json
generates:
# the base types that are generated
src/storefront-api-types.d.ts:
plugins:
- add:
content:
- '/** '
- ' * THIS FILE IS AUTO-GENERATED, DO NOT EDIT'
- ' * Based on Storefront API 2022-07'
- ' * If changes need to happen to the types defined in this file, then generally the Storefront API needs to update, and then you can run `yarn graphql-types`'
- ' * Except custom Scalars, which are defined in the `codegen.yml` file'
- ' */'
- '/* eslint-disable */'
- typescript:
useTypeImports: true
# If a default type for a scalar isn't set, then instead of 'any' let's set to 'unknown' for better type safety.
defaultScalarType: unknown
useImplementingTypes: true
enumsAsTypes: true
# Define how the SFAPI's custom scalars map to TS types
scalars:
DateTime: string
Decimal: string
HTML: string
Money: string
URL: string
# the schema file, which is the local representation of the graphql endpoint
./storefront.schema.json:
plugins:
- 'introspection':
minify: true
22 changes: 18 additions & 4 deletions packages/hydrogen-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shopify/hydrogen-ui",
"version": "2022.04.0",
"version": "2022.07.0",
"description": "Components for modern custom Shopify storefronts",
"homepage": "https://github.com/Shopify/hydrogen#readme",
"license": "MIT",
Expand All @@ -9,12 +9,14 @@
"node": ">=14"
},
"files": [
"dist"
"dist",
"storefront.schema.json"
],
"type": "module",
"exports": {
"./server": "./dist/index.server.js",
"./client": "./dist/index.client.js"
"./client": "./dist/index.client.js",
"./storefront-api-types": "./dist/storefront-api-types.d.ts"
},
"typesVersions": {
"<=4.6": {
Expand All @@ -23,6 +25,9 @@
],
"server": [
"./dist/index.server.d.ts"
],
"storefront-api-types": [
"./dist/storefront-api-types.d.ts"
]
}
},
Expand All @@ -33,18 +38,27 @@
"dev:ts": "tsc --watch",
"build": "yarn build:vite && yarn build:ts",
"build:vite": "vite build",
"build:ts": "tsc",
"build:ts": "run-p build:tsc copy-storefront-types",
"build:tsc": "tsc",
"copy-storefront-types": "cpy ./src/storefront-api-types.d.ts ./dist/ --flat",
"format": "prettier --write \"src/**/*\"",
"graphql-types": "graphql-codegen --config codegen.yml && yarn format",
"preview": "vite preview",
"test": "vitest",
"test:ci": "vitest run --coverage"
},
"devDependencies": {
"@faker-js/faker": "^6.1.2",
"@graphql-codegen/cli": "^2.6.2",
"@graphql-codegen/typescript": "^2.4.8",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@vitejs/plugin-react": "^1.3.0",
"c8": "^7.11.0",
"cpy-cli": "^4.1.0",
"graphql": "^16.3.0",
"happy-dom": "^2.55.0",
"prettier": "^2.6.2",
"vite": "^2.9.0",
"vitest": "^0.9.4"
},
Expand Down
12 changes: 5 additions & 7 deletions packages/hydrogen-ui/src/ExternalVideo.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import {render, screen} from '@testing-library/react';
import {PartialDeep} from 'type-fest';
import {
import type {
ExternalVideo as ExternalVideoType,
Image,
MediaHost,
MediaContentType,
} from '../../hydrogen/src/storefront-api-types';
} from './storefront-api-types';
import {ExternalVideo} from './ExternalVideo';
import {faker} from '@faker-js/faker';
import {vi} from 'vitest';
Expand Down Expand Up @@ -92,12 +90,12 @@ export function getExternalVideoData(
): PartialDeep<ExternalVideoType> {
return {
id: externalVideo.id ?? faker.random.words(),
mediaContentType: MediaContentType.ExternalVideo,
mediaContentType: 'EXTERNAL_VIDEO',
embedUrl: externalVideo.embedUrl ?? faker.internet.url(),
host:
externalVideo.host ?? faker.datatype.number({max: 2, min: 1}) === 1
? MediaHost.Youtube
: MediaHost.Vimeo,
? 'YOUTUBE'
: 'VIMEO',
previewImage: getPreviewImage(externalVideo.previewImage ?? undefined),
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/hydrogen-ui/src/ExternalVideo.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useMemo} from 'react';
import type {ExternalVideo as ExternalVideoType} from '../../hydrogen/src/storefront-api-types';
import type {ExternalVideo as ExternalVideoType} from './storefront-api-types';
import type {PartialDeep} from 'type-fest';

interface ExternalVideoProps {
Expand Down
Loading