├── index.js ├── .npmrc ├── .eslintignore ├── .prettierrc ├── .npmignore ├── src ├── helpers │ ├── cacheKey.js │ ├── getFromCache.js │ ├── saveToCache.js │ ├── shouldUseCachedVersion.js │ ├── saveNodeFromGarbageCollection.js │ ├── getNonRootFileNodeIds.js │ ├── checkForSecretKey.js │ ├── getRootFileNodeIds.js │ ├── checkForStripeObjects.js │ ├── extractUrls.js │ ├── hasFilesToDownload.js │ ├── extractChildUrls.js │ ├── checkCache.js │ ├── createFileNode.js │ └── addLocalFiles.js ├── __tests__ │ ├── cacheKey.test.js │ ├── checkForSecretKey.test.js │ ├── checkForStripeObjects.test.js │ ├── getRootFileNodeIds.js │ ├── getNonRootFileNodeIds.js │ ├── extractUrls.test.js │ ├── shouldUseCachedVersion.test.js │ ├── hasFilesToDownload.test.js │ ├── addLocalFiles.test.js │ ├── StripeObject.test.js │ └── extractChildUrls.test.js ├── StripeObject.js ├── FileDownloadService.js ├── gatsby-node.js └── stripeObjects.json ├── .gitignore ├── .babelrc ├── .eslintrc ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── package.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── README.md └── CHANGELOG.md /index.js: -------------------------------------------------------------------------------- 1 | //noop -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/__tests__ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true 3 | } 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | yarn.lock 4 | package-lock.json 5 | src 6 | __tests__ -------------------------------------------------------------------------------- /src/helpers/cacheKey.js: -------------------------------------------------------------------------------- 1 | function cacheKey(url) { 2 | return `stripe-file-${url}`; 3 | } 4 | 5 | module.exports = cacheKey; 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /*.js 4 | /stripeObjects.json 5 | helpers 6 | !index.js 7 | __tests__ 8 | !/src/__tests__ 9 | !/src/helpers -------------------------------------------------------------------------------- /src/helpers/getFromCache.js: -------------------------------------------------------------------------------- 1 | function getFromCache(cache, cacheKey) { 2 | return cache.get(cacheKey); 3 | } 4 | 5 | module.exports = getFromCache; 6 | -------------------------------------------------------------------------------- /src/helpers/saveToCache.js: -------------------------------------------------------------------------------- 1 | async function saveToCache(cache, cacheKey, value) { 2 | await cache.set(cacheKey, value); 3 | } 4 | 5 | module.exports = saveToCache; 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "14.15.0" 8 | } 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /src/helpers/shouldUseCachedVersion.js: -------------------------------------------------------------------------------- 1 | function shouldUseCachedVersion(cachedData, node) { 2 | return cachedData && node.updated === cachedData.updated; 3 | } 4 | 5 | module.exports = shouldUseCachedVersion; 6 | -------------------------------------------------------------------------------- /src/helpers/saveNodeFromGarbageCollection.js: -------------------------------------------------------------------------------- 1 | function saveNodeFromGarbageCollection(touchNode, getNode, nodeId) { 2 | touchNode(getNode(nodeId)); 3 | } 4 | 5 | module.exports = saveNodeFromGarbageCollection; 6 | -------------------------------------------------------------------------------- /src/helpers/getNonRootFileNodeIds.js: -------------------------------------------------------------------------------- 1 | function getNonRootFileNodeIds(fileNodeIds) { 2 | return fileNodeIds.filter((fileNodeId) => fileNodeId.location !== "root"); 3 | } 4 | 5 | module.exports = getNonRootFileNodeIds; 6 | -------------------------------------------------------------------------------- /src/helpers/checkForSecretKey.js: -------------------------------------------------------------------------------- 1 | function checkForSecretKey(secretKey) { 2 | if (!secretKey) { 3 | throw new Error("No Stripe secret key found in gatsby-config"); 4 | } 5 | } 6 | 7 | module.exports = checkForSecretKey; 8 | -------------------------------------------------------------------------------- /src/helpers/getRootFileNodeIds.js: -------------------------------------------------------------------------------- 1 | function getRootFileNodeIds(fileNodeIds) { 2 | return fileNodeIds 3 | .filter((fileNodeId) => fileNodeId.location === "root") 4 | .map((rootFileNodeId) => rootFileNodeId.id); 5 | } 6 | 7 | module.exports = getRootFileNodeIds; 8 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true, 5 | "jest": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:prettier/recommended" 10 | ], 11 | "parser": "babel-eslint", 12 | "rules": { 13 | "no-console": "off" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/helpers/checkForStripeObjects.js: -------------------------------------------------------------------------------- 1 | function checkForStripeObjects(objects) { 2 | if (!objects.length) { 3 | throw new Error( 4 | "No Stripe object types found in gatsby-config. Add types to objects array like this: ['Balance', 'Customer', 'BalanceTransaction']" 5 | ); 6 | } 7 | } 8 | 9 | module.exports = checkForStripeObjects; 10 | -------------------------------------------------------------------------------- /src/__tests__/cacheKey.test.js: -------------------------------------------------------------------------------- 1 | const cacheKey = require("../helpers/cacheKey"); 2 | 3 | describe("cacheKey()", () => { 4 | test("returns Gatsby cache key when given file url", () => { 5 | const url = 6 | "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3"; 7 | const expected = `stripe-file-${url}`; 8 | 9 | expect(cacheKey(url)).toBe(expected); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/helpers/extractUrls.js: -------------------------------------------------------------------------------- 1 | const extractChildUrls = require("./extractChildUrls"); 2 | 3 | function extractUrls(node) { 4 | switch (node.object) { 5 | case "product": 6 | return node.images.map((url) => ({ location: "root", url })); 7 | case "sku": 8 | case "price": 9 | return extractChildUrls(node); 10 | default: 11 | return []; 12 | } 13 | } 14 | 15 | module.exports = extractUrls; 16 | -------------------------------------------------------------------------------- /src/helpers/hasFilesToDownload.js: -------------------------------------------------------------------------------- 1 | function hasFilesToDownload(node) { 2 | const hasImages = node.images && node.images.length; 3 | const hasImage = node.image && node.image.length; 4 | const hasProductImages = node.product && hasFilesToDownload(node.product); 5 | // eslint-disable-next-line no-unneeded-ternary 6 | return hasImages || hasImage || hasProductImages ? true : false; 7 | } 8 | 9 | module.exports = hasFilesToDownload; 10 | -------------------------------------------------------------------------------- /src/helpers/extractChildUrls.js: -------------------------------------------------------------------------------- 1 | const hasFilesToDownload = require("./hasFilesToDownload"); 2 | 3 | function extractChildUrls(node) { 4 | let urls = []; 5 | if (node.image && node.image.length) { 6 | urls = [{ location: "root", url: node.image }]; 7 | } 8 | 9 | if (hasFilesToDownload(node.product)) { 10 | node.product.images.forEach((url) => { 11 | urls.push({ location: "product", url }); 12 | }); 13 | } 14 | return urls; 15 | } 16 | 17 | module.exports = extractChildUrls; 18 | -------------------------------------------------------------------------------- /src/__tests__/checkForSecretKey.test.js: -------------------------------------------------------------------------------- 1 | const checkForSecretKey = require("../helpers/checkForSecretKey"); 2 | 3 | describe("plugin", () => { 4 | describe(", when options: secretKey", () => { 5 | test("is empty, throws error", () => { 6 | const secretKey = ""; 7 | const error = "No Stripe secret key found in gatsby-config"; 8 | 9 | expect(() => checkForSecretKey(secretKey)).toThrow(error); 10 | }); 11 | 12 | test("is not empty, does not throw error", () => { 13 | const secretKey = "a_secret_key"; 14 | 15 | expect(checkForSecretKey(secretKey)).toBe(undefined); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [njosefbeck] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /src/__tests__/checkForStripeObjects.test.js: -------------------------------------------------------------------------------- 1 | const checkForStripeObjects = require("../helpers/checkForStripeObjects"); 2 | 3 | describe("plugin", () => { 4 | describe(", when options: object array", () => { 5 | test("is empty, throws error", () => { 6 | const objects = []; 7 | const error = 8 | "No Stripe object types found in gatsby-config. Add types to objects array like this: ['Balance', 'Customer', 'BalanceTransaction']"; 9 | 10 | expect(() => checkForStripeObjects(objects)).toThrow(error); 11 | }); 12 | 13 | test("is not empty, does not throw error", () => { 14 | const objects = ["Sku"]; 15 | 16 | expect(checkForStripeObjects(objects)).toBe(undefined); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/helpers/checkCache.js: -------------------------------------------------------------------------------- 1 | const getFromCache = require("./getFromCache"); 2 | const cacheKey = require("./cacheKey"); 3 | const shouldUseCachedVersion = require("./shouldUseCachedVersion"); 4 | const saveNodeFromGarbageCollection = require("./saveNodeFromGarbageCollection"); 5 | 6 | async function checkCache({ cache, getNode, touchNode, url, node }) { 7 | const cachedFileData = await getFromCache(cache, cacheKey(url)); 8 | if (shouldUseCachedVersion(cachedFileData, node)) { 9 | const fileNode = getNode(cachedFileData.fileNodeId); 10 | 11 | if (fileNode) { 12 | saveNodeFromGarbageCollection( 13 | touchNode, 14 | getNode, 15 | cachedFileData.fileNodeId 16 | ); 17 | return cachedFileData.fileNodeId; 18 | } 19 | } 20 | } 21 | 22 | module.exports = checkCache; 23 | -------------------------------------------------------------------------------- /src/__tests__/getRootFileNodeIds.js: -------------------------------------------------------------------------------- 1 | const getRootFileNodeIds = require("../helpers/getRootFileNodeIds"); 2 | 3 | describe("getRootFileNodeIds()", () => { 4 | test("returns only root file node ids", () => { 5 | const fileNodeIds = [ 6 | { 7 | location: "root", 8 | id: "8fa3f02d-5e34-5191-bf6a-7533210053fc", 9 | }, 10 | { 11 | location: "product", 12 | id: "67735a50-5109-51be-85b4-803f05d27797", 13 | }, 14 | { 15 | location: "product", 16 | id: "7bffbe3e-beed-5893-bc26-eaec9fc6d787", 17 | }, 18 | { 19 | location: "product", 20 | id: "b9c3ae18-78f9-5b31-8e6b-372de7b6102a", 21 | }, 22 | ]; 23 | 24 | const expected = ["8fa3f02d-5e34-5191-bf6a-7533210053fc"]; 25 | 26 | expect(getRootFileNodeIds(fileNodeIds)).toEqual(expected); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/helpers/createFileNode.js: -------------------------------------------------------------------------------- 1 | const { createRemoteFileNode } = require("gatsby-source-filesystem"); 2 | const cacheKey = require("./cacheKey"); 3 | const saveToCache = require("./saveToCache"); 4 | 5 | async function createFileNode({ 6 | store, 7 | cache, 8 | createNode, 9 | createNodeId, 10 | url, 11 | node, 12 | }) { 13 | try { 14 | const fileNode = await createRemoteFileNode({ 15 | url, 16 | parentNodeId: node.id, 17 | store, 18 | cache, 19 | createNode, 20 | createNodeId, 21 | }); 22 | 23 | if (fileNode) { 24 | await saveToCache(cache, cacheKey(url), { 25 | fileNodeId: fileNode.id, 26 | updated: node.updated, 27 | }); 28 | return fileNode.id; 29 | } 30 | } catch (e) { 31 | console.error(`${e}\nSkipping...`); 32 | } 33 | } 34 | 35 | module.exports = createFileNode; 36 | -------------------------------------------------------------------------------- /src/helpers/addLocalFiles.js: -------------------------------------------------------------------------------- 1 | const getRootFileNodeIds = require("./getRootFileNodeIds"); 2 | const getNonRootFileNodeIds = require("./getNonRootFileNodeIds"); 3 | 4 | function addLocalFiles(node, fileNodeIds) { 5 | const rootFileNodeIds = getRootFileNodeIds(fileNodeIds); 6 | const nonRootFileNodeIds = getNonRootFileNodeIds(fileNodeIds); 7 | const nodeWithLocalFiles = Object.assign(node, { 8 | localFiles___NODE: rootFileNodeIds, 9 | }); 10 | 11 | if (!nonRootFileNodeIds.length) { 12 | return nodeWithLocalFiles; 13 | } 14 | 15 | nonRootFileNodeIds.forEach((fileNodeId) => { 16 | nodeWithLocalFiles[fileNodeId.location].localFiles___NODE = []; 17 | }); 18 | 19 | nonRootFileNodeIds.forEach((fileNodeId) => { 20 | nodeWithLocalFiles[fileNodeId.location].localFiles___NODE.push( 21 | fileNodeId.id 22 | ); 23 | }); 24 | 25 | return nodeWithLocalFiles; 26 | } 27 | 28 | module.exports = addLocalFiles; 29 | -------------------------------------------------------------------------------- /src/__tests__/getNonRootFileNodeIds.js: -------------------------------------------------------------------------------- 1 | const getNonRootFileNodeIds = require("../helpers/getNonRootFileNodeIds"); 2 | 3 | describe("getNonRootFileNodeIds()", () => { 4 | test("returns sub-object file node ids", () => { 5 | const fileNodeIds = [ 6 | { 7 | location: "root", 8 | id: "8fa3f02d-5e34-5191-bf6a-7533210053fc", 9 | }, 10 | { 11 | location: "product", 12 | id: "67735a50-5109-51be-85b4-803f05d27797", 13 | }, 14 | { 15 | location: "product", 16 | id: "7bffbe3e-beed-5893-bc26-eaec9fc6d787", 17 | }, 18 | { 19 | location: "product", 20 | id: "b9c3ae18-78f9-5b31-8e6b-372de7b6102a", 21 | }, 22 | ]; 23 | 24 | const expected = [ 25 | { 26 | location: "product", 27 | id: "67735a50-5109-51be-85b4-803f05d27797", 28 | }, 29 | { 30 | location: "product", 31 | id: "7bffbe3e-beed-5893-bc26-eaec9fc6d787", 32 | }, 33 | { 34 | location: "product", 35 | id: "b9c3ae18-78f9-5b31-8e6b-372de7b6102a", 36 | }, 37 | ]; 38 | 39 | expect(getNonRootFileNodeIds(fileNodeIds)).toEqual(expected); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/StripeObject.js: -------------------------------------------------------------------------------- 1 | const stripeObjs = require("./stripeObjects.json"); 2 | 3 | class StripeObject { 4 | constructor(type) { 5 | const obj = stripeObjs.objects.find((o) => o.type === type); 6 | 7 | if (!obj) { 8 | throw new Error( 9 | `Unknown type: ${type} passed to StripeObject. This type is not supported.` 10 | ); 11 | } 12 | 13 | this.id = obj.id; 14 | this.product = obj.product; 15 | this.name = obj.name; 16 | this.type = obj.type; 17 | this.description = obj.description; 18 | this.canIterate = obj.canIterate; 19 | this.methodName = obj.methodName; 20 | this.methodArgs = obj.methodArgs; 21 | } 22 | 23 | objectPath(stripe) { 24 | let path = null; 25 | if (this.product) { 26 | path = stripe[this.product][this.name]; 27 | } else { 28 | path = stripe[this.name]; 29 | } 30 | 31 | return path; 32 | } 33 | 34 | node(createContentDigest, payload) { 35 | const node = { 36 | ...payload, 37 | id: payload.id || `Stripe${this.type}${this.id}`, 38 | parent: null, 39 | children: [], 40 | internal: { 41 | type: `Stripe${this.type}`, 42 | content: JSON.stringify(payload), 43 | contentDigest: createContentDigest(payload), 44 | description: this.description, 45 | }, 46 | }; 47 | 48 | return node; 49 | } 50 | } 51 | 52 | module.exports = StripeObject; 53 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: njosefbeck 7 | 8 | --- 9 | 10 | **Prerequisites** 11 | 12 | [ ] Put an X between the brackets on this line if you have done all of the following: 13 | * Read through the README fully. 14 | * Ensured you are running Node v.10 or above. 15 | * Made sure you're using at least Gatsby v.2.0.15. 16 | * Checked that your issue isn't already filed. 17 | 18 | **Describe the bug** 19 | A clear and concise description of what the bug is. 20 | 21 | **To Reproduce** 22 | Steps to reproduce the behavior: 23 | 1. Go to '...' 24 | 2. Click on '....' 25 | 3. Scroll down to '....' 26 | 4. See error 27 | 28 | **Expected behavior** 29 | A clear and concise description of what you expected to happen. 30 | 31 | **Screenshots** 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | **Versions (please complete the following information):** 35 | 36 | os: [version] 37 | node: [version] 38 | npm: [version] 39 | gatsby: [version] 40 | gatsby-source-stripe: [version] 41 | 42 | **Gatsby config:** 43 | 44 | Copy the portion of your Gatsby config for this plugin here. **Do not include your `secretKey`.** 45 | 46 | ```js 47 | { 48 | resolve: `gatsby-source-stripe`, 49 | options: { 50 | objects: ['Sku', 'Product', 'Customer'], 51 | secretKey: '...', 52 | downloadFiles: true, 53 | } 54 | } 55 | ``` 56 | 57 | **Additional context** 58 | Add any other context about the problem here. 59 | -------------------------------------------------------------------------------- /src/__tests__/extractUrls.test.js: -------------------------------------------------------------------------------- 1 | const extractUrls = require("../helpers/extractUrls"); 2 | 3 | describe("extractUrls()", () => { 4 | test("returns empty array when product has no images", () => { 5 | const node = { 6 | id: "prod_EyUMnCrvQMhw3b", 7 | object: "product", 8 | images: [], 9 | type: "good", 10 | updated: 1556536238, 11 | }; 12 | 13 | const expected = []; 14 | 15 | expect(extractUrls(node)).toEqual(expected); 16 | }); 17 | 18 | test("returns urls when product has images", () => { 19 | const node = { 20 | id: "prod_EyUMnCrvQMhw3b", 21 | object: "product", 22 | images: [ 23 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 24 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 25 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 26 | ], 27 | type: "good", 28 | updated: 1556536238, 29 | }; 30 | 31 | const expected = [ 32 | { 33 | location: "root", 34 | url: "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 35 | }, 36 | { 37 | location: "root", 38 | url: "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 39 | }, 40 | { 41 | location: "root", 42 | url: "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 43 | }, 44 | ]; 45 | 46 | expect(extractUrls(node)).toEqual(expected); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-source-stripe", 3 | "version": "4.0.0", 4 | "main": "index.js", 5 | "description": "Gatsby source plugin for building websites using Stripe as a data source", 6 | "scripts": { 7 | "prebuild": "npm test && del-cli '*.js' '!src/**/**.js' '!index.js'", 8 | "build": "babel src --out-dir . --copy-files && del-cli __tests__", 9 | "prepare": "cross-env NODE_ENV=production npm run build", 10 | "lint": "eslint src --ext .js", 11 | "format": "prettier --write src/**/**.js", 12 | "test": "jest", 13 | "watch:test": "jest --watch", 14 | "watch": "babel -w src --out-dir . --copy-files && del-cli __tests__" 15 | }, 16 | "keywords": [ 17 | "stripe", 18 | "gatsby", 19 | "gatsby-plugin", 20 | "gatsby-source-plugin" 21 | ], 22 | "author": "Nathan Beck (njosefbeck.com)", 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/njosefbeck/gatsby-source-stripe.git" 26 | }, 27 | "bugs": "https://github.com/njosefbeck/gatsby-source-stripe/issues", 28 | "license": "MIT", 29 | "engines": { 30 | "node": ">=14.15.0" 31 | }, 32 | "peerDependencies": { 33 | "gatsby": ">=4.0.0" 34 | }, 35 | "devDependencies": { 36 | "@babel/cli": "7.16.0", 37 | "@babel/core": "7.16.0", 38 | "@babel/preset-env": "7.16.4", 39 | "babel-eslint": "10.1.0", 40 | "cross-env": "7.0.3", 41 | "del-cli": "4.0.1", 42 | "eslint": "7.21.0", 43 | "eslint-config-prettier": "8.3.0", 44 | "eslint-plugin-import": "2.25.3", 45 | "eslint-plugin-prettier": "3.3.1", 46 | "jest": "27.3.1", 47 | "prettier": "2.4.1" 48 | }, 49 | "dependencies": { 50 | "gatsby-source-filesystem": "4.2.0", 51 | "stripe": "8.191.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/__tests__/shouldUseCachedVersion.test.js: -------------------------------------------------------------------------------- 1 | const shouldUseCachedVersion = require("../helpers/shouldUseCachedVersion"); 2 | 3 | describe("shouldUseCachedVersion()", () => { 4 | test("returns undefined when no cached file present", () => { 5 | const node = { 6 | id: "sku_Ew1GWVDLcI23bd", 7 | object: "sku", 8 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 9 | updated: 1555966756, 10 | }; 11 | 12 | const cachedFile = undefined; 13 | 14 | const expected = undefined; 15 | 16 | expect(shouldUseCachedVersion(cachedFile, node)).toBe(expected); 17 | }); 18 | 19 | test("returns true when cached file updated timestamp = fetched node updated timestamp", () => { 20 | const node = { 21 | id: "sku_Ew1GWVDLcI23bd", 22 | object: "sku", 23 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 24 | updated: 1555966756, 25 | }; 26 | 27 | const cachedFile = { 28 | fileNodeId: "71c34662-6557-5fe4-a2f0-931be50fb7c7", 29 | updated: 1555966756, 30 | }; 31 | 32 | const expected = true; 33 | 34 | expect(shouldUseCachedVersion(cachedFile, node)).toBe(expected); 35 | }); 36 | 37 | test("returns false when cached file updated timestamp != fetched node updated timestamp", () => { 38 | const node = { 39 | id: "sku_Ew1GWVDLcI23bd", 40 | object: "sku", 41 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 42 | updated: 1556748059, 43 | }; 44 | 45 | const cachedFile = { 46 | fileNodeId: "71c34662-6557-5fe4-a2f0-931be50fb7c7", 47 | updated: 1555966756, 48 | }; 49 | 50 | const expected = false; 51 | 52 | expect(shouldUseCachedVersion(cachedFile, node)).toBe(expected); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /src/FileDownloadService.js: -------------------------------------------------------------------------------- 1 | const extractUrls = require("./helpers/extractUrls"); 2 | const checkCache = require("./helpers/checkCache"); 3 | const createFileNode = require("./helpers/createFileNode"); 4 | const hasFilesToDownload = require("./helpers/hasFilesToDownload"); 5 | const addLocalFiles = require("./helpers/addLocalFiles"); 6 | 7 | class FileDownloadService { 8 | constructor({ store, cache, createNode, createNodeId, touchNode, getNode }) { 9 | this.store = store; 10 | this.cache = cache; 11 | this.createNode = createNode; 12 | this.createNodeId = createNodeId; 13 | this.touchNode = touchNode; 14 | this.getNode = getNode; 15 | } 16 | 17 | async downloadAndAddTo(node) { 18 | switch (node.object) { 19 | case "product": 20 | case "sku": 21 | case "price": 22 | return this.downloadFiles(node); 23 | default: 24 | return node; 25 | } 26 | } 27 | 28 | async downloadFiles(node) { 29 | if (!hasFilesToDownload(node)) { 30 | return node; 31 | } 32 | 33 | const urls = extractUrls(node); 34 | if (!urls.length) { 35 | return node; 36 | } 37 | 38 | const fileNodeIds = []; 39 | 40 | for (const url of urls) { 41 | const cachedFileNodeId = await checkCache({ 42 | cache: this.cache, 43 | getNode: this.getNode, 44 | touchNode: this.touchNode, 45 | url: url.url, 46 | node, 47 | }); 48 | 49 | if (cachedFileNodeId) { 50 | fileNodeIds.push({ location: url.location, id: cachedFileNodeId }); 51 | continue; 52 | } 53 | 54 | const fileNodeId = await createFileNode({ 55 | store: this.store, 56 | cache: this.cache, 57 | createNode: this.createNode, 58 | createNodeId: this.createNodeId, 59 | url: url.url, 60 | node, 61 | }); 62 | 63 | if (fileNodeId) { 64 | fileNodeIds.push({ location: url.location, id: fileNodeId }); 65 | } 66 | } 67 | 68 | if (!fileNodeIds.length) { 69 | return node; 70 | } 71 | 72 | const nodeWithLocalFiles = addLocalFiles(node, fileNodeIds); 73 | return nodeWithLocalFiles; 74 | } 75 | } 76 | 77 | module.exports = FileDownloadService; 78 | -------------------------------------------------------------------------------- /src/__tests__/hasFilesToDownload.test.js: -------------------------------------------------------------------------------- 1 | const hasFilesToDownload = require("../helpers/hasFilesToDownload"); 2 | 3 | describe("hasFilesToDownload()", () => { 4 | test("returns true when node has image", () => { 5 | const node = { 6 | id: "sku_Ew1GWVDLcI23bd", 7 | object: "sku", 8 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 9 | product: "prod_BosWT9EsdzgjPn", 10 | updated: 1555966756, 11 | parent: null, 12 | children: [], 13 | internal: {}, 14 | }; 15 | 16 | const expected = true; 17 | 18 | expect(hasFilesToDownload(node)).toBe(expected); 19 | }); 20 | 21 | test("returns false when node has no image", () => { 22 | const node = { 23 | id: "sku_Ew1GWVDLcI23bd", 24 | object: "sku", 25 | image: null, 26 | product: "prod_BosWT9EsdzgjPn", 27 | updated: 1555966756, 28 | parent: null, 29 | children: [], 30 | internal: {}, 31 | }; 32 | 33 | const expected = false; 34 | 35 | expect(hasFilesToDownload(node)).toBe(expected); 36 | }); 37 | 38 | test("returns true when node has images", () => { 39 | const node = { 40 | id: "prod_EyUMnCrvQMhw3b", 41 | object: "product", 42 | images: [ 43 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 44 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 45 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 46 | ], 47 | type: "good", 48 | updated: 1556536238, 49 | }; 50 | 51 | const expected = true; 52 | 53 | expect(hasFilesToDownload(node)).toBe(expected); 54 | }); 55 | 56 | test("returns false when node has no images", () => { 57 | const node = { 58 | id: "prod_EyUMnCrvQMhw3b", 59 | object: "product", 60 | images: [], 61 | type: "good", 62 | updated: 1556536238, 63 | }; 64 | 65 | const expected = false; 66 | 67 | expect(hasFilesToDownload(node)).toBe(expected); 68 | }); 69 | 70 | test("returns true when only subnode has image", () => { 71 | const productNode = { 72 | id: "prod_EyUMnCrvQMhw3b", 73 | object: "product", 74 | images: [ 75 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 76 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 77 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 78 | ], 79 | type: "good", 80 | updated: 1556536238, 81 | }; 82 | 83 | const node = { 84 | id: "sku_Ew1GWVDLcI23bd", 85 | object: "sku", 86 | image: null, 87 | product: productNode, 88 | updated: 1555966756, 89 | parent: null, 90 | children: [], 91 | internal: {}, 92 | }; 93 | 94 | const expected = true; 95 | 96 | expect(hasFilesToDownload(node)).toBe(expected); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /src/gatsby-node.js: -------------------------------------------------------------------------------- 1 | const Stripe = require("stripe"); 2 | const StripeObject = require("./StripeObject"); 3 | const FileDownloadService = require("./FileDownloadService"); 4 | const checkForSecretKey = require("./helpers/checkForSecretKey"); 5 | const checkForStripeObjects = require("./helpers/checkForStripeObjects"); 6 | 7 | exports.sourceNodes = async ( 8 | { actions, cache, createNodeId, createContentDigest, getNode, store }, 9 | { downloadFiles = false, objects = [], secretKey = "" } 10 | ) => { 11 | const { createNode, touchNode } = actions; 12 | 13 | checkForStripeObjects(objects); 14 | checkForSecretKey(secretKey); 15 | 16 | const stripe = new Stripe(secretKey, { 17 | appInfo: { 18 | name: "Gatsby.js Stripe Source Plugin", 19 | version: "3.0.7", 20 | url: "https://github.com/njosefbeck/gatsby-source-stripe", 21 | }, 22 | }); 23 | 24 | // Initialize stripeObjects based on gatsby plugin objects 25 | const stripeObjects = objects.map((type) => new StripeObject(type)); 26 | 27 | for (const stripeObj of stripeObjects) { 28 | /* 29 | * Outputs the stripe object's path, to allow us to 30 | * get to the proper method 31 | * 32 | * Example outputs: 33 | * const path = stripe['customers'] 34 | * const path = stripe['terminal']['readers'] 35 | */ 36 | const path = stripeObj.objectPath(stripe); 37 | 38 | /* 39 | * Some Stripe objects, like "Balance" aren't iterable. 40 | * The canIterate key is set manually in stripeObjects.json 41 | * based on testing the different object types. 42 | */ 43 | if (!stripeObj.canIterate) { 44 | let payload = await path[stripeObj.methodName](stripeObj.methodArgs); 45 | const node = stripeObj.node(createContentDigest, payload); 46 | createNode(node); 47 | continue; 48 | } 49 | 50 | /* 51 | * Use for - await - of as per the Stripe.js Node documentation 52 | * for auto pagination purposes 53 | * 54 | * path[stripeObj.methodName](stripeObj.methodArgs) translates to 55 | * something like the following, depending on the object types 56 | * passed in the config: 57 | * 58 | * stripe['customers']['list']({ "expand": "data.default_source" }) 59 | */ 60 | for await (let payload of path[stripeObj.methodName]( 61 | stripeObj.methodArgs 62 | )) { 63 | /** 64 | * Leaving this in here as a reminder that, depending on what the Gatsby.js 65 | * team says, I'll need to deal with event objects for skus and products having 66 | * the same attributes key, but having different data types (i.e. sku.attributes 67 | * is an object, and product.attributes is an array). 68 | */ 69 | /* 70 | if (payload.object == 'event' && Array.isArray(payload.data.object.attributes)) { 71 | console.log(payload.data.object.object); 72 | console.log(payload.data.object.attributes); 73 | } 74 | */ 75 | 76 | let node = stripeObj.node(createContentDigest, payload); 77 | 78 | if (downloadFiles) { 79 | const downloadService = new FileDownloadService({ 80 | store, 81 | cache, 82 | createNode, 83 | createNodeId, 84 | touchNode, 85 | getNode, 86 | }); 87 | node = await downloadService.downloadAndAddTo(node); 88 | } 89 | 90 | createNode(node); 91 | } 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /src/__tests__/addLocalFiles.test.js: -------------------------------------------------------------------------------- 1 | const addLocalFiles = require("../helpers/addLocalFiles"); 2 | 3 | describe("addLocalFiles()", () => { 4 | test.each(["sku", "price"])( 5 | "adds local files from %s to root node", 6 | (object) => { 7 | const node = { 8 | id: `${object}_Ew1GWVDLcI23bd`, 9 | object, 10 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 11 | product: "prod_BosWT9EsdzgjPn", 12 | }; 13 | 14 | const fileNodeIds = [ 15 | { 16 | location: "root", 17 | id: "8fa3f02d-5e34-5191-bf6a-7533210053fc", 18 | }, 19 | ]; 20 | 21 | const expected = { 22 | ...node, 23 | localFiles___NODE: ["8fa3f02d-5e34-5191-bf6a-7533210053fc"], 24 | }; 25 | 26 | expect(addLocalFiles(node, fileNodeIds)).toEqual(expected); 27 | } 28 | ); 29 | 30 | test.each(["sku", "price"])( 31 | "adds local files from %s to root and sub-nodes", 32 | (object) => { 33 | const node = { 34 | id: `${object}_Ew1GWVDLcI23bd`, 35 | object, 36 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 37 | product: { 38 | id: "prod_EyUMnCrvQMhw3b", 39 | object: "product", 40 | images: [ 41 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 42 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 43 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 44 | ], 45 | type: "good", 46 | updated: 1556536238, 47 | }, 48 | }; 49 | 50 | const fileNodeIds = [ 51 | { 52 | location: "root", 53 | id: "8fa3f02d-5e34-5191-bf6a-7533210053fc", 54 | }, 55 | { 56 | location: "product", 57 | id: "67735a50-5109-51be-85b4-803f05d27797", 58 | }, 59 | { 60 | location: "product", 61 | id: "7bffbe3e-beed-5893-bc26-eaec9fc6d787", 62 | }, 63 | { 64 | location: "product", 65 | id: "b9c3ae18-78f9-5b31-8e6b-372de7b6102a", 66 | }, 67 | ]; 68 | 69 | const expected = { 70 | id: `${object}_Ew1GWVDLcI23bd`, 71 | object, 72 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 73 | product: { 74 | id: "prod_EyUMnCrvQMhw3b", 75 | object: "product", 76 | images: [ 77 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 78 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 79 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 80 | ], 81 | type: "good", 82 | updated: 1556536238, 83 | localFiles___NODE: [ 84 | "67735a50-5109-51be-85b4-803f05d27797", 85 | "7bffbe3e-beed-5893-bc26-eaec9fc6d787", 86 | "b9c3ae18-78f9-5b31-8e6b-372de7b6102a", 87 | ], 88 | }, 89 | localFiles___NODE: ["8fa3f02d-5e34-5191-bf6a-7533210053fc"], 90 | }; 91 | 92 | expect(addLocalFiles(node, fileNodeIds)).toEqual(expected); 93 | } 94 | ); 95 | }); 96 | -------------------------------------------------------------------------------- /src/__tests__/StripeObject.test.js: -------------------------------------------------------------------------------- 1 | const StripeObject = require("../StripeObject"); 2 | const crypto = require(`crypto`); 3 | 4 | /** 5 | * createContentDigest() implementation taken from: 6 | * https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/create-content-digest.js 7 | */ 8 | const createContentDigest = (input) => { 9 | const content = typeof input !== `string` ? JSON.stringify(input) : input; 10 | 11 | return crypto.createHash(`md5`).update(content).digest(`hex`); 12 | }; 13 | 14 | describe("StripeObject", () => { 15 | describe("constructor", () => { 16 | test("throws error when given unknown type", () => { 17 | const type = "Skyu"; 18 | const error = `Unknown type: ${type} passed to StripeObject. This type is not supported.`; 19 | 20 | expect(() => new StripeObject(type)).toThrow(error); 21 | }); 22 | 23 | test("initializes object given a known type", () => { 24 | const type = "Sku"; 25 | const instance = new StripeObject("Sku"); 26 | 27 | expect(instance.name).toBe("skus"); 28 | expect(instance.type).toBe(type); 29 | expect(instance.methodName).toBe("list"); 30 | }); 31 | }); 32 | 33 | describe("objectPath()", () => { 34 | const stripe = { 35 | orders: { 36 | list: () => "Listing out orders...", 37 | }, 38 | issuing: { 39 | authorizations: { 40 | list: () => "Listing issuing authorizations...", 41 | }, 42 | }, 43 | }; 44 | 45 | test("returns top-level stripe-node resource object", () => { 46 | const instance = new StripeObject("Order"); 47 | const resourceObject = instance.objectPath(stripe); 48 | 49 | expect(resourceObject.list()).toBe("Listing out orders..."); 50 | }); 51 | 52 | test("returns namespaced stripe-node resource object", () => { 53 | const instance = new StripeObject("IssuingAuthorization"); 54 | const resourceObject = instance.objectPath(stripe); 55 | 56 | expect(resourceObject.list()).toBe("Listing issuing authorizations..."); 57 | }); 58 | }); 59 | 60 | describe("node()", () => { 61 | test("creates Gatsby node from stripe-node resource payload", () => { 62 | const instance = new StripeObject("Sku"); 63 | const payload = { 64 | id: "sku_Ew1GWVDLcI23bd", 65 | object: "sku", 66 | active: true, 67 | attributes: { 68 | size: "Medium", 69 | gender: "Unisex", 70 | }, 71 | created: 1555966756, 72 | currency: "usd", 73 | image: null, 74 | inventory: { 75 | quantity: null, 76 | type: "infinite", 77 | value: null, 78 | }, 79 | livemode: false, 80 | metadata: {}, 81 | package_dimensions: null, 82 | price: 1500, 83 | product: "prod_BosWT9EsdzgjPn", 84 | updated: 1555966756, 85 | }; 86 | const expected = { 87 | ...payload, 88 | id: "sku_Ew1GWVDLcI23bd", 89 | parent: null, 90 | children: [], 91 | internal: { 92 | type: `Stripe${instance.type}`, 93 | content: JSON.stringify(payload), 94 | contentDigest: createContentDigest(payload), 95 | description: instance.description, 96 | }, 97 | }; 98 | 99 | expect(instance.node(createContentDigest, payload)).toEqual(expected); 100 | }); 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at njosefbeck@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /src/__tests__/extractChildUrls.test.js: -------------------------------------------------------------------------------- 1 | const extractChildUrls = require("../helpers/extractChildUrls"); 2 | 3 | describe("extractChildUrls()", () => { 4 | test.each(["sku", "price"])( 5 | "returns empty array when %s node has no image", 6 | (object) => { 7 | const node = { 8 | id: `${object}_Ew1GWVDLcI23bd`, 9 | object, 10 | image: null, 11 | product: "prod_BosWT9EsdzgjPn", 12 | updated: 1555966756, 13 | parent: null, 14 | children: [], 15 | internal: {}, 16 | }; 17 | 18 | const expected = []; 19 | 20 | expect(extractChildUrls(node)).toEqual(expected); 21 | } 22 | ); 23 | 24 | test.each(["sku", "price"])( 25 | "returns product image urls even when %s has no image", 26 | (object) => { 27 | const node = { 28 | id: `${object}_Ew1GWVDLcI23bd`, 29 | object, 30 | image: null, 31 | product: { 32 | id: "prod_EyUMnCrvQMhw3b", 33 | object: "product", 34 | images: [ 35 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 36 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 37 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 38 | ], 39 | type: "good", 40 | updated: 1556536238, 41 | }, 42 | updated: 1555966756, 43 | parent: null, 44 | children: [], 45 | internal: {}, 46 | }; 47 | 48 | const expected = [ 49 | { 50 | location: "product", 51 | url: "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 52 | }, 53 | { 54 | location: "product", 55 | url: "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 56 | }, 57 | { 58 | location: "product", 59 | url: "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 60 | }, 61 | ]; 62 | 63 | expect(extractChildUrls(node)).toEqual(expected); 64 | } 65 | ); 66 | 67 | test.each(["sku", "price"])("returns %s node image url", (object) => { 68 | const node = { 69 | id: `${object}_Ew1GWVDLcI23bd`, 70 | object, 71 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 72 | product: "prod_BosWT9EsdzgjPn", 73 | updated: 1555966756, 74 | parent: null, 75 | children: [], 76 | internal: {}, 77 | }; 78 | 79 | const expected = [ 80 | { 81 | location: "root", 82 | url: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 83 | }, 84 | ]; 85 | 86 | expect(extractChildUrls(node)).toEqual(expected); 87 | }); 88 | 89 | test.each(["sku", "price"])( 90 | "returns %s node image url and product image urls", 91 | (object) => { 92 | const node = { 93 | id: `${object}_Ew1GWVDLcI23bd`, 94 | object, 95 | image: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 96 | product: { 97 | id: "prod_EyUMnCrvQMhw3b", 98 | object: "product", 99 | images: [ 100 | "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 101 | "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 102 | "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 103 | ], 104 | type: "good", 105 | updated: 1556536238, 106 | }, 107 | updated: 1555966756, 108 | parent: null, 109 | children: [], 110 | internal: {}, 111 | }; 112 | 113 | const expected = [ 114 | { 115 | location: "root", 116 | url: "https://files.stripe.com/files/f_test_SWXjBddZpg3sRYV6R9yVBpu3", 117 | }, 118 | { 119 | location: "product", 120 | url: "https://images.ctfassets.net/wubeq4r3otg9/4z8w2ARN4Qk2qUKeWIaMa6/d75a0e74446c6e1df1155b754b92372d/black.png", 121 | }, 122 | { 123 | location: "product", 124 | url: "https://images.ctfassets.net/wubeq4r3otg9/3q7n4GuUhWaQY82Iw64KEq/9dffaeb403227171594c2dda9a5df333/rainbow.png", 125 | }, 126 | { 127 | location: "product", 128 | url: "https://njosefbeck.github.io/lets-watch-sailormoon/static/media/sailor_moon_logo.1630c2ed.png", 129 | }, 130 | ]; 131 | 132 | expect(extractChildUrls(node)).toEqual(expected); 133 | } 134 | ); 135 | }); 136 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to gatsby-source-stripe 2 | 3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: 4 | 5 | The following is a set of guidelines for contributing to the gatsby-source-stripe plugin. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | ## Code of Conduct 8 | 9 | This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [njosefbeck@gmail.com](mailto:njosefbeck@gmail.com). 10 | 11 | ## What should I know before I get started? 12 | 13 | Before contributing to this project, take the time to read through the [README](README.md). Additionally, be sure you are familiar with [Gatsby](https://gatsbyjs.org). Specifically, read through the Gatsby documentation on [creating a source plugin](https://www.gatsbyjs.org/docs/create-source-plugin/). 14 | 15 | ## How Can I Contribute? 16 | 17 | ### Reporting Bugs 18 | 19 | This section guides you through submitting a bug report. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports. 20 | 21 | Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](ISSUE_TEMPLATE.md), the information it asks for helps us resolve issues faster. 22 | 23 | > **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one. 24 | 25 | #### Before Submitting A Bug Report 26 | 27 | * **Check the [README](README.md).** You might be running an un-supported version of Node or Gatsby with this plugin. The README gives details on what versions the plugin works with. 28 | 29 | #### How Do I Submit A (Good) Bug Report? 30 | 31 | Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information by filling in [the template](ISSUE_TEMPLATE.md). 32 | 33 | Explain the problem and include additional details to help maintainers reproduce the problem: 34 | 35 | * **Use a clear and descriptive title** for the issue to identify the problem. 36 | * **Describe the exact steps which reproduce the problem** in as many details as possible. 37 | * **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). 38 | * **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. 39 | * **Explain which behavior you expected to see instead and why.** 40 | * **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. If you use the keyboard while following the steps, **record the GIF with the [Keybinding Resolver](https://github.com/atom/keybinding-resolver) shown**. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. 41 | * **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below. 42 | 43 | Provide more context by answering these questions: 44 | 45 | * **Did the problem start happening recently** (e.g. after updating to a new version of gatsby-source-stripe) or was this always a problem? 46 | * If the problem started happening recently, **can you reproduce the problem in an older version of Atom?** What's the most recent version in which the problem doesn't happen? 47 | * **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. 48 | 49 | ### Suggesting Enhancements 50 | 51 | This section guides you through submitting an enhancement suggestion, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions. 52 | 53 | #### Before Submitting An Enhancement Suggestion 54 | 55 | * **Check the [CHANGELOG](CHANGELOG.md)** unreleased section to see if your enhancement is already listed, but just not released yet. 56 | * **Perform a search** through the issues to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. 57 | 58 | #### How Do I Submit A (Good) Enhancement Suggestion? 59 | 60 | Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information by filling in [the template](ISSUE_TEMPLATE.md). 61 | 62 | * **Use a clear and descriptive title** for the issue to identify the suggestion. 63 | * **Provide a step-by-step description of the suggested enhancement** in as many details as possible. 64 | * **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). 65 | * **Explain why this enhancement would be useful** to most gatsby-source-stripe users. 66 | 67 | ### Your First Code Contribution 68 | 69 | Unsure where to begin contributing? You can start by looking through the `help-wanted` issues: 70 | 71 | * [Help wanted issues][help-wanted] - issues which should be a bit more involved than `beginner` issues. 72 | 73 | ### Coding Guidelines 74 | 75 | Several notes to keep in mind as you add code to this project. 76 | 77 | * If you add any dependencies to the project via package.json, keep in mind that we only use absolute versions of packages. For example, `2.2.6` instead of `^2.2.6`. This helps maintain consistency across npm installs. Our `.npmrc` file also helps enforce this. 78 | * For commits, we prefer the active voice / imperative mood. For more info (and a great article), check [here](https://chris.beams.io/posts/git-commit/#imperative) 79 | * Be sure to use the `npm run lint` and `npm run format` commands often, but especially before submitting a PR. 80 | 81 | ## Attribution 82 | 83 | This document is an edited version of [Atom's CONTRIBUTING.md](https://github.com/atom/atom/blob/master/CONTRIBUTING.md). 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gatsby-source-stripe 2 | 3 | Source plugin for pulling in data from the [Stripe API](https://stripe.com/docs/api). Current with Stripe API version [2020-08-27](https://stripe.com/docs/upgrades#2020-08-27). 4 | 5 | This plugin is a source plugin, so it brings in your Stripe data. Use cases for this Stripe source plugin: 6 | 7 | * Create an ecommerce store. This plugin allows you to bring your product and SKU data into your Gatsby site at build time to be [used with Stripe Checkout](https://www.gatsbyjs.org/tutorial/ecommerce-tutorial/#example-2-import-skus-via-source-plugin). 8 | * Create various dashboards around customers, invoices, etc. Use this plugin to bring in any of the data types listed below. 9 | 10 | Do you use this plugin in your Gatsby project? Let us know and we can add it here as an example! 11 | 12 | Check out the [CHANGELOG](https://github.com/njosefbeck/gatsby-source-stripe/blob/master/CHANGELOG.md) for past and upcoming updates. 13 | 14 | ## Install 15 | 16 | `npm install gatsby-source-stripe` 17 | 18 | or 19 | 20 | `yarn add gatsby-source-stripe` 21 | 22 | ## How to use 23 | 24 | **NOTE: You must be using Gatsby version 4.0.0 or greater.** 25 | 26 | In the plugin options objects' array, specify the object types you would like to get data for. For example, if you'd like to get the lists of data for your Skus and Products, your objects array would look like this: `['Product', 'Sku']`. 27 | 28 | Additionally, only include your Stripe secret key via a [.env](https://www.npmjs.com/package/dotenv) file that is not version-controlled. We don't want your key ending up in your version-controlled source code! For enhanced security, you can also create a [restricted API key](https://stripe.com/docs/keys#limiting-access-with-restricted-api-keys) in your Stripe Developer Dashboard. Since this plugin only ever sources data, you can restrict `All core resources` to `Read only`, and even turn off access to certain resources that you know you don't use. 29 | 30 | Enable [downloading files](#downloading-files) associated with your Stripe Skus and Products by setting `downloadFiles` to true. 31 | 32 | Example: 33 | 34 | ```javascript 35 | // In your gatsby-config.js 36 | plugins: [ 37 | { 38 | resolve: `gatsby-source-stripe`, 39 | options: { 40 | objects: ['Balance', 'BalanceTransaction', 'Product', 'ApplicationFee', 'Sku', 'Subscription'], 41 | secretKey: 'stripe_secret_key_here', 42 | downloadFiles: true, 43 | } 44 | } 45 | ] 46 | ``` 47 | 48 | ### Supported List of Types 49 | 50 | Below is a table with a list of the Stripe types supported in the options' objects array, as well as what Stripe API method the type maps to, and any other additional notes. 51 | 52 | | Type | Stripe API Method | Notes | 53 | | --- | --- | --- | 54 | | Balance | [stripe.balance.retrieve()](https://stripe.com/docs/api/balance/balance_retrieve?lang=node) | Not iterable | 55 | | BalanceTransaction | [stripe.balanceTransactions.list()](https://stripe.com/docs/api/balance/balance_history?lang=node) | None | 56 | | Charge | [stripe.charges.list()](https://stripe.com/docs/api/charges/list?lang=node) | None | 57 | | Customer | [stripe.customers.list()](https://stripe.com/docs/api/customers/list?lang=node) | None | 58 | | Dispute | [stripe.disputes.list()](https://stripe.com/docs/api/disputes/list?lang=node) | None | 59 | | Event | [stripe.events.list()](https://stripe.com/docs/api/events/list?lang=node) | None | 60 | | File | [stripe.files.list()](https://stripe.com/docs/api/files/list?lang=node) | None | 61 | | FileLink | [stripe.fileLinks.list()](https://stripe.com/docs/api/file_links/list?lang=node) | None | 62 | | PaymentIntent | [stripe.paymentIntents.list()](https://stripe.com/docs/api/payment_intents/list?lang=node) | None | 63 | | Payout | [stripe.payouts.list()](https://stripe.com/docs/api/payouts/list?lang=node) | None | 64 | | Product | [stripe.products.list()](https://stripe.com/docs/api/products/list?lang=node) | None | 65 | | Refund | [stripe.refunds.list()](https://stripe.com/docs/api/refunds/list?lang=node) | None | 66 | | Coupon | [stripe.coupons.list()](https://stripe.com/docs/api/coupons/list?lang=node) | None | 67 | | Invoice | [stripe.invoices.list()](https://stripe.com/docs/api/invoices/list?lang=node) | None | 68 | | InvoiceItem | [stripe.invoiceItems.list()](https://stripe.com/docs/api/invoiceitems/list?lang=node) | None | 69 | | Plan | [stripe.plans.list()](https://stripe.com/docs/api/plans/list?lang=node) | None | 70 | | Subscription | [stripe.subscriptions.list()](https://stripe.com/docs/api/subscriptions/list?lang=node) | None | 71 | | Account | [stripe.accounts.list()](https://stripe.com/docs/api/accounts/list?lang=node) | None | 72 | | ApplicationFee | [stripe.applicationFees.list()](https://stripe.com/docs/api/application_fees/list?lang=node) | None | 73 | | CountrySpec | [stripe.countrySpecs.list()](https://stripe.com/docs/api/country_specs/list?lang=node) | None | 74 | | TopUp | [stripe.topUps.list()](https://stripe.com/docs/api/topups/list?lang=node) | None | 75 | | Transfer | [stripe.transfers.list()](https://stripe.com/docs/api/transfers/list?lang=node) | None | 76 | | IssuingAuthorization | [stripe.issuing.authorizations.list()](https://stripe.com/docs/api/issuing/authorizations/list?lang=node) | Issuing is in closed beta. Can only get data if you have access to the beta. | 77 | | IssuingCardholder | [stripe.issuing.cardholders.list()](https://stripe.com/docs/api/issuing/cardholders/list?lang=node) | Issuing is in closed beta. Can only get data if you have access to the beta. | 78 | | IssuingCard | [stripe.issuing.cards.list()](https://stripe.com/docs/api/issuing/cards/list?lang=node) | Issuing is in closed beta. Can only get data if you have access to the beta. | 79 | | IssuingDispute | [stripe.issuing.disputes.list()](https://stripe.com/docs/api/issuing/disputes/list?lang=node) | Issuing is in closed beta. Can only get data if you have access to the beta. | 80 | | IssuingTransaction | [stripe.issuing.transactions.list()](https://stripe.com/docs/api/issuing/transactions/list?lang=node) | Issuing is in closed beta. Can only get data if you have access to the beta. | 81 | | TerminalLocation | [stripe.terminal.locations.list()](https://stripe.com/docs/api/terminal/locations/list?lang=node) | None | 82 | | TerminalReader | [stripe.terminal.readers.list()](https://stripe.com/docs/api/terminal/readers/list?lang=node) | None | 83 | | Order | [stripe.orders.list()](https://stripe.com/docs/api/orders/list?lang=node) | None | 84 | | OrderReturn | [stripe.orderReturns.list()](https://stripe.com/docs/api/order_returns/list?lang=node) | None | 85 | | Sku | [stripe.skus.list()](https://stripe.com/docs/api/skus/list?lang=node) | None | 86 | | SigmaScheduledQueryRun | [stripe.sigma.ScheduledQueryRuns.list()](https://stripe.com/docs/api/sigma/scheduled_queries/list?lang=node) | Only works with live secret keys, not test keys | 87 | | WebhookEndpoint | [stripe.webhookEndpoints.list()](https://stripe.com/docs/api/webhook_endpoints/list?lang=node) | None | 88 | | CreditNote | [stripe.creditNotes.list()](https://stripe.com/docs/api/credit_notes/list?lang=node) | None | 89 | | Review | [stripe.reviews.list()](https://stripe.com/docs/api/radar/reviews/list?lang=node) | None | 90 | | Session | [stripe.checkout.sessions.list()](https://stripe.com/docs/api/checkout/sessions/list?lang=node) | None | 91 | | Price | [stripe.prices.list()](https://stripe.com/docs/api/prices/list?lang=node) | None | 92 | | TaxRate | [stripe.taxRates.list()](https://stripe.com/docs/api/tax_rates/list?lang=node) | None | 93 | | SetupIntent | [stripe.setupIntents.list()](https://stripe.com/docs/api/setup_intents/list?lang=node) | None | 94 | | PromotionCode | [stripe.promotionCodes.list()](https://stripe.com/docs/api/promotion_codes/list?lang=node) | None | 95 | | SubscriptionSchedule | [stripe.subscriptionSchedules.list()](https://stripe.com/docs/api/subscription_schedules/list?lang=node) | None | 96 | | EarlyFraudWarning | [stripe.radar.earlyFraudWarnings.list()](https://stripe.com/docs/api/radar/early_fraud_warnings/list?lang=node) | None | 97 | 98 | 99 | ## Expanding Objects 100 | 101 | Expanding all Stripe objects is tricky, as some objects have a lot of nested sub-objects to expand! We've tried to auto-expand as much of the top-level objects as possible. You can peruse a list of what is expanded per object in the `stripeObjects.json` file. If we're missing something that you'd like expanded, please create an issue! 102 | 103 | ## Auto-pagination 104 | 105 | **NOTE: Due to stripe-node's [autopagination recommendations](https://github.com/stripe/stripe-node#auto-pagination) this plugin has been tested against v10.13.0 and later. If you experience any issues with earlier versions of Node, please first consider upgrading your Node version. Otherwise, file an issue and we'll try to resolve!** 106 | 107 | All list responses are fully paginated. 108 | 109 | ## Downloading Files 110 | 111 | Setting `downloadFiles: true` in the plugin configuration enables downloading of images on Sku and Product objects. A Gatsby [File node](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-filesystem#how-to-query) is created for each downloaded file, and references are placed on the `localFiles` field of their Stripe nodes. 112 | 113 | You can give these File nodes to plugins like [gatsby-image](https://using-gatsby-image.gatsbyjs.org/) to create responsive images and/or [gatsby-transformer-sharp](https://image-processing.gatsbyjs.org/) to process images at build. 114 | 115 | ## How to query with Skus 116 | 117 | **NOTE: For the example below, be sure that you actually have products with SKUs in your Stripe account, otherwise you will get an error saying: `Cannot query field "allStripeSku" on type "Query"`. With the update to Prices API, the Sku/Order API is now deprecated. If you have an account that uses Prices, see [How to query with Prices](#how-to-query-with-prices).** 118 | 119 | Below is an example query for fetching all your Stripe SKUs. Note that the `localFiles` will not be there if you didn't specify `downloadFiles: true` in the plugin options. 120 | 121 | ```graphql 122 | { 123 | allStripeSku { 124 | edges { 125 | node { 126 | id, 127 | active, 128 | localFiles { 129 | id 130 | } 131 | product { 132 | id 133 | } 134 | } 135 | } 136 | } 137 | } 138 | ``` 139 | 140 | Just replace "Sku" with any of the types used in your config `objects` array. 141 | 142 | You can also query for a specific Stripe object like this: 143 | 144 | ```graphql 145 | { 146 | stripeCustomer(id: { eq: "customer_id_here" }) { 147 | id, 148 | name 149 | } 150 | } 151 | ``` 152 | 153 | When using GraphiQL, click on "Docs" in the top-right corner of the screen to explore all of the Stripe data being brought in, including their schemas. Additionally, check out Gatsby's handy [GraphQL Reference](https://www.gatsbyjs.org/docs/graphql-reference/) for information about filtering, sorting, etc. 154 | 155 | 156 | ## How to query with Prices 157 | 158 | **NOTE: With the update to Prices API, the Sku/Order API is now deprecated. If you still have an account that uses Skus, see [How to query with Skus](#how-to-query-with-skus).** 159 | 160 | Below is an example query for fetching all Stripe Prices. 161 | 162 | ```graphql 163 | { 164 | allStripePrice { 165 | edges { 166 | node { 167 | id, 168 | object, 169 | active, 170 | billing_scheme, 171 | product, 172 | type, 173 | livemode, 174 | unit_amount, 175 | unit_amount_decimal, 176 | currency 177 | } 178 | } 179 | } 180 | } 181 | ``` 182 | 183 | You can add or remove any of the nodes to query for what you need. 184 | 185 | ## Gotchas 186 | 187 | This section outlines common questions and issues that other user's have run into and how they were resolved. 188 | 189 | ### "My Subscription objects aren't showing up in my GraphQL results" 190 | 191 | This issue comes up when trying to get back all SKU for your account, expecting that products of type `service` will also be present. As Subscriptions (products of type `service`) don't have SKUs, they won't show up in the SKU results. To get back those, you must also query for `Product` objects. 192 | 193 | Thus, for those who have Subscription products, we recommend you have an `objects` array like below. 194 | 195 | ```javascript 196 | // In your gatsby-config.js 197 | plugins: [ 198 | { 199 | resolve: `gatsby-source-stripe`, 200 | options: { 201 | objects: ['Sku', 'Product'], 202 | secretKey: 'stripe_secret_key_here', 203 | downloadFiles: true, 204 | } 205 | } 206 | ] 207 | ``` 208 | 209 | ## Develop 210 | 211 | Would you like to help maintain this project? We would love your help! Checkout [issues](https://github.com/njosefbeck/gatsby-source-stripe/issues) and look for tags labeled `help wanted`. Also please check out our [CODE OF CONDUCT](CODE_OF_CONDUCT.md) and our [CONTRIBUTING](CONTRIBUTING.md) documents. 212 | 213 | To set up the project locally, follow these steps: 214 | 215 | 1) Fork the repo and pull it down locally. For ease of testing, we recommend pulling it into an existing Gatsby project, in a `plugins` directory. 216 | 2) Add the plugin, with options, to `gatsby-config.js`. 217 | 3) Install dependencies by running `npm install` in the project directory. 218 | 4) Run `npm run build` in the console, to transpile the code for testing and running in your project. 219 | 5) Hack away! 220 | 221 | Included is an [ESLint](https://eslint.org) config to help check the correctness of your changes of your code, and a [prettier](https://prettier.io) config to format it. Use them with the corresponding plugins for your editor of choice, or run the tools from the command line with `npm run lint` and `npm run format`. Don't forget to format your changes with prettier before submitting a PR! 222 | -------------------------------------------------------------------------------- /src/stripeObjects.json: -------------------------------------------------------------------------------- 1 | { 2 | "objects": [ 3 | { 4 | "id": 1, 5 | "product": null, 6 | "name": "balance", 7 | "type": "Balance", 8 | "description": "The current balance on the Stripe account.", 9 | "canIterate": false, 10 | "methodName": "retrieve", 11 | "methodArgs": {} 12 | }, 13 | { 14 | "id": 2, 15 | "product": null, 16 | "name": "balanceTransactions", 17 | "type": "BalanceTransaction", 18 | "description": "A list of transactions that have contributed to the Stripe account balance (e.g., charges, transfers, and so forth).", 19 | "canIterate": true, 20 | "methodName": "list", 21 | "methodArgs": { 22 | "expand": ["data.source.destination", "data.source.customer", "data.source.invoice"] 23 | } 24 | }, 25 | { 26 | "id": 3, 27 | "product": null, 28 | "name": "charges", 29 | "type": "Charge", 30 | "description": "A list of charges previously created.", 31 | "canIterate": true, 32 | "methodName": "list", 33 | "methodArgs": { 34 | "expand": ["data.application", "data.application_fee", "data.balance_transaction", "data.customer", "data.destination", "data.dispute", "data.invoice", "data.on_behalf_of", "data.order", "data.review", "data.source_transfer", "data.transfer"] 35 | } 36 | }, 37 | { 38 | "id": 4, 39 | "product": null, 40 | "name": "customers", 41 | "type": "Customer", 42 | "description": "A list of customers.", 43 | "canIterate": true, 44 | "methodName": "list", 45 | "methodArgs": { 46 | "expand": ["data.default_source"] 47 | } 48 | }, 49 | { 50 | "id": 5, 51 | "product": null, 52 | "name": "disputes", 53 | "type": "Dispute", 54 | "description": "A list of disputes.", 55 | "canIterate": true, 56 | "methodName": "list", 57 | "methodArgs": { 58 | "expand": ["data.charge", "data.evidence.cancellation_policy", "data.evidence.customer_communication","data.evidence.customer_signature","data.evidence.duplicate_charge_documentation","data.evidence.receipt","data.evidence.refund_policy","data.evidence.service_documentation","data.evidence.shipping_documentation","data.evidence.uncategorized_file"] 59 | } 60 | }, 61 | { 62 | "id": 6, 63 | "product": null, 64 | "name": "events", 65 | "type": "Event", 66 | "description": "A list of events.", 67 | "canIterate": true, 68 | "methodName": "list", 69 | "methodArgs": {} 70 | }, 71 | { 72 | "id": 7, 73 | "product": null, 74 | "name": "files", 75 | "type": "File", 76 | "description": "A list of files uploaded to Stripe.", 77 | "canIterate": true, 78 | "methodName": "list", 79 | "methodArgs": {} 80 | }, 81 | { 82 | "id": 8, 83 | "product": null, 84 | "name": "fileLinks", 85 | "type": "FileLink", 86 | "description": "A list of file object links, so non-Stripe users can access the files.", 87 | "canIterate": true, 88 | "methodName": "list", 89 | "methodArgs": {} 90 | }, 91 | { 92 | "id": 9, 93 | "product": null, 94 | "name": "paymentIntents", 95 | "type": "PaymentIntent", 96 | "description": "A list of payment intents, tracking the process of collecting a payment from a customer.", 97 | "canIterate": true, 98 | "methodName": "list", 99 | "methodArgs": { 100 | "expand": ["data.application", "data.customer", "data.on_behalf_of", "data.review", "data.source"] 101 | } 102 | }, 103 | { 104 | "id": 10, 105 | "product": null, 106 | "name": "payouts", 107 | "type": "Payout", 108 | "description": "A list of existing payouts sent to third-party bank accounts or that Stripe has sent to the Stripe account.", 109 | "canIterate": true, 110 | "methodName": "list", 111 | "methodArgs": { 112 | "expand": ["data.balance_transaction", "data.destination"] 113 | } 114 | }, 115 | { 116 | "id": 11, 117 | "product": null, 118 | "name": "products", 119 | "type": "Product", 120 | "description": "A list of all products.", 121 | "canIterate": true, 122 | "methodName": "list", 123 | "methodArgs": {} 124 | }, 125 | { 126 | "id": 12, 127 | "product": null, 128 | "name": "refunds", 129 | "type": "Refund", 130 | "description": "A list of refunds.", 131 | "canIterate": true, 132 | "methodName": "list", 133 | "methodArgs": { 134 | "expand": ["data.balance_transaction", "data.charge", "data.source_transfer_reversal", "data.transfer_reversal"] 135 | } 136 | }, 137 | { 138 | "id": 13, 139 | "product": null, 140 | "name": "coupons", 141 | "type": "Coupon", 142 | "description": "A list of all coupons.", 143 | "canIterate": true, 144 | "methodName": "list", 145 | "methodArgs": {} 146 | }, 147 | { 148 | "id": 14, 149 | "product": null, 150 | "name": "invoices", 151 | "type": "Invoice", 152 | "description": "A list of invoices.", 153 | "canIterate": true, 154 | "methodName": "list", 155 | "methodArgs": { 156 | "expand": ["data.charge", "data.default_source", "data.subscription"] 157 | } 158 | }, 159 | { 160 | "id": 15, 161 | "product": null, 162 | "name": "invoiceItems", 163 | "type": "InvoiceItem", 164 | "description": "A list of all invoice items.", 165 | "canIterate": true, 166 | "methodName": "list", 167 | "methodArgs": {} 168 | }, 169 | { 170 | "id": 16, 171 | "product": null, 172 | "name": "plans", 173 | "type": "Plan", 174 | "description": "A list of all plans.", 175 | "canIterate": true, 176 | "methodName": "list", 177 | "methodArgs": {} 178 | }, 179 | { 180 | "id": 17, 181 | "product": null, 182 | "name": "subscriptions", 183 | "type": "Subscription", 184 | "description": "A list of subscriptions.", 185 | "canIterate": true, 186 | "methodName": "list", 187 | "methodArgs": { 188 | "expand": ["data.customer", "data.default_source"] 189 | } 190 | }, 191 | { 192 | "id": 18, 193 | "product": null, 194 | "name": "accounts", 195 | "type": "Account", 196 | "description": "A list of all accounts connected to your platform via Stripe Connect.", 197 | "canIterate": true, 198 | "methodName": "list", 199 | "methodArgs": {} 200 | }, 201 | { 202 | "id": 19, 203 | "product": null, 204 | "name": "applicationFees", 205 | "type": "ApplicationFee", 206 | "description": "A list of all application fees associated with your Stripe Connect platform.", 207 | "canIterate": true, 208 | "methodName": "list", 209 | "methodArgs": {} 210 | }, 211 | { 212 | "id": 20, 213 | "product": null, 214 | "name": "countrySpecs", 215 | "type": "CountrySpec", 216 | "description": "A list of country specs.", 217 | "canIterate": true, 218 | "methodName": "list", 219 | "methodArgs": {} 220 | }, 221 | { 222 | "id": 21, 223 | "product": null, 224 | "name": "topups", 225 | "type": "TopUp", 226 | "description": "A list of top-ups.", 227 | "canIterate": true, 228 | "methodName": "list", 229 | "methodArgs": {} 230 | }, 231 | { 232 | "id": 22, 233 | "product": null, 234 | "name": "transfers", 235 | "type": "Transfer", 236 | "description": "A list of transfers to and from the accounts connected to your Stripe Connect platform.", 237 | "canIterate": true, 238 | "methodName": "list", 239 | "methodArgs": { 240 | "expand": ["data.balance_transaction", "data.destination", "data.destination_payment", "data.source_transaction"] 241 | } 242 | }, 243 | { 244 | "id": 23, 245 | "product": "issuing", 246 | "name": "authorizations", 247 | "type": "IssuingAuthorization", 248 | "description": "A list of Issuing authorizations.", 249 | "canIterate": true, 250 | "methodName": "list", 251 | "methodArgs": { 252 | "expand": ["data.cardholder"] 253 | } 254 | }, 255 | { 256 | "id": 24, 257 | "product": "issuing", 258 | "name": "cardholders", 259 | "type": "IssuingCardholder", 260 | "description": "A list of Issuing cardholders.", 261 | "canIterate": true, 262 | "methodName": "list", 263 | "methodArgs": {} 264 | }, 265 | { 266 | "id": 25, 267 | "product": "issuing", 268 | "name": "cards", 269 | "type": "IssuingCard", 270 | "description": "A list of Issuing cards.", 271 | "canIterate": true, 272 | "methodName": "list", 273 | "methodArgs": {} 274 | }, 275 | { 276 | "id": 26, 277 | "product": "issuing", 278 | "name": "disputes", 279 | "type": "IssuingDispute", 280 | "description": "A list of Issuing disputes.", 281 | "canIterate": true, 282 | "methodName": "list", 283 | "methodArgs": {} 284 | }, 285 | { 286 | "id": 27, 287 | "product": "issuing", 288 | "name": "transactions", 289 | "type": "IssuingTransaction", 290 | "description": "A list of Issuing transactions.", 291 | "canIterate": true, 292 | "methodName": "list", 293 | "methodArgs": { 294 | "expand": ["data.authorization", "data.card", "data.cardholder"] 295 | } 296 | }, 297 | { 298 | "id": 28, 299 | "product": "terminal", 300 | "name": "locations", 301 | "type": "TerminalLocation", 302 | "description": "A list of Terminal locations.", 303 | "canIterate": true, 304 | "methodName": "list", 305 | "methodArgs": {} 306 | }, 307 | { 308 | "id": 29, 309 | "product": "terminal", 310 | "name": "readers", 311 | "type": "TerminalReader", 312 | "description": "A list of Terminal readers.", 313 | "canIterate": true, 314 | "methodName": "list", 315 | "methodArgs": {} 316 | }, 317 | { 318 | "id": 30, 319 | "product": null, 320 | "name": "orders", 321 | "type": "Order", 322 | "description": "A list of orders.", 323 | "canIterate": true, 324 | "methodName": "list", 325 | "methodArgs": { 326 | "expand": ["data.charge", "data.customer"] 327 | } 328 | }, 329 | { 330 | "id": 31, 331 | "product": null, 332 | "name": "orderReturns", 333 | "type": "OrderReturn", 334 | "description": "A list of order returns.", 335 | "canIterate": true, 336 | "methodName": "list", 337 | "methodArgs": {} 338 | }, 339 | { 340 | "id": 32, 341 | "product": null, 342 | "name": "skus", 343 | "type": "Sku", 344 | "description": "A list of skus.", 345 | "canIterate": true, 346 | "methodName": "list", 347 | "methodArgs": { 348 | "expand": ["data.product"] 349 | } 350 | }, 351 | { 352 | "id": 33, 353 | "product": "sigma", 354 | "name": "scheduledQueryRuns", 355 | "type": "SigmaScheduledQueryRun", 356 | "description": "A list of Sigma scheduled query runs.", 357 | "canIterate": true, 358 | "methodName": "list", 359 | "methodArgs": {} 360 | }, 361 | { 362 | "id": 34, 363 | "product": null, 364 | "name": "webhookEndpoints", 365 | "type": "WebhookEndpoint", 366 | "description": "A list of webhook endpoints.", 367 | "canIterate": true, 368 | "methodName": "list", 369 | "methodArgs": {} 370 | }, 371 | { 372 | "id": 35, 373 | "product": null, 374 | "name": "creditNotes", 375 | "type": "CreditNote", 376 | "description": "A list of credit notes.", 377 | "canIterate": true, 378 | "methodName": "list", 379 | "methodArgs": { 380 | "expand": ["data.customer", "data.invoice", "data.refund"] 381 | } 382 | }, 383 | { 384 | "id": 36, 385 | "product": null, 386 | "name": "reviews", 387 | "type": "Review", 388 | "description": "A list of Review objects that have open set to true.", 389 | "canIterate": true, 390 | "methodName": "list", 391 | "methodArgs": { 392 | "expand": ["data.charge", "data.payment_intent"] 393 | } 394 | }, 395 | { 396 | "id": 37, 397 | "product": "radar", 398 | "name": "valueLists", 399 | "type": "ValueList", 400 | "description": "A list of ValueList objects.", 401 | "canIterate": true, 402 | "methodName": "list", 403 | "methodArgs": {} 404 | }, 405 | { 406 | "id": 38, 407 | "product": "checkout", 408 | "name": "sessions", 409 | "type": "Session", 410 | "description": "A list of Checkout Session objects.", 411 | "canIterate": true, 412 | "methodName": "list", 413 | "methodArgs": { 414 | "expand": ["data.customer", "data.line_items", "data.payment_intent"] 415 | } 416 | }, 417 | { 418 | "id": 39, 419 | "product": null, 420 | "name": "prices", 421 | "type": "Price", 422 | "description": "A list of Price objects.", 423 | "canIterate": true, 424 | "methodName": "list", 425 | "methodArgs": { 426 | "expand": ["data.product", "data.tiers"] 427 | } 428 | }, 429 | { 430 | "id": 40, 431 | "product": null, 432 | "name": "taxRates", 433 | "type": "TaxRate", 434 | "description": "A list of TaxRate objects.", 435 | "canIterate": true, 436 | "methodName": "list", 437 | "methodArgs": {} 438 | }, 439 | { 440 | "id": 41, 441 | "product": null, 442 | "name": "setupIntents", 443 | "type": "SetupIntent", 444 | "description": "A list of SetupIntent objects.", 445 | "canIterate": true, 446 | "methodName": "list", 447 | "methodArgs": { 448 | "expand": ["data.customer", "data.latest_attempt", "data.mandate", "data.on_behalf_of", "data.single_use_mandate"] 449 | } 450 | }, 451 | { 452 | "id": 42, 453 | "product": null, 454 | "name": "promotionCodes", 455 | "type": "PromotionCode", 456 | "description": "A list of PromotionCode objects.", 457 | "canIterate": true, 458 | "methodName": "list", 459 | "methodArgs": { 460 | "expand": ["data.customer"] 461 | } 462 | }, 463 | { 464 | "id": 43, 465 | "product": null, 466 | "name": "subscriptionSchedules", 467 | "type": "SubscriptionSchedule", 468 | "description": "A list of SubscriptionSchedule objects.", 469 | "canIterate": true, 470 | "methodName": "list", 471 | "methodArgs": { 472 | "expand": ["data.customer", "data.subscription"] 473 | } 474 | }, 475 | { 476 | "id": 44, 477 | "product": "radar", 478 | "name": "earlyFraudWarnings", 479 | "type": "EarlyFraudWarning", 480 | "description": "A list of EarlyFraudWarning objects.", 481 | "canIterate": true, 482 | "methodName": "list", 483 | "methodArgs": { 484 | "expand": ["data.charge"] 485 | } 486 | } 487 | ] 488 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 5 | 6 | ## Unreleased 7 | 8 | ## [4.0.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.2.2...v4.0.0) - 2021-11-23 9 | - Fix issue that occurred when using Gatsby v4. 10 | - [BREAKING] From this version on, this package will only support Gatsby v4+. 11 | - Update @babel/cli from [7.13.0 to 7.16.0](https://github.com/babel/babel/releases). 12 | - Update @babel/core from [7.13.8 to 7.16.0](https://github.com/babel/babel/releases). 13 | - Update @babel/preset-env from [7.13.9 to 7.16.4](https://github.com/babel/babel/releases). 14 | - Update del-cli from [3.0.1 to 4.0.1](https://github.com/sindresorhus/del-cli/releases). 15 | - Update eslint-config-prettier from [8.1.0 to 8.3.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 16 | - Update eslint-plugin-import from [2.22.1 to 2.25.3](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 17 | - Update jest from [26.6.3 to 27.3.1](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 18 | - Update prettier from [2.2.1 to 2.4.1](https://prettier.io/blog/2019/04/12/1.17.0.html). 19 | - Update gatsby-source-filesystem from [3.0.0 to 4.2.0](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 20 | - Update stripe from [8.137.0 to 8.191.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 21 | 22 | ## [3.2.2](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.2.1...v3.2.2) - 2021-03-06 23 | - Auto-expand the tiers field in the Price object (thanks @klintan!). 24 | - Update file formatting based on updated eslint + prettier. 25 | - Update @babel/cli from [7.12.10 to 7.13.0](https://github.com/babel/babel/releases). 26 | - Update @babel/core from [7.12.10 to 7.13.8](https://github.com/babel/babel/releases). 27 | - Update @babel/preset-env from [7.12.11 to 7.13.9](https://github.com/babel/babel/releases). 28 | - Update eslint from [7.16.0 to 7.21.0](https://github.com/eslint/eslint/releases). 29 | - Update eslint-config-prettier from [7.1.0 to 8.1.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 30 | - Update eslint-plugin-prettier from [3.3.0 to 3.3.1](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 31 | - Update gatsby-source-filesystem from [2.8.1 to 3.0.0](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 32 | - Update stripe from [8.129.0 to 8.137.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 33 | 34 | ## [3.2.1](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.2.0...v3.2.1) - 2021-01-02 35 | - Remove a non-existent field from the Stripe Connect Account object so that it wouldn't error out when fetching Connect Accounts. 36 | 37 | ## [3.2.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.1.1...v3.2.0) - 2021-01-01 38 | - Enable downloading of images in the expanded `products` field of the Price type (thanks @brxck). 39 | - Add the following Stripe objects: TaxRate, SetupIntent, PromotionCode, SubscriptionSchedule, EarlyFraudWarning. These objects are now retrievable via their list methods. 40 | - Add above objects to the README, and update README to the fact that we're in line with Stripe API version 2020-08-27. 41 | - Update @babel/cli from [7.10.3 to 7.12.10](https://github.com/babel/babel/releases). 42 | - Update @babel/core from [7.10.3 to 7.12.10](https://github.com/babel/babel/releases). 43 | - Update @babel/preset-env from [7.10.3 to 7.12.11](https://github.com/babel/babel/releases). 44 | - Update cross-env from [7.0.2 to 7.0.3](https://github.com/kentcdodds/cross-env/releases). 45 | - Update eslint from [7.3.0 to 7.16.0](https://github.com/eslint/eslint/releases). 46 | - Update eslint-config-prettier from [6.11.0 to 7.1.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 47 | - Update eslint-plugin-import from [2.21.2 to 2.22.1](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 48 | - Update eslint-plugin-prettier from [3.1.4 to 3.3.0](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 49 | - Update gatsby-source-filesystem from [2.3.12 to 2.8.1](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 50 | - Update jest from [26.0.1 to 26.6.3](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 51 | - Update prettier from [2.0.5 to 2.2.1](https://prettier.io/blog/2019/04/12/1.17.0.html). 52 | - Update stripe from [8.64.0 to 8.129.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 53 | 54 | ## [3.1.1](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.1.0...v3.1.1) - 2020-06-21 55 | - Expand Price product, so that product object is returned along with price. Thanks @vSterlin! 56 | - Include Price query example in README. Thanks @brittneypostma! 57 | - Update @babel/cli from [7.10.1 to 7.10.3](https://github.com/babel/babel/releases). 58 | - Update @babel/core from [7.10.1 to 7.10.3](https://github.com/babel/babel/releases). 59 | - Update @babel/preset-env from [7.10.2 to 7.10.3](https://github.com/babel/babel/releases). 60 | - Update eslint from [7.1.0 to 7.3.0](https://github.com/eslint/eslint/releases). 61 | - Update eslint-plugin-import from [2.20.2 to 2.21.2](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 62 | - Update eslint-plugin-prettier from [3.1.3 to 3.1.4](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 63 | - Update gatsby-source-filesystem from [2.3.8 to 2.3.12](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 64 | - Update stripe from [8.56.0 to 8.64.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 65 | 66 | 67 | ## [3.1.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.7...v3.1.0) - 2020-05-30 68 | - Add Checkout Sessions resource. 69 | - Add Prices resource. 70 | - Update @babel/cli from [7.8.4 to 7.10.1](https://github.com/babel/babel/releases). 71 | - Update @babel/core from [7.8.7 to 7.10.2](https://github.com/babel/babel/releases). 72 | - Update @babel/preset-env from [7.8.7 to 7.10.2](https://github.com/babel/babel/releases). 73 | - Update del-cli from [3.0.0 to 3.0.1](https://github.com/sindresorhus/del-cli/releases). 74 | - Update eslint from [6.8.0 to 7.1.0](https://github.com/eslint/eslint/releases). 75 | - Update eslint-config-prettier from [6.10.0 to 6.11.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 76 | - Update eslint-plugin-import from [2.20.1 to 2.20.2](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 77 | - Update eslint-plugin-prettier from [3.1.2 to 3.1.3](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 78 | - Update gatsby-source-filesystem from [2.1.55 to 2.3.8](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 79 | - Update jest from [25.1.0 to 26.0.1](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 80 | - Update prettier from [1.19.1 to 2.0.5](https://prettier.io/blog/2019/04/12/1.17.0.html). 81 | - Update stripe from [8.32.0 to 8.56.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 82 | 83 | ## [3.0.7](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.6...v3.0.7) - 2020-03-14 84 | - Remove old ISSUE template as using GitHub's built-in version. 85 | - Add gotchas section to README and fix some typos. 86 | - Update Stripe client signature to remove deprecation warning. 87 | - Update @babel/core from [7.8.4 to 7.8.7](https://github.com/babel/babel/releases). 88 | - Update @babel/preset-env from [7.8.4 to 7.8.7](https://github.com/babel/babel/releases). 89 | - Update babel-eslint from [10.0.3 to 10.1.0](https://github.com/babel/babel-eslint/releases). 90 | - Update cross-env from [7.0.0 to 7.0.2](https://github.com/kentcdodds/cross-env/releases). 91 | - Update gatsby-source-filesystem from [2.1.48 to 2.1.55](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 92 | - Update stripe from [8.20.0 to 8.32.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 93 | 94 | ## [3.0.6](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.5...v3.0.6) - 2020-02-23 95 | - Update @babel/cli from [7.6.0 to 7.8.4](https://github.com/babel/babel/releases). 96 | - Update @babel/core from [7.6.0 to 7.8.4](https://github.com/babel/babel/releases). 97 | - Update @babel/preset-env from [7.6.0 to 7.8.4](https://github.com/babel/babel/releases). 98 | - Update stripe from [7.9.0 to 8.20.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 99 | - Update gatsby-source-filesystem from [2.1.22 to 2.1.48](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 100 | - Update jest from [24.9.0 to 25.1.0](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 101 | - Update prettier from [1.18.2 to 1.19.1](https://prettier.io/blog/2019/04/12/1.17.0.html). 102 | - Update cross-env from [5.2.1 to 7.0.0](https://github.com/kentcdodds/cross-env/releases). 103 | - Update eslint from [6.3.0 to 6.8.0](https://github.com/eslint/eslint/releases). 104 | - Update eslint-config-prettier from [6.3.0 to 6.10.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 105 | - Update eslint-plugin-import from [2.18.2 to 2.20.1](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 106 | - Update eslint-plugin-prettier from [3.1.0 to 3.1.2](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 107 | 108 | ## [3.0.5](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.4...v3.0.5) - 2019-11-24 109 | - Update README with note related to having at least one Product & SKU in your Stripe inventory when running the example query. Thanks @Petar-np! 110 | - Fix eslint errors. 111 | - Update gatsby-source-filesystem from [2.1.22 to 2.1.38](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 112 | - Update stripe from [7.9.0 to 7.13.1](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 113 | - Update @babel/cli from [7.6.0 to 7.7.4](https://github.com/babel/babel/releases). 114 | - Update @babel/core from [7.6.0 to 7.7.4](https://github.com/babel/babel/releases). 115 | - Update @babel/preset-env from [7.6.0 to 7.7.4](https://github.com/babel/babel/releases). 116 | - Update cross-env from [5.2.1 to 6.0.3](https://github.com/kentcdodds/cross-env/releases). 117 | - Update eslint from [6.3.0 to 6.7.0](https://github.com/eslint/eslint/releases). 118 | - Update eslint-config-prettier from [6.3.0 to 6.7.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 119 | - Update prettier from [1.18.2 to 1.19.1](https://prettier.io/blog/2019/04/12/1.17.0.html). 120 | 121 | ## [3.0.4](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.3...v3.0.4) - 2019-09-12 122 | - Update @babel/cli from [7.5.5 to 7.6.0](https://github.com/babel/babel/releases). 123 | - Update @babel/core from [7.5.5 to 7.6.0](https://github.com/babel/babel/releases). 124 | - Update @babel/preset-env from [7.5.5 to 7.6.0](https://github.com/babel/babel/releases). 125 | - Update babel-eslint from [10.0.2 to 10.0.3](https://github.com/babel/babel-eslint/releases). 126 | - Update cross-env from [5.2.0 to 5.2.1](https://github.com/kentcdodds/cross-env/releases). 127 | - Update del-cli from [2.0.0 to 3.0.0](https://github.com/sindresorhus/del-cli/releases). 128 | - Update eslint from [6.1.0 to 6.3.0](https://github.com/eslint/eslint/releases). 129 | - Update eslint-config-prettier from [6.0.0 to 6.3.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 130 | - Update gatsby-source-filesystem from [2.1.9 to 2.1.22](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 131 | - Update jest from [24.8.0 to 24.9.0](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 132 | - Update stripe from [7.7.0 to 7.9.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 133 | 134 | ## [3.0.3](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.2...v3.0.3) - 2019-07-26 135 | - Fix an issue where the images of a `Sku`'s expanded product field are not downloaded if the `Sku` has no image itself. 136 | - Update gatsby-source-filesystem from [2.1.6 to 2.1.9](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 137 | - Update stripe from [7.5.0 to 7.7.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 138 | 139 | ## [3.0.2](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.1...v3.0.2) - 2019-07-26 140 | - Remove `mediaType` from StripeObject Gatsby node, to solve bug related to using this plugin in the same project as `gatsby-tranformer-json`. Update relevant test. 141 | - Add `jest` environment to `.eslintrc`. 142 | - Update @babel/cli from [7.4.3 to 7.4.4](https://github.com/babel/babel/releases). 143 | - Update @babel/core from [7.4.3 to 7.4.5](https://github.com/babel/babel/releases). 144 | - Update @babel/preset-env from [7.4.3 to 7.4.5](https://github.com/babel/babel/releases). 145 | - Update babel-eslint from [10.0.1 to 10.0.2](https://github.com/babel/babel-eslint/releases). 146 | - Update eslint from [5.16.0 to 6.1.0](https://github.com/eslint/eslint/releases). 147 | - Update eslint-config-prettier from [4.3.0 to 6.0.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 148 | - Update eslint-plugin-import from [2.17.3 to 2.18.2](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 149 | - Update gatsby-source-filesystem from [2.0.38 to 2.1.6](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 150 | - Update stripe from [7.1.0 to 7.5.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 151 | 152 | ## [3.0.1](https://github.com/njosefbeck/gatsby-source-stripe/compare/v3.0.0...v3.0.1) - 2019-06-07 153 | - Handle download file error gracefully, so that plugin processes all Stripe objects possible, even if one errors out. 154 | 155 | ## [3.0.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.2.1...v3.0.0) - 2019-06-07 156 | 157 | **BREAKING** 158 | - We rewrote the local files download implementation to ensure we could 100% support (1) downloading `Product` images, and (2) downloading a `Sku` image and any of its associated Product's images. This means that downloading of `File` and `FileLinks` is no longer supported. 159 | - Additionally, if we're not able to download any local files, the `localFile` field is now set to `null` rather than an empty array. 160 | - Also, the `auth` flag has been removed from the plugin options. 161 | 162 | **NON-BREAKING** 163 | - Add some initial tests using Jest. Test commands include: `npm test`, `npm run watch:test`. Also tests run every time you use `npm run prepare`, `npm run build`. 164 | - Add .eslintignore to ignore tests dir when running eslint. 165 | - Add prebuild npm script to handle deleting old JavaScript files on build. 166 | - Fix capitalization issue: stripeObject.js --> StripeObject.js. 167 | - Update project to support Node `v8.16.0` or above. 168 | - Add support for [Credit Notes](https://stripe.com/docs/api/credit_notes/list), [Reviews](https://stripe.com/docs/api/radar/reviews/list), and [Value Lists](https://stripe.com/docs/api/radar/value_lists/object). Add one of the following strings to your config `objects` array to get this new data: `CreditNote`, `Review` or `ValueList`. 169 | - `balance.listTransactions()` has now become `balanceTransactions.list()`. The string used in your config `objects` array stays the same: `BalanceTransaction`. 170 | 171 | **DEPENDENCIES** 172 | - Update @babel/cli from [7.4.3 to 7.4.4](https://github.com/babel/babel/releases). 173 | - Update @babel/core from [7.4.3 to 7.4.5](https://github.com/babel/babel/releases). 174 | - Update @babel/preset-env from [7.4.3 to 7.4.5](https://github.com/babel/babel/releases). 175 | - Update del-cli from [1.1.0 to 2.0.0](https://github.com/sindresorhus/del-cli/releases). 176 | - Update eslint-config-prettier from [4.1.0 to 4.3.0](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md). 177 | - Update eslint-plugin-import from [2.17.0 to 2.17.3](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 178 | - Update eslint-plugin-prettier from [3.0.1 to 3.1.0](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md). 179 | - Update gatsby-source-filesystem from [2.0.29 to 2.0.38](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 180 | - Update jest from [24.7.1 to 24.8.0](https://github.com/facebook/jest/blob/master/CHANGELOG.md). 181 | - Update prettier from [1.17.0 to 1.18.2](https://prettier.io/blog/2019/04/12/1.17.0.html). 182 | - Update stripe from [6.28.0 to 7.1.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 183 | 184 | ## [2.2.2](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.2.1...v2.2.2) - 2019-04-13 185 | - Fix file capitalization issue. 186 | 187 | ## [2.2.1](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.2.0...v2.2.1) - 2019-04-13 188 | - Fix issue where need an index.js file, even if blank, so that Gatsby can find the plugin. 189 | 190 | ## [2.2.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.9...v2.2.0) - 2019-04-13 191 | - Add ESLint and prettier configuration & dependencies. 192 | - Fix bootstrap progressing without awaiting file downloads. 193 | - Fix cached Gatsby File nodes being deleted after development server restart. 194 | - Refactor LocalFile.js to improve readability. (Thanks @Francesco-Lanciana !) 195 | - Add the ability to remove Authorization headers from any HTTP request made when fetching files not hosted on Stripe. (Thanks @Francesco-Lanciana !) 196 | - Remove babel-compiled files from .gitignore. 197 | - Add .npmignore. 198 | - Add engines field to package.json. This plugin only works in versions of Node >= 10.13.0. 199 | - Update package.json scripts for properly building plugin for publishing. 200 | - Add .npmrc to enforce exact versions when adding new packages to the project. 201 | - Add coding guidelines section to CONTRIBUTING.md. 202 | - Update @babel/cli from 7.2.3 to 7.4.3. 203 | - Update @babel/core from 7.4.0 to 7.4.3. 204 | - Update @babel/preset-env from 7.4.2 to 7.4.3. 205 | - Update eslint-plugin-import from [2.16.0 to 2.17.0](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md). 206 | - Update gatsby-source-filesystem from [2.0.28 to 2.0.29](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 207 | - Update prettier from [1.16.4 to 1.17.0](https://prettier.io/blog/2019/04/12/1.17.0.html). 208 | 209 | ## [2.1.9](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.6...v2.1.9) - 2019-03-27 210 | ### Changed 211 | - Update stripe from [6.20.0 to 6.28.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 212 | - Update gatsby-source-filesystem from [2.0.16 to 2.0.28](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 213 | - Update @babel/cli from 7.2.0 to 7.2.3. 214 | - Update @babel/core from 7.2.2 to 7.4.0. 215 | - Update @babel/preset-env from 7.2.2 to 7.4.0. 216 | 217 | ## [2.1.7](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.6...v2.1.7) - 2019-02-11 218 | ### Changed 219 | - Update @babel/preset-env from [7.2.3 to 7.3.1](https://github.com/babel/babel/releases). 220 | - Update gatsby-source-filesystem from [2.0.16 to 2.0.20](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 221 | - Update stripe from [6.20.0 to 6.23.1](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 222 | 223 | ## [2.1.6](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.5...v2.1.6) - 2019-01-14 224 | ### Changed 225 | - Add information to README about using restricted API keys 226 | 227 | ## [2.1.5](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.4...v2.1.5) - 2019-01-14 228 | ### Changed 229 | - Fix File-breaking typo (Thanks @brxck!) 230 | 231 | ## [2.1.4](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.3...v2.1.4) - 2019-01-12 232 | ### Changed 233 | - Update [README](README.md) with the following: 234 | - Add links to the newly added CONTRIBUTING and CODE OF CONDUCT documents 235 | - Add caveat to file downloading section about using Checkout's beta 236 | - Refinements to file downloading feature (Thanks @brxck for your contributions!) 237 | - Remove no longer needed dummy password 238 | - Check node type before attempting download 239 | - Update downloading for iterable File nodes 240 | - Correct query for localFiles 241 | - Update gatsby-source-filesystem from [2.0.11 to 2.0.16](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 242 | 243 | ## [2.1.3](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.2...v2.1.3) - 2019-01-08 244 | ### Changed 245 | - Update stripe from [6.18.0 to 6.20.0](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md). 246 | - Update gatsby-source-filesystem from [2.0.11 to 2.0.12](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-filesystem/CHANGELOG.md). 247 | - Update @babel/cli from 7.2.0 to 7.2.3. 248 | - Update @babel/core from 7.2.0 to 7.2.2. 249 | - Update @babel/node from 7.2.0 to 7.2.2. 250 | - Update @babel/preset-env from 7.2.0 to 7.2.3. 251 | - Add [code of conduct](CODE_OF_CONDUCT.md) file. 252 | - Add [contributing](CONTRIBUTING.md) file. 253 | - Add [issue template](ISSUE_TEMPLATE.md) file. 254 | 255 | ## [2.1.2](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.1.0...v2.1.2) - 2018-12-09 256 | ### Changed 257 | - Update project dependencies, including stripe, which fixes issue #11. 258 | - Change README and inline code comments to reflect update (Stripe Files are now iterable!). 259 | 260 | ## [2.1.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.0.5...v2.1.0) - 2018-12-06 261 | ### Changed 262 | - Add support for downloading File objects associated with File objects, and images on Sku and Product objects. This will enable images to be processed by gatsby-transformer-sharp and used with gatsby-image. Read the updated README for more information. Thanks to @brxck for this AWESOME update. 263 | - Update peer dependency for Gatsby to >= 2.0.15. This is necessary since the plugin uses "createContentDigest", which didn't exist in versions prior to 2.0.15. Peer dependency information can be found in `package.json` and in the README. 264 | - Update project dependencies to latest versions. 265 | 266 | ## [2.0.5](https://github.com/njosefbeck/gatsby-source-stripe/compare/v2.0.0...v2.0.5) - 2018-11-20 267 | ### Changed 268 | - Fix generated file to accurately reflect StripeObject.js 269 | - Add babel-transpiled files back to version control to ensure they are part of npm package when installed by users. 270 | - Moved dependencies to devDependencies to avoid dependency pollution. 271 | 272 | ## [2.0.0](https://github.com/njosefbeck/gatsby-source-stripe/compare/v1.2.1...v2.0.0) - 2018-11-18 273 | ### Changed 274 | - This release contains a number of breaking changes. 275 | - Due to the way we're handling auto-pagination, you must use Node v.10 or higher when using this version of the plugin. 276 | - When adding Stripe objects to the objects array in `gatsby-config.js`, you must use the object types listed in the README. Thus, the type names have changed. 277 | - Re-write plugin to incorporate [stripe-node](https://github.com/stripe/stripe-node) auto-pagination. 278 | - Update README to include more information about how to use the plugin. 279 | - Update plugin implementation to bring it fully up to date with Stripe API version 2018-11-08. This involves adding some new object types (ex: TopUp, TerminalLocation), and renaming other objects (fileUploads becomes File). 280 | - Add plugin information for the Stripe library as recommended [here](https://github.com/stripe/stripe-node#writing-a-plugin). 281 | 282 | ## [1.2.1](https://github.com/njosefbeck/gatsby-source-stripe/compare/v1.2.0...v1.2.1) - 2018-11-02 283 | ### Changed 284 | - Update stripe dependency to 6.13.0. 285 | 286 | ## 1.2.0 - 2018-10-09 287 | ### Changed 288 | - Add CHANGELOG. 289 | - Fix issue where pagination wouldn't stop when calling Stripe methods. Fixed by @raae. 290 | - Add gatsby v1+ as peer dependency as recommended [here](https://github.com/gatsbyjs/gatsby/blob/master/docs/docs/migrating-from-v1-to-v2.md#for-plugin-maintainers). 291 | - Rename `boundActionCreators` to `actions` as part of [Gatsby v2 migration](https://github.com/gatsbyjs/gatsby/blob/master/docs/docs/migrating-from-v1-to-v2.md#rename-boundactioncreators-to-actions). 292 | - Update [Stripe Node.js Library](https://www.npmjs.com/package/stripe) from 6.8.0 to 6.12.1. 293 | --------------------------------------------------------------------------------