├── .DS_Store ├── .gitignore ├── README.md ├── lerna.json ├── package.json ├── plugins ├── braintree │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── braintree-common.ts │ │ ├── braintree-payment-method.ts │ │ ├── braintree-plugin.ts │ │ ├── braintree.resolver.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ └── types.ts │ └── tsconfig.json ├── extended-shipments │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── calculators │ │ │ ├── flatrateCalculator.ts │ │ │ └── weightCalculator.ts │ │ ├── checkers │ │ │ ├── args.ts │ │ │ ├── functions.ts │ │ │ ├── geoChecker.ts │ │ │ └── valueWeightChecker.ts │ │ ├── constants.ts │ │ ├── custom-fields.ts │ │ ├── index.ts │ │ ├── plugin.ts │ │ ├── types.ts │ │ ├── ui │ │ │ ├── components │ │ │ │ ├── country-selector-component │ │ │ │ │ ├── country-selector.component.html │ │ │ │ │ ├── country-selector.component.scss │ │ │ │ │ └── country-selector.component.ts │ │ │ │ └── zone-selector-component │ │ │ │ │ ├── zone-selector.component.html │ │ │ │ │ ├── zone-selector.component.scss │ │ │ │ │ └── zone-selector.component.ts │ │ │ ├── generated-types.ts │ │ │ └── geo-selector.module.ts │ │ └── utils.ts │ └── tsconfig.json ├── featured-plugin │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── custom-fields.ts │ │ ├── index.ts │ │ └── plugin.ts │ └── tsconfig.json ├── gcp-storage │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── asset-thumbnail.resolvers.ts │ │ ├── asset-thumbnail.schema.ts │ │ ├── google-storage-config.ts │ │ ├── google-storage-plugin.ts │ │ ├── google-storage-strategy.ts │ │ └── index.ts │ └── tsconfig.json ├── jobqueue-plugin │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── jobs-queues.ts │ │ ├── options.ts │ │ ├── plugin.ts │ │ ├── pub-sub-job-queue-strategy.spec.ts │ │ └── pub-sub-job-queue-strategy.ts │ └── tsconfig.json └── seo-plugin │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ ├── custom-fields.ts │ ├── index.ts │ └── plugin.ts │ └── tsconfig.json └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artcoded-net/vendure-plugins/38e022ccef8eb6ae1635eaf47db7f51821c89a17/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Artcoded's Vendure Plugins monorepo 2 | 3 | This is a monorepo for all our Vendure plugins. 4 | Please refer to readme's inside of each plugin's folder for reference and documentation. 5 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["plugins/*"], 3 | "version": "independent", 4 | "useWorkspaces": "true" 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/vendure-plugins-root", 3 | "private": true, 4 | "workspaces": [ 5 | "plugins/*" 6 | ], 7 | "devDependencies": { 8 | "lerna": "^3.22.1", 9 | "typescript": "latest" 10 | }, 11 | "scripts": { 12 | "link-packages": "lerna run link" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugins/braintree/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/braintree/README.md: -------------------------------------------------------------------------------- 1 | # Braintree plugin for Vendure 2 | 3 | This plugin is a subtle adaptation/fix of the [official Braintree Vendure plugin](https://github.com/vendure-ecommerce/real-world-vendure/tree/master/src/plugins/braintree), found in the real-world-vendure repository of Vendure, and that has now been updated based on these fixes. 4 | 5 | Also the following documentation is just a subtle adaptation of the original one. 6 | 7 | This plugin enables payments to be processed by [Braintree](https://www.braintreepayments.com/), a popular payment provider. 8 | 9 | ## Requirements 10 | 11 | 1. You will need to create a Braintree sandbox account as outlined in https://developers.braintreepayments.com/start/overview. 12 | 2. Then install `braintree` and `@types/braintree` from npm. This plugin was written with `v3.0.0` of the Braintree lib. 13 | 14 | ## Setup 15 | 16 | 1. Add the plugin to your VendureConfig `plugins` array. 17 | 2. In the admin UI, fill in the `merchantId`, `publicKey`, `privateKey` and `merchantAccountId` from your Braintree account 18 | 3. If the account is not a sandbox but is meant for production, flag the "live" checkbox 19 | 20 | ## Usage 21 | 22 | The plugin is designed to work with the [Braintree drop-in UI](https://developers.braintreepayments.com/guides/drop-in/overview/javascript/v3). 23 | 24 | In your storefront, you'll have some code like this to submit the payment: 25 | 26 | ```TypeScript 27 | async function submitPayment() { 28 | const paymentResult = await this.dropin.requestPaymentMethod(); 29 | myGraphQlClient.mutation(gql` 30 | mutation { 31 | addPaymentToOrder(input: $input) { 32 | id 33 | state 34 | payments { 35 | id 36 | amount 37 | errorMessage 38 | method 39 | state 40 | transactionId 41 | createdAt 42 | } 43 | } 44 | }`, { 45 | input: { 46 | method: 'braintree', 47 | metadata: paymentResult, 48 | }, 49 | }); 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /plugins/braintree/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/vendure-braintree-plugin", 3 | "author": { 4 | "name": "Artcoded", 5 | "email": "dev@artcoded.net", 6 | "url": "https://artcoded.net" 7 | }, 8 | "description": "Braintree integration plugin for Vendure, adapted from the real-world-vendure plugin", 9 | "version": "1.0.5", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "README.md", 15 | "LICENSE.md" 16 | ], 17 | "dependencies": { 18 | "@nestjs/graphql": "latest", 19 | "@types/braintree": "^2.22.4", 20 | "apollo-server-core": "latest", 21 | "braintree": "^3.0.0", 22 | "@vendure/common": "^1.2.0", 23 | "@vendure/core": "^1.2.0" 24 | }, 25 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817", 26 | "license": "MIT", 27 | "publishConfig": { 28 | "access": "public" 29 | }, 30 | "scripts": { 31 | "build": "rimraf dist && tsc", 32 | "prepare": "yarn build", 33 | "link": "yarn link" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugins/braintree/src/braintree-common.ts: -------------------------------------------------------------------------------- 1 | import { BraintreeGateway, Environment, Transaction } from "braintree"; 2 | import { PaymentMethodArgsHash } from "./types"; 3 | 4 | export function getGateway(args: PaymentMethodArgsHash): BraintreeGateway { 5 | return new BraintreeGateway({ 6 | environment: 7 | // @ts-ignore: type error boolean vs string 8 | args.live == "true" || args.live == true 9 | ? Environment.Production 10 | : Environment.Sandbox, // Sandbox by default 11 | merchantId: args.merchantId, 12 | privateKey: args.privateKey, 13 | publicKey: args.publicKey, 14 | }); 15 | } 16 | 17 | /** 18 | * Returns a subset of the Transaction object of interest to the Administrator. 19 | */ 20 | export function extractMetadataFromTransaction(transaction: Transaction): { 21 | [key: string]: any; 22 | } { 23 | const metadata: { [key: string]: any } = { 24 | status: transaction.status, 25 | currencyIsoCode: transaction.currencyIsoCode, 26 | merchantAccountId: transaction.merchantAccountId, 27 | cvvCheck: decodeAvsCode(transaction.cvvResponseCode), 28 | avsPostCodeCheck: decodeAvsCode(transaction.avsPostalCodeResponseCode), 29 | avsStreetAddressCheck: decodeAvsCode( 30 | transaction.avsStreetAddressResponseCode 31 | ), 32 | processorAuthorizationCode: transaction.processorAuthorizationCode, 33 | processorResponseText: transaction.processorResponseText, 34 | paymentMethod: transaction.paymentInstrumentType, 35 | }; 36 | if (transaction.creditCard && transaction.creditCard.cardType) { 37 | metadata.cardData = { 38 | cardType: transaction.creditCard.cardType, 39 | last4: transaction.creditCard.last4, 40 | expirationDate: transaction.creditCard.expirationDate, 41 | }; 42 | } 43 | if (transaction.paypalAccount && transaction.paypalAccount.authorizationId) { 44 | metadata.paypalData = { 45 | payerEmail: transaction.paypalAccount.payerEmail, 46 | paymentId: transaction.paypalAccount.paymentId, 47 | authorizationId: transaction.paypalAccount.authorizationId, 48 | payerStatus: transaction.paypalAccount.payerStatus, 49 | sellerProtectionStatus: transaction.paypalAccount.sellerProtectionStatus, 50 | transactionFeeAmount: transaction.paypalAccount.transactionFeeAmount, 51 | }; 52 | } 53 | return metadata; 54 | } 55 | 56 | function decodeAvsCode(code: string): string { 57 | switch (code) { 58 | case "I": 59 | return "Not Provided"; 60 | case "M": 61 | return "Matched"; 62 | case "N": 63 | return "Not Matched"; 64 | case "U": 65 | return "Not Verified"; 66 | case "S": 67 | return "Not Supported"; 68 | case "E": 69 | return "AVS System Error"; 70 | case "A": 71 | return "Not Applicable"; 72 | case "B": 73 | return "Skipped"; 74 | default: 75 | return "Unknown"; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /plugins/braintree/src/braintree-payment-method.ts: -------------------------------------------------------------------------------- 1 | import { LanguageCode } from "@vendure/common/lib/generated-types"; 2 | import { 3 | Logger, 4 | PaymentMethodHandler, 5 | CreatePaymentResult, 6 | } from "@vendure/core"; 7 | 8 | import { extractMetadataFromTransaction, getGateway } from "./braintree-common"; 9 | import { loggerCtx } from "./constants"; 10 | 11 | /** 12 | * The handler for Braintree payments. 13 | */ 14 | export const braintreePaymentMethodHandler = new PaymentMethodHandler({ 15 | code: "braintree", 16 | description: [ 17 | { languageCode: LanguageCode.en, value: "Braintree" }, 18 | { languageCode: LanguageCode.it, value: "Braintree" }, 19 | ], 20 | args: { 21 | merchantId: { type: "string" }, 22 | publicKey: { type: "string" }, 23 | privateKey: { type: "string" }, 24 | merchantAccountId: { type: "string" }, 25 | live: { type: "boolean" }, 26 | }, 27 | 28 | createPayment: async ( 29 | ctx, 30 | order, 31 | amount, 32 | args, 33 | metadata 34 | ): Promise => { 35 | const gateway = getGateway(args); 36 | try { 37 | const response = await gateway.transaction.sale({ 38 | amount: (order.totalWithTax / 100).toString(10), 39 | orderId: order.code, 40 | paymentMethodNonce: metadata.nonce, 41 | options: { 42 | submitForSettlement: false, 43 | }, 44 | }); 45 | if (!response.success) { 46 | return { 47 | amount: order.totalWithTax, 48 | state: "Declined" as const, 49 | transactionId: response.transaction.id, 50 | errorMessage: response.message, 51 | metadata: extractMetadataFromTransaction(response.transaction), 52 | }; 53 | } 54 | return { 55 | amount: order.totalWithTax, 56 | state: "Authorized" as const, 57 | transactionId: response.transaction.id, 58 | metadata: extractMetadataFromTransaction(response.transaction), 59 | }; 60 | } catch (e: any) { 61 | Logger.error(e, loggerCtx); 62 | return { 63 | amount: order.totalWithTax, 64 | state: "Declined" as const, 65 | transactionId: "", 66 | errorMessage: e.toString(), 67 | metadata: e, 68 | }; 69 | } 70 | }, 71 | 72 | settlePayment: async (ctx, order, payment, args) => { 73 | const gateway = getGateway(args); 74 | try { 75 | const response = await gateway.transaction.submitForSettlement( 76 | payment.transactionId 77 | ); 78 | return { 79 | success: response.success, 80 | errorMessage: response.errors ? response.message : undefined, 81 | }; 82 | } catch (e: any) { 83 | Logger.error(e, loggerCtx); 84 | return { success: false, errorMessage: e.toString() }; 85 | } 86 | }, 87 | 88 | async createRefund(ctx, input, amount, order, payment, args) { 89 | const gateway = getGateway(args); 90 | const response = await gateway.transaction.refund( 91 | payment.transactionId, 92 | (amount / 100).toString(10) 93 | ); 94 | if (!response.success) { 95 | return { 96 | state: "Failed" as const, 97 | transactionId: response.transaction.id, 98 | metadata: response, 99 | }; 100 | } 101 | return { 102 | state: "Settled" as const, 103 | transactionId: response.transaction.id, 104 | metadata: response, 105 | }; 106 | }, 107 | }); 108 | -------------------------------------------------------------------------------- /plugins/braintree/src/braintree-plugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginCommonModule, VendurePlugin } from "@vendure/core"; 2 | import { gql } from "apollo-server-core"; 3 | 4 | import { braintreePaymentMethodHandler } from "./braintree-payment-method"; 5 | import { BraintreeResolver } from "./braintree.resolver"; 6 | 7 | /** 8 | * This plugin implements the Braintree (https://www.braintreepayments.com/) payment provider. 9 | */ 10 | @VendurePlugin({ 11 | imports: [PluginCommonModule], 12 | providers: [], 13 | configuration: (config) => { 14 | config.paymentOptions.paymentMethodHandlers.push( 15 | braintreePaymentMethodHandler 16 | ); 17 | return config; 18 | }, 19 | shopApiExtensions: { 20 | schema: gql` 21 | extend type Query { 22 | generateBraintreeClientToken(orderId: ID!): String! 23 | } 24 | `, 25 | resolvers: [BraintreeResolver], 26 | }, 27 | }) 28 | export class BraintreePlugin {} 29 | -------------------------------------------------------------------------------- /plugins/braintree/src/braintree.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Args, Query, Resolver } from "@nestjs/graphql"; 2 | import { 3 | Ctx, 4 | ID, 5 | InternalServerError, 6 | Logger, 7 | OrderService, 8 | PaymentMethod, 9 | RequestContext, 10 | TransactionalConnection, 11 | } from "@vendure/core"; 12 | 13 | import { getGateway } from "./braintree-common"; 14 | import { braintreePaymentMethodHandler } from "./braintree-payment-method"; 15 | import { loggerCtx } from "./constants"; 16 | import { PaymentMethodArgsHash } from "./types"; 17 | 18 | @Resolver() 19 | export class BraintreeResolver { 20 | constructor( 21 | private connection: TransactionalConnection, 22 | private orderService: OrderService 23 | ) {} 24 | 25 | @Query() 26 | async generateBraintreeClientToken( 27 | @Ctx() ctx: RequestContext, 28 | @Args() { orderId }: { orderId: ID } 29 | ) { 30 | const order = await this.orderService.findOne(ctx, orderId); 31 | if (order) { 32 | const args = await this.getPaymentMethodArgs(ctx); 33 | const gateway = getGateway(args); 34 | try { 35 | const result = await gateway.clientToken.generate({ 36 | merchantAccountId: args.merchantAccountId, 37 | }); 38 | return result.clientToken; 39 | } catch (e) { 40 | Logger.error(e); 41 | } 42 | } else { 43 | throw new InternalServerError( 44 | `[${loggerCtx}] Could not find a Customer for the given Order` 45 | ); 46 | } 47 | } 48 | 49 | private async getPaymentMethodArgs( 50 | ctx: RequestContext 51 | ): Promise { 52 | const method = await this.connection 53 | .getRepository(ctx, PaymentMethod) 54 | .findOne({ 55 | where: { 56 | code: braintreePaymentMethodHandler.code, 57 | }, 58 | }); 59 | if (!method) { 60 | throw new InternalServerError( 61 | `[${loggerCtx}] Could not find Braintree PaymentMethod` 62 | ); 63 | } 64 | return method.handler.args.reduce((hash, arg) => { 65 | return { 66 | ...hash, 67 | [arg.name]: arg.value, 68 | }; 69 | }, {} as PaymentMethodArgsHash); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /plugins/braintree/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const loggerCtx = 'BraintreePlugin'; 2 | -------------------------------------------------------------------------------- /plugins/braintree/src/index.ts: -------------------------------------------------------------------------------- 1 | export { BraintreePlugin } from './braintree-plugin'; -------------------------------------------------------------------------------- /plugins/braintree/src/types.ts: -------------------------------------------------------------------------------- 1 | import { ConfigArgValues } from '@vendure/core/dist/common/configurable-operation'; 2 | 3 | import { braintreePaymentMethodHandler } from './braintree-payment-method'; 4 | 5 | export type PaymentMethodArgsHash = ConfigArgValues; -------------------------------------------------------------------------------- /plugins/braintree/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"] 20 | } 21 | -------------------------------------------------------------------------------- /plugins/extended-shipments/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/extended-shipments/README.md: -------------------------------------------------------------------------------- 1 | # Extended shipments plugin for Vendure 2 | 3 | This plugin introduces new checkers and calculators, mostly to add geographic based filtering and pricing thresholds based on products' (and total parcels') weights, which are introduced as product custom fields. 4 | This plugin supports by default translations in English and Italian, but of course can be easily adapted to other and more languages. 5 | This is also a good example on how to customize Vendure's shipments logic through a plugin. 6 | 7 | # Documentation 8 | 9 | This plugin introduces new shipping checkers and calculators, as described below. 10 | 11 | ## How to use 12 | 13 | Install: 14 | 15 | ```shell 16 | npm install @artcoded/vendure-extended-shipments-plugin 17 | ``` 18 | 19 | or 20 | 21 | ```shell 22 | yarn add @artcoded/vendure-extended-shipments-plugin 23 | ``` 24 | 25 | Then register in your Vendure config, like this: 26 | 27 | ```typescript 28 | import { ExtendedShipmentsPlugin } from @artcoded/vendure-extended-shipments-plugin; 29 | 30 | //... 31 | 32 | plugins: [ 33 | ExtendedShipmentsPlugin 34 | ] 35 | ``` 36 | 37 | ## Shipping price calculators 38 | 39 | The calculators are under the ./calculators folder and are: 40 | 41 | - a flat rate calculator 42 | - a calculator based on the total order weight 43 | 44 | ### Flat rate calculator 45 | 46 | This is a very simple fixed price calculation based on fixed price and fixed tax rate 47 | 48 | ### Order weight-based calculator 49 | 50 | This custom shipping price calculator takes a weight unit of measure (weightUoM), a list of minimum weight thresholds and a corresponding list of prices to apply to each price range, plus a default pricing. So if for example: 51 | 52 | - the weight unit is 'kg', 53 | - the weight thresholds are [1, 3, 6], 54 | - the corresponding prices are [10, 20, 30] and 55 | - the default price is 5 56 | 57 | the shipping price will be calculated as follows: 58 | 59 | - if the order weight is 1 to 2.9 Kg, the price will be 10€, 60 | - if the weight is 3 to 5.9 Kg the price will be 20, 61 | - from 6 Kg and more it will be 30 62 | - if the weight doesn't fall into any range (e.g. in this example it is under 1 Kg) the default price will be applied. 63 | 64 | ## Shipping eligibility checkers 65 | 66 | The checkers are under the ./checkers folder with their helper functions. 67 | 68 | ### The geo checker: based on geography 69 | 70 | Checks if the order shipping destination is among the selected zones or countries. 71 | It's enough that the destination country is either inside one of the selected zones or corresponds to one of the selected countries: in other words, geographic conditions are evaluated with an 'or' approach. 72 | 73 | ### The checker based on order value and weight 74 | 75 | The ValueWeightShippingEligibility checker checks if the total order value is over a certain min threshold AND at the same time the total weight is under a max threshold. 76 | 77 | ## Ui extension: the geo-selector module 78 | 79 | In order to take the zone/country inputs from the user, the geo-checker needs the ui extension "geo-selector" located under the ./ui folder. 80 | 81 | ## Custom fields 82 | 83 | We need to add weight and weight unit of measure to the variants as custom fields. Please not it is _not_ required that all variants use the same unit of measure: unit conversion is performed when evaluating the total order weight (see the relevant helper function in utils.ts) 84 | -------------------------------------------------------------------------------- /plugins/extended-shipments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/vendure-extended-shipments-plugin", 3 | "author": { 4 | "name": "Artcoded", 5 | "email": "dev@artcoded.net", 6 | "url": "https://artcoded.net" 7 | }, 8 | "description": "Vendure plugin that adds shipments configuration capabilities such as price calculation based on parcel weight", 9 | "version": "0.3.1", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "README.md", 15 | "LICENSE.md" 16 | ], 17 | "dependencies": { 18 | "@angular/core": "*", 19 | "@angular/forms": "*", 20 | "@vendure/admin-ui": "^1.2.0", 21 | "@vendure/common": "^1.2.0", 22 | "@vendure/core": "^1.2.0", 23 | "@vendure/ui-devkit": "^1.2.0", 24 | "rxjs": "*", 25 | "typeorm": "*" 26 | }, 27 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817", 28 | "license": "MIT", 29 | "publishConfig": { 30 | "access": "public" 31 | }, 32 | "scripts": { 33 | "build": "rimraf dist && tsc && cp -r ./src/ui ./dist", 34 | "prepare": "yarn build" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/calculators/flatrateCalculator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple shipping calculator based on a fixed price and fixed tax rate percentage 3 | */ 4 | 5 | import { LanguageCode, ShippingCalculator } from "@vendure/core"; 6 | 7 | export const flatRateShippingCalculator = new ShippingCalculator({ 8 | code: "flatrate-shipping-calculator", 9 | description: [ 10 | { 11 | languageCode: LanguageCode.en, 12 | value: "Flat-Rate Shipping Calculator (default)", 13 | }, 14 | { 15 | languageCode: LanguageCode.it, 16 | value: "Spedizione a prezzo fisso (default)", 17 | }, 18 | ], 19 | args: { 20 | rate: { 21 | type: "int", 22 | config: { inputType: "money" }, 23 | ui: { component: "currency-form-input" }, 24 | label: [ 25 | { languageCode: LanguageCode.en, value: "Shipping price" }, 26 | { languageCode: LanguageCode.it, value: "Prezzo di spedizione" }, 27 | ], 28 | }, 29 | taxRate: { 30 | type: "int", 31 | config: { inputType: "percentage" }, 32 | ui: { component: "number-form-input", min: 0, max: 100, suffix: "%" }, 33 | label: [ 34 | { languageCode: LanguageCode.en, value: "Tax rate" }, 35 | { languageCode: LanguageCode.it, value: "Percentuale tasse" }, 36 | ], 37 | }, 38 | }, 39 | calculate: (ctx, order, args) => { 40 | return { 41 | price: args.rate, 42 | taxRate: args.taxRate, 43 | priceIncludesTax: ctx.channel.pricesIncludeTax, 44 | }; 45 | }, 46 | }); 47 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/calculators/weightCalculator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This custom shipping price calculator takes a weight unit of measure (weightUoM), a list of minimum weight thresholds 3 | * and a corresponding list of prices to apply to each price range, plus a default pricing. 4 | * So if for example the weight unit is kg, the weight thresholds are [1, 3, 6], the corresponding prices are [10, 20, 30] 5 | * and the default price is 5, if the order weight is 1 to 2.9 Kg, the price will be 10€, if the weight is 3 to 5.9 Kg the price 6 | * will be 20, from 6 Kg and more it will be 30. If the weight doesn't fall into any range (e.g. in this example it is under 1 Kg) 7 | * the default price will be applied. 8 | */ 9 | 10 | import { 11 | LanguageCode, 12 | CalculateShippingFn, 13 | ShippingCalculator, 14 | OrderLine, 15 | } from "@vendure/core"; 16 | import { ConfigArgs } from "@vendure/core/dist/common/configurable-operation"; 17 | import { WeightUnit } from "../types"; 18 | import { getOrderWeight } from "../utils"; 19 | 20 | type WeightShippingCalculatorArgs = { 21 | weightUoM: { 22 | type: "string"; 23 | ui: { 24 | component: string; 25 | options: { 26 | value: string; 27 | }[]; 28 | }; 29 | label: ( 30 | | { 31 | languageCode: LanguageCode; 32 | value: string; 33 | } 34 | | { 35 | languageCode: LanguageCode; 36 | value: string; 37 | } 38 | )[]; 39 | }; 40 | minWeights: { 41 | type: "float"; 42 | list: boolean; 43 | ui: { 44 | component: string; 45 | }; 46 | label: ( 47 | | { 48 | languageCode: LanguageCode; 49 | value: string; 50 | } 51 | | { 52 | languageCode: LanguageCode; 53 | value: string; 54 | } 55 | )[]; 56 | }; 57 | correspondingPrices: { 58 | type: "float"; 59 | list: boolean; 60 | ui: { 61 | component: string; 62 | }; 63 | label: ( 64 | | { 65 | languageCode: LanguageCode; 66 | value: string; 67 | } 68 | | { 69 | languageCode: LanguageCode; 70 | value: string; 71 | } 72 | )[]; 73 | }; 74 | defaultPrice: { 75 | type: "float"; 76 | ui: { 77 | component: string; 78 | }; 79 | label: ( 80 | | { 81 | languageCode: LanguageCode; 82 | value: string; 83 | } 84 | | { 85 | languageCode: LanguageCode; 86 | value: string; 87 | } 88 | )[]; 89 | }; 90 | taxRate: { 91 | type: "float"; 92 | ui: { 93 | component: string; 94 | suffix: string; 95 | }; 96 | label: ( 97 | | { 98 | languageCode: LanguageCode.en; 99 | value: string; 100 | } 101 | | { 102 | languageCode: LanguageCode.it; 103 | value: string; 104 | } 105 | )[]; 106 | }; 107 | }; 108 | 109 | const calculateWeightBasedShippingCost: CalculateShippingFn = 110 | async (ctx, order, args) => { 111 | const { 112 | weightUoM, 113 | minWeights, 114 | correspondingPrices, 115 | defaultPrice, 116 | taxRate, 117 | } = args; 118 | // get products' custom fields (weight ecc.) from order and calculate total 119 | const totalWeight = getOrderWeight(order, weightUoM as WeightUnit); 120 | const sortedWeights = (minWeights as any as number[]).sort( 121 | (a: number, b: number) => a - b 122 | ); //ordino i pesi in ordine crescente 123 | const sortedPrices = (correspondingPrices as any as number[]).sort( 124 | (a: number, b: number) => a - b 125 | ); //ordino i prezzi in ordine crescente 126 | let shipmentPrice: number | undefined = undefined; 127 | for (let i = sortedWeights.length - 1; i >= 0; i--) { 128 | const currentWeight = Number.isNaN(sortedWeights[i]) 129 | ? 0 130 | : sortedWeights[i]; 131 | // comincio dal peso più alto 132 | if (totalWeight >= currentWeight) { 133 | shipmentPrice = sortedPrices[i]; 134 | break; //esci dal ciclo for 135 | } 136 | } 137 | 138 | const price = shipmentPrice ? shipmentPrice : defaultPrice; 139 | 140 | return { 141 | price, 142 | taxRate, 143 | priceIncludesTax: ctx.channel.pricesIncludeTax, 144 | metadata: { 145 | // penso nulla 146 | }, 147 | }; 148 | }; 149 | 150 | export const weightShippingCalculator = new ShippingCalculator({ 151 | code: "weight-shipping-calculator", 152 | description: [ 153 | { 154 | languageCode: LanguageCode.en, 155 | value: "Based on parcel weight", 156 | }, 157 | { 158 | languageCode: LanguageCode.it, 159 | value: "Peso della spedizione", 160 | }, 161 | ], 162 | args: { 163 | weightUoM: { 164 | type: "string", 165 | ui: { 166 | component: "select-form-input", 167 | options: [{ value: "g" }, { value: "kg" }], 168 | }, 169 | label: [ 170 | { 171 | languageCode: LanguageCode.en, 172 | value: "The weight unit of measure", 173 | }, 174 | { 175 | languageCode: LanguageCode.it, 176 | value: "Unità di misura per il peso", 177 | }, 178 | ], 179 | }, 180 | minWeights: { 181 | //Il minimo peso a partire da cui è applicato il relativo prezzo 182 | type: "float", 183 | list: true, 184 | ui: { component: "number-form-input", min: 0 }, 185 | label: [ 186 | { 187 | languageCode: LanguageCode.en, 188 | value: 189 | "The minimum weight thresholds that determine which price to apply to the shipment", 190 | }, 191 | { 192 | languageCode: LanguageCode.it, 193 | value: 194 | "Le soglie di peso minimo che determinano le fasce di prezzo da applicare alla spedizione", 195 | }, 196 | ], 197 | }, 198 | correspondingPrices: { 199 | //Applico il prezzo i se il peso è almeno pari a i e non c'è una fascia più prossima 200 | type: "float", 201 | list: true, 202 | ui: { component: "currency-form-input" }, 203 | label: [ 204 | { 205 | languageCode: LanguageCode.en, 206 | value: 207 | "The shipment prices to apply (for example price number 1 is applied if the parcel weight is at least equal to the weight threshold number 1, but less than the threshold number 2. Please note all values are sorted in ascending order!", 208 | }, 209 | { 210 | languageCode: LanguageCode.it, 211 | value: 212 | "I valori di prezzo da applicare (ad esempio il prezzo numero 1 è applicato se il peso della spedizione è almeno pari alla soglia di peso numero 1 ma inferiore alla numero 2. Nota bene: tutti i valori sono ordinati in ordine crescente!", 213 | }, 214 | ], 215 | }, 216 | defaultPrice: { 217 | type: "float", 218 | ui: { component: "currency-form-input" }, 219 | label: [ 220 | { 221 | languageCode: LanguageCode.en, 222 | value: 223 | "The shipment price to apply if the weight doesn't fit in any weight threshold", 224 | }, 225 | { 226 | languageCode: LanguageCode.it, 227 | value: 228 | "Il valore di prezzo da applicare se il peso non ricade in nessuna fascia di peso specificata", 229 | }, 230 | ], 231 | }, 232 | taxRate: { 233 | type: "float", 234 | ui: { component: "number-form-input", min: 0, max: 100, suffix: "%" }, 235 | label: [ 236 | { 237 | languageCode: LanguageCode.en, 238 | value: "The shipment price tax rate to apply (optional)", 239 | }, 240 | { 241 | languageCode: LanguageCode.it, 242 | value: 243 | "Il valore percentuale delle tasse da imporre sul prezzo di spedizione (opzionale)", 244 | }, 245 | ], 246 | }, 247 | }, 248 | calculate: calculateWeightBasedShippingCost, 249 | }); 250 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/checkers/args.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The minimum order value and maximum order weight args for the custom value- and weight-based shipping eligibility checkers 3 | */ 4 | 5 | import { LanguageCode } from "@vendure/core"; 6 | import { ConfigArgDef } from "@vendure/core/dist/common/configurable-operation"; 7 | 8 | export const minimumValue: ConfigArgDef<"int"> = { 9 | type: "int", 10 | config: { inputType: "money" }, 11 | ui: { component: "currency-form-input" }, 12 | label: [ 13 | { languageCode: LanguageCode.en, value: "Minimum order value" }, 14 | { languageCode: LanguageCode.it, value: "Valore minimo dell'ordine" }, 15 | ], 16 | description: [ 17 | { 18 | languageCode: LanguageCode.en, 19 | value: 20 | "Order is eligible only if its total is greater or equal to this value", 21 | }, 22 | { 23 | languageCode: LanguageCode.it, 24 | value: 25 | "L'ordine è adatto a questo metodo di spedizione solo se il suo valore è almeno pari a questo", 26 | }, 27 | ], 28 | }; 29 | 30 | export const maximumWeight: ConfigArgDef<"int"> = { 31 | type: "int", 32 | ui: { component: "number-form-input", options: { suffix: "kg" } }, 33 | label: [ 34 | { languageCode: LanguageCode.en, value: "Maximum order weight" }, 35 | { languageCode: LanguageCode.it, value: "Peso massimo dell'ordine" }, 36 | ], 37 | description: [ 38 | { 39 | languageCode: LanguageCode.en, 40 | value: 41 | "Order is eligible only if its total weight is at most equal to this value", 42 | }, 43 | { 44 | languageCode: LanguageCode.it, 45 | value: 46 | "L'ordine è adatto a questo metodo di spedizione solo se il suo peso totale è al massimo pari a questo", 47 | }, 48 | ], 49 | }; 50 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/checkers/functions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper functions to check if the order value is greater than a certain min threshold or lower than a weight threshold 3 | */ 4 | 5 | import { Order } from "@vendure/core"; 6 | import { getOrderWeight } from "../utils"; 7 | 8 | export const orderValueGreaterThan = ({ 9 | order, 10 | orderMinimum, 11 | }: { 12 | order: Order; 13 | orderMinimum?: number; 14 | }) => (orderMinimum ? order.totalWithTax >= orderMinimum : true); 15 | 16 | export const orderWeightLessThan = ({ 17 | order, 18 | maximumWeight, 19 | }: { 20 | order: Order; 21 | maximumWeight?: number; 22 | }) => { 23 | const orderWeight = getOrderWeight(order, "kg"); 24 | return maximumWeight ? orderWeight <= maximumWeight : true; 25 | }; 26 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/checkers/geoChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if the order shipping destination is among the selected zones or countries. 3 | * It's enough that the destination country is either inside one of the selected zones or corresponds 4 | * to one of the selected countries. 5 | */ 6 | 7 | import { 8 | ShippingEligibilityChecker, 9 | LanguageCode, 10 | Zone, 11 | TransactionalConnection, 12 | Injector, 13 | Country, 14 | } from "@vendure/core"; 15 | import { orderWeightLessThan, orderValueGreaterThan } from "./functions"; 16 | import { minimumValue, maximumWeight } from "./args"; 17 | 18 | let connection: TransactionalConnection; 19 | 20 | const getZoneMembers = (zoneName: string) => { 21 | return connection 22 | .getRepository(Zone) 23 | .findOne( 24 | { name: zoneName }, 25 | { 26 | relations: ["members"], 27 | } 28 | ) 29 | .then((zone) => { 30 | if (zone) return zone.members; 31 | }); 32 | }; 33 | 34 | export const orderGeoChecker = new ShippingEligibilityChecker({ 35 | init: async (injector: Injector) => { 36 | connection = injector.get(TransactionalConnection); 37 | }, 38 | code: "order-geo-checker", 39 | description: [ 40 | { 41 | languageCode: LanguageCode.en, 42 | value: "Location based", 43 | }, 44 | { 45 | languageCode: LanguageCode.it, 46 | value: "Criterio geografico", 47 | }, 48 | ], 49 | args: { 50 | zones: { 51 | type: "string", 52 | ui: { component: "zone-selector" }, 53 | list: true, 54 | label: [ 55 | { 56 | languageCode: LanguageCode.en, 57 | value: "Applicable Zone", 58 | }, 59 | { 60 | languageCode: LanguageCode.it, 61 | value: "Zona applicabile", 62 | }, 63 | ], 64 | }, 65 | countries: { 66 | type: "string", 67 | ui: { component: "country-selector" }, 68 | list: true, 69 | label: [ 70 | { 71 | languageCode: LanguageCode.en, 72 | value: "Country name", 73 | }, 74 | { 75 | languageCode: LanguageCode.it, 76 | value: "Nome nazione", 77 | }, 78 | ], 79 | }, 80 | orderMinimum: minimumValue, 81 | maximumWeight, 82 | }, 83 | check: async (ctx, order, args) => { 84 | const { orderMinimum, maximumWeight, zones, countries } = args; 85 | if ( 86 | !orderValueGreaterThan({ order, orderMinimum }) || 87 | !orderWeightLessThan({ order, maximumWeight }) 88 | ) 89 | return false; 90 | const argZones = zones.filter((zone) => zone !== ""); // zone names 91 | const argCountries = countries.filter((country) => country !== ""); // country codes 92 | const orderCountry = order.shippingAddress.countryCode; // order countrycode 93 | if (!orderCountry) return false; 94 | 95 | //check if (at least one) selected zone contains the order country 96 | if (argZones && argZones.length > 0) { 97 | // Create an array containing countries in args zones 98 | for (let zone of argZones) { 99 | const zoneMembers = (await getZoneMembers(zone))?.filter( 100 | (country) => country.enabled 101 | ); 102 | const zoneMembersCodes = 103 | zoneMembers?.map((country: Country) => country.code) || []; 104 | const matchingCountry = zoneMembersCodes.find( 105 | (country) => orderCountry === country 106 | ); 107 | if (matchingCountry) { 108 | return true; 109 | } 110 | } 111 | } 112 | 113 | //TODO: filter argCountries removing the disabled ones 114 | 115 | // zones condition is not satisfied... now checking country conditions 116 | if (argCountries && argCountries.length > 0) { 117 | const matchingCountry = argCountries.find( 118 | (country) => orderCountry === country 119 | ); 120 | if (matchingCountry) { 121 | return true; 122 | } 123 | } 124 | if (!argZones && !argCountries) return true; 125 | // Didn't find any matching area 126 | return false; 127 | }, 128 | }); 129 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/checkers/valueWeightChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if the total order value is over a certain min threshold AND at the same time the total weight is under a max threshold. 3 | */ 4 | 5 | import { LanguageCode, ShippingEligibilityChecker } from "@vendure/core"; 6 | import { orderWeightLessThan, orderValueGreaterThan } from "./functions"; 7 | import { minimumValue, maximumWeight } from "./args"; 8 | 9 | export const valueWeightShippingEligibilityChecker = 10 | new ShippingEligibilityChecker({ 11 | code: "value-shipping-eligibility-checker", 12 | description: [ 13 | { 14 | languageCode: LanguageCode.en, 15 | value: "Shipping Eligibility Checker based on order value and weight", 16 | }, 17 | { 18 | languageCode: LanguageCode.it, 19 | value: "Filtra in base al valore e al peso dell'ordine", 20 | }, 21 | ], 22 | args: { 23 | orderMinimum: minimumValue, 24 | maximumWeight, 25 | }, 26 | check: (ctx, order, args) => { 27 | const { orderMinimum, maximumWeight } = args; 28 | return ( 29 | orderValueGreaterThan({ order, orderMinimum }) && 30 | orderWeightLessThan({ order, maximumWeight }) 31 | ); 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const PLUGIN_INIT_OPTIONS = Symbol('PLUGIN_INIT_OPTIONS'); 2 | export const loggerCtx = 'ExtendedShipmentsPlugin'; 3 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/custom-fields.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * We need to add weight and weight unit of measure to the variants as custom fields. It is not required that all variants use 3 | * the same unit of measure: unit conversion is performed when evaluating the total order weight (see the relevant function) 4 | */ 5 | 6 | import { LanguageCode, CustomFields } from "@vendure/core"; 7 | 8 | const ProductVariantCustomFields: CustomFields["ProductVariant"] = [ 9 | { 10 | name: "weight", 11 | type: "float", 12 | min: 0, 13 | label: [ 14 | { languageCode: LanguageCode.en, value: "Weight" }, 15 | { languageCode: LanguageCode.it, value: "Peso" }, 16 | ], 17 | }, 18 | { 19 | name: "weightUoM", 20 | type: "string", 21 | options: [ 22 | { value: "g" }, 23 | { value: "kg" }, 24 | // { value: 'lb' }, { value: 'oz' } TODO: add these UoM 25 | ], 26 | label: [ 27 | { languageCode: LanguageCode.en, value: "Weight unit of measure" }, 28 | { languageCode: LanguageCode.it, value: "Unità di misura per il peso" }, 29 | ], 30 | }, 31 | ]; 32 | 33 | export default ProductVariantCustomFields; 34 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/index.ts: -------------------------------------------------------------------------------- 1 | export { ExtendedShipmentsPlugin } from './plugin'; -------------------------------------------------------------------------------- /plugins/extended-shipments/src/plugin.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configures the plugins by registering the checkers, the calculators, the custom fields and the UI extension 3 | */ 4 | 5 | import { 6 | PluginCommonModule, 7 | VendurePlugin, 8 | RuntimeVendureConfig, 9 | } from "@vendure/core"; 10 | import ProductVariantCustomFields from "./custom-fields"; 11 | import path from "path"; 12 | import { orderGeoChecker } from "./checkers/geoChecker"; 13 | import { AdminUiExtension } from "@vendure/ui-devkit/compiler"; 14 | import { valueWeightShippingEligibilityChecker } from "./checkers/valueWeightChecker"; 15 | import { flatRateShippingCalculator } from "./calculators/flatrateCalculator"; 16 | import { weightShippingCalculator } from "./calculators/weightCalculator"; 17 | 18 | @VendurePlugin({ 19 | imports: [PluginCommonModule], 20 | configuration: (config) => ExtendedShipmentsPlugin.configure(config), 21 | }) 22 | export class ExtendedShipmentsPlugin { 23 | constructor() {} 24 | 25 | static async configure( 26 | config: RuntimeVendureConfig 27 | ): Promise { 28 | config.customFields.ProductVariant.push(...ProductVariantCustomFields!); 29 | config!.shippingOptions!.shippingEligibilityCheckers!.push( 30 | valueWeightShippingEligibilityChecker 31 | ); 32 | config!.shippingOptions!.shippingEligibilityCheckers!.push(orderGeoChecker); 33 | config!.shippingOptions!.shippingCalculators!.push( 34 | weightShippingCalculator 35 | ); 36 | config!.shippingOptions!.shippingCalculators!.push( 37 | flatRateShippingCalculator 38 | ); 39 | return config; 40 | } 41 | 42 | // Note: we need to point to source files, as ui extension ts files are not compiled by the plugin, but by the Angular CLI (via compile script) 43 | static uiExtension: AdminUiExtension = { 44 | extensionPath: path.join(__dirname, "./ui"), 45 | ngModules: [ 46 | { 47 | type: "shared", 48 | ngModuleFileName: "geo-selector.module.ts", 49 | ngModuleName: "GeoSelectorModule", 50 | }, 51 | ], 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The weight unit of measures supported by this plugin 3 | */ 4 | 5 | export type WeightUnit = "g" | "kg"; 6 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/country-selector-component/country-selector.component.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | {{ item.name }} 14 | 15 | 16 | {{ item.name }} 17 | 18 | 19 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/country-selector-component/country-selector.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 90% 3 | } -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/country-selector-component/country-selector.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeDetectionStrategy, 3 | Component, 4 | Input, 5 | OnInit, 6 | } from "@angular/core"; 7 | import { FormControl } from "@angular/forms"; 8 | import { Observable } from "rxjs"; 9 | import { FormInputComponent } from "@vendure/admin-ui/core"; 10 | import { DataService } from "@vendure/admin-ui/core"; 11 | import { GetCountryList } from "@vendure/admin-ui/core"; 12 | import { map } from "rxjs/operators"; 13 | 14 | @Component({ 15 | selector: "vdr-country-selector", 16 | templateUrl: "./country-selector.component.html", 17 | styleUrls: ["./country-selector.component.scss"], 18 | changeDetection: ChangeDetectionStrategy.Default, 19 | }) 20 | export class CountrySelectorInputComponent 21 | implements FormInputComponent, OnInit 22 | { 23 | static readonly id: string = "country-selector"; 24 | @Input() readonly: boolean; 25 | formControl: FormControl; 26 | countries$: Observable; 27 | config: any; 28 | 29 | constructor(private dataService: DataService) {} 30 | 31 | ngOnInit() { 32 | this.countries$ = this.dataService.settings 33 | .getCountries(999) 34 | .mapStream((data) => data.countries.items) 35 | .pipe(map((countries) => countries.filter((c) => c.enabled))); 36 | } 37 | 38 | selectCountry(country: GetCountryList.Items) { 39 | if (country) this.formControl.setValue(country.code); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/zone-selector-component/zone-selector.component.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | {{ item.name }} 14 | 15 | 16 | {{ item.name }} 17 | 18 | 19 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/zone-selector-component/zone-selector.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 90% 3 | } -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/components/zone-selector-component/zone-selector.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | import { Observable } from 'rxjs'; 4 | import { FormInputComponent } from '@vendure/admin-ui/core'; 5 | import { DataService } from '@vendure/admin-ui/core'; 6 | import { GetZones } from '@vendure/admin-ui/core'; 7 | 8 | @Component({ 9 | selector: 'vdr-zone-selector', 10 | templateUrl: './zone-selector.component.html', 11 | styleUrls: ['./zone-selector.component.scss'], 12 | changeDetection: ChangeDetectionStrategy.Default, 13 | }) 14 | export class ZoneSelectorInputComponent implements FormInputComponent, OnInit { 15 | static readonly id: string = 'zone-selector'; 16 | @Input() readonly: boolean; 17 | formControl: FormControl; 18 | zones$: Observable; 19 | config: any; 20 | 21 | constructor(private dataService: DataService) {} 22 | 23 | ngOnInit() { 24 | this.zones$ = this.dataService.settings.getZones().mapStream(data => data.zones); 25 | } 26 | 27 | selectZone(zone: GetZones.Zones) { 28 | if(zone) this.formControl.setValue(zone.name); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/generated-types.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | export type Maybe = T | null; 3 | export type Exact = { [K in keyof T]: T[K] }; 4 | /** All built-in and custom scalars, mapped to their actual values */ 5 | export type Scalars = { 6 | ID: string; 7 | String: string; 8 | Boolean: boolean; 9 | Int: number; 10 | Float: number; 11 | /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */ 12 | DateTime: any; 13 | /** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */ 14 | JSON: any; 15 | /** The `Upload` scalar type represents a file upload. */ 16 | Upload: any; 17 | }; 18 | 19 | export type AddNoteToCustomerInput = { 20 | id: Scalars['ID']; 21 | note: Scalars['String']; 22 | isPublic: Scalars['Boolean']; 23 | }; 24 | 25 | export type AddNoteToOrderInput = { 26 | id: Scalars['ID']; 27 | note: Scalars['String']; 28 | isPublic: Scalars['Boolean']; 29 | }; 30 | 31 | export type Address = Node & { 32 | __typename?: 'Address'; 33 | id: Scalars['ID']; 34 | createdAt: Scalars['DateTime']; 35 | updatedAt: Scalars['DateTime']; 36 | fullName?: Maybe; 37 | company?: Maybe; 38 | streetLine1: Scalars['String']; 39 | streetLine2?: Maybe; 40 | city?: Maybe; 41 | province?: Maybe; 42 | postalCode?: Maybe; 43 | country: Country; 44 | phoneNumber?: Maybe; 45 | defaultShippingAddress?: Maybe; 46 | defaultBillingAddress?: Maybe; 47 | customFields?: Maybe; 48 | }; 49 | 50 | export type Adjustment = { 51 | __typename?: 'Adjustment'; 52 | adjustmentSource: Scalars['String']; 53 | type: AdjustmentType; 54 | description: Scalars['String']; 55 | amount: Scalars['Int']; 56 | }; 57 | 58 | export enum AdjustmentType { 59 | Tax = 'TAX', 60 | Promotion = 'PROMOTION', 61 | Shipping = 'SHIPPING', 62 | Refund = 'REFUND', 63 | TaxRefund = 'TAX_REFUND', 64 | PromotionRefund = 'PROMOTION_REFUND', 65 | ShippingRefund = 'SHIPPING_REFUND' 66 | } 67 | 68 | export type Administrator = Node & { 69 | __typename?: 'Administrator'; 70 | id: Scalars['ID']; 71 | createdAt: Scalars['DateTime']; 72 | updatedAt: Scalars['DateTime']; 73 | firstName: Scalars['String']; 74 | lastName: Scalars['String']; 75 | emailAddress: Scalars['String']; 76 | user: User; 77 | }; 78 | 79 | export type AdministratorFilterParameter = { 80 | createdAt?: Maybe; 81 | updatedAt?: Maybe; 82 | firstName?: Maybe; 83 | lastName?: Maybe; 84 | emailAddress?: Maybe; 85 | }; 86 | 87 | export type AdministratorList = PaginatedList & { 88 | __typename?: 'AdministratorList'; 89 | items: Array; 90 | totalItems: Scalars['Int']; 91 | }; 92 | 93 | export type AdministratorListOptions = { 94 | skip?: Maybe; 95 | take?: Maybe; 96 | sort?: Maybe; 97 | filter?: Maybe; 98 | }; 99 | 100 | export type AdministratorSortParameter = { 101 | id?: Maybe; 102 | createdAt?: Maybe; 103 | updatedAt?: Maybe; 104 | firstName?: Maybe; 105 | lastName?: Maybe; 106 | emailAddress?: Maybe; 107 | }; 108 | 109 | export type Asset = Node & { 110 | __typename?: 'Asset'; 111 | id: Scalars['ID']; 112 | createdAt: Scalars['DateTime']; 113 | updatedAt: Scalars['DateTime']; 114 | name: Scalars['String']; 115 | type: AssetType; 116 | fileSize: Scalars['Int']; 117 | mimeType: Scalars['String']; 118 | width: Scalars['Int']; 119 | height: Scalars['Int']; 120 | source: Scalars['String']; 121 | preview: Scalars['String']; 122 | focalPoint?: Maybe; 123 | }; 124 | 125 | export type AssetFilterParameter = { 126 | createdAt?: Maybe; 127 | updatedAt?: Maybe; 128 | name?: Maybe; 129 | type?: Maybe; 130 | fileSize?: Maybe; 131 | mimeType?: Maybe; 132 | width?: Maybe; 133 | height?: Maybe; 134 | source?: Maybe; 135 | preview?: Maybe; 136 | }; 137 | 138 | export type AssetList = PaginatedList & { 139 | __typename?: 'AssetList'; 140 | items: Array; 141 | totalItems: Scalars['Int']; 142 | }; 143 | 144 | export type AssetListOptions = { 145 | skip?: Maybe; 146 | take?: Maybe; 147 | sort?: Maybe; 148 | filter?: Maybe; 149 | }; 150 | 151 | export type AssetSortParameter = { 152 | id?: Maybe; 153 | createdAt?: Maybe; 154 | updatedAt?: Maybe; 155 | name?: Maybe; 156 | fileSize?: Maybe; 157 | mimeType?: Maybe; 158 | width?: Maybe; 159 | height?: Maybe; 160 | source?: Maybe; 161 | preview?: Maybe; 162 | }; 163 | 164 | export enum AssetType { 165 | Image = 'IMAGE', 166 | Video = 'VIDEO', 167 | Binary = 'BINARY' 168 | } 169 | 170 | export type AssignProductsToChannelInput = { 171 | productIds: Array; 172 | channelId: Scalars['ID']; 173 | priceFactor?: Maybe; 174 | }; 175 | 176 | export type AuthenticationInput = { 177 | native?: Maybe; 178 | }; 179 | 180 | export type AuthenticationMethod = Node & { 181 | __typename?: 'AuthenticationMethod'; 182 | id: Scalars['ID']; 183 | createdAt: Scalars['DateTime']; 184 | updatedAt: Scalars['DateTime']; 185 | strategy: Scalars['String']; 186 | }; 187 | 188 | export type BooleanCustomFieldConfig = CustomField & { 189 | __typename?: 'BooleanCustomFieldConfig'; 190 | name: Scalars['String']; 191 | type: Scalars['String']; 192 | label?: Maybe>; 193 | description?: Maybe>; 194 | readonly?: Maybe; 195 | internal?: Maybe; 196 | }; 197 | 198 | export type BooleanOperators = { 199 | eq?: Maybe; 200 | }; 201 | 202 | export type Cancellation = Node & StockMovement & { 203 | __typename?: 'Cancellation'; 204 | id: Scalars['ID']; 205 | createdAt: Scalars['DateTime']; 206 | updatedAt: Scalars['DateTime']; 207 | productVariant: ProductVariant; 208 | type: StockMovementType; 209 | quantity: Scalars['Int']; 210 | orderLine: OrderLine; 211 | }; 212 | 213 | export type CancelOrderInput = { 214 | /** The id of the order to be cancelled */ 215 | orderId: Scalars['ID']; 216 | /** Optionally specify which OrderLines to cancel. If not provided, all OrderLines will be cancelled */ 217 | lines?: Maybe>; 218 | reason?: Maybe; 219 | }; 220 | 221 | export type Channel = Node & { 222 | __typename?: 'Channel'; 223 | id: Scalars['ID']; 224 | createdAt: Scalars['DateTime']; 225 | updatedAt: Scalars['DateTime']; 226 | code: Scalars['String']; 227 | token: Scalars['String']; 228 | defaultTaxZone?: Maybe; 229 | defaultShippingZone?: Maybe; 230 | defaultLanguageCode: LanguageCode; 231 | currencyCode: CurrencyCode; 232 | pricesIncludeTax: Scalars['Boolean']; 233 | }; 234 | 235 | export type Collection = Node & { 236 | __typename?: 'Collection'; 237 | isPrivate: Scalars['Boolean']; 238 | id: Scalars['ID']; 239 | createdAt: Scalars['DateTime']; 240 | updatedAt: Scalars['DateTime']; 241 | languageCode?: Maybe; 242 | name: Scalars['String']; 243 | slug: Scalars['String']; 244 | breadcrumbs: Array; 245 | position: Scalars['Int']; 246 | description: Scalars['String']; 247 | featuredAsset?: Maybe; 248 | assets: Array; 249 | parent?: Maybe; 250 | children?: Maybe>; 251 | filters: Array; 252 | translations: Array; 253 | productVariants: ProductVariantList; 254 | customFields?: Maybe; 255 | }; 256 | 257 | 258 | export type CollectionProductVariantsArgs = { 259 | options?: Maybe; 260 | }; 261 | 262 | export type CollectionBreadcrumb = { 263 | __typename?: 'CollectionBreadcrumb'; 264 | id: Scalars['ID']; 265 | name: Scalars['String']; 266 | slug: Scalars['String']; 267 | }; 268 | 269 | export type CollectionFilterParameter = { 270 | isPrivate?: Maybe; 271 | createdAt?: Maybe; 272 | updatedAt?: Maybe; 273 | languageCode?: Maybe; 274 | name?: Maybe; 275 | slug?: Maybe; 276 | position?: Maybe; 277 | description?: Maybe; 278 | }; 279 | 280 | export type CollectionList = PaginatedList & { 281 | __typename?: 'CollectionList'; 282 | items: Array; 283 | totalItems: Scalars['Int']; 284 | }; 285 | 286 | export type CollectionListOptions = { 287 | skip?: Maybe; 288 | take?: Maybe; 289 | sort?: Maybe; 290 | filter?: Maybe; 291 | }; 292 | 293 | export type CollectionSortParameter = { 294 | id?: Maybe; 295 | createdAt?: Maybe; 296 | updatedAt?: Maybe; 297 | name?: Maybe; 298 | slug?: Maybe; 299 | position?: Maybe; 300 | description?: Maybe; 301 | }; 302 | 303 | export type CollectionTranslation = { 304 | __typename?: 'CollectionTranslation'; 305 | id: Scalars['ID']; 306 | createdAt: Scalars['DateTime']; 307 | updatedAt: Scalars['DateTime']; 308 | languageCode: LanguageCode; 309 | name: Scalars['String']; 310 | slug: Scalars['String']; 311 | description: Scalars['String']; 312 | }; 313 | 314 | export type ConfigArg = { 315 | __typename?: 'ConfigArg'; 316 | name: Scalars['String']; 317 | type: Scalars['String']; 318 | value: Scalars['String']; 319 | }; 320 | 321 | export type ConfigArgDefinition = { 322 | __typename?: 'ConfigArgDefinition'; 323 | name: Scalars['String']; 324 | type: Scalars['String']; 325 | label?: Maybe; 326 | description?: Maybe; 327 | config?: Maybe; 328 | }; 329 | 330 | export type ConfigArgInput = { 331 | name: Scalars['String']; 332 | type: Scalars['String']; 333 | value: Scalars['String']; 334 | }; 335 | 336 | export type ConfigurableOperation = { 337 | __typename?: 'ConfigurableOperation'; 338 | code: Scalars['String']; 339 | args: Array; 340 | }; 341 | 342 | export type ConfigurableOperationDefinition = { 343 | __typename?: 'ConfigurableOperationDefinition'; 344 | code: Scalars['String']; 345 | args: Array; 346 | description: Scalars['String']; 347 | }; 348 | 349 | export type ConfigurableOperationInput = { 350 | code: Scalars['String']; 351 | arguments: Array; 352 | }; 353 | 354 | export type Coordinate = { 355 | __typename?: 'Coordinate'; 356 | x: Scalars['Float']; 357 | y: Scalars['Float']; 358 | }; 359 | 360 | export type CoordinateInput = { 361 | x: Scalars['Float']; 362 | y: Scalars['Float']; 363 | }; 364 | 365 | export type Country = Node & { 366 | __typename?: 'Country'; 367 | id: Scalars['ID']; 368 | createdAt: Scalars['DateTime']; 369 | updatedAt: Scalars['DateTime']; 370 | languageCode: LanguageCode; 371 | code: Scalars['String']; 372 | name: Scalars['String']; 373 | enabled: Scalars['Boolean']; 374 | translations: Array; 375 | }; 376 | 377 | export type CountryFilterParameter = { 378 | createdAt?: Maybe; 379 | updatedAt?: Maybe; 380 | languageCode?: Maybe; 381 | code?: Maybe; 382 | name?: Maybe; 383 | enabled?: Maybe; 384 | }; 385 | 386 | export type CountryList = PaginatedList & { 387 | __typename?: 'CountryList'; 388 | items: Array; 389 | totalItems: Scalars['Int']; 390 | }; 391 | 392 | export type CountryListOptions = { 393 | skip?: Maybe; 394 | take?: Maybe; 395 | sort?: Maybe; 396 | filter?: Maybe; 397 | }; 398 | 399 | export type CountrySortParameter = { 400 | id?: Maybe; 401 | createdAt?: Maybe; 402 | updatedAt?: Maybe; 403 | code?: Maybe; 404 | name?: Maybe; 405 | }; 406 | 407 | export type CountryTranslation = { 408 | __typename?: 'CountryTranslation'; 409 | id: Scalars['ID']; 410 | createdAt: Scalars['DateTime']; 411 | updatedAt: Scalars['DateTime']; 412 | languageCode: LanguageCode; 413 | name: Scalars['String']; 414 | }; 415 | 416 | export type CountryTranslationInput = { 417 | id?: Maybe; 418 | languageCode: LanguageCode; 419 | name?: Maybe; 420 | }; 421 | 422 | export type CreateAddressInput = { 423 | fullName?: Maybe; 424 | company?: Maybe; 425 | streetLine1: Scalars['String']; 426 | streetLine2?: Maybe; 427 | city?: Maybe; 428 | province?: Maybe; 429 | postalCode?: Maybe; 430 | countryCode: Scalars['String']; 431 | phoneNumber?: Maybe; 432 | defaultShippingAddress?: Maybe; 433 | defaultBillingAddress?: Maybe; 434 | customFields?: Maybe; 435 | }; 436 | 437 | export type CreateAdministratorInput = { 438 | firstName: Scalars['String']; 439 | lastName: Scalars['String']; 440 | emailAddress: Scalars['String']; 441 | password: Scalars['String']; 442 | roleIds: Array; 443 | }; 444 | 445 | export type CreateAssetInput = { 446 | file: Scalars['Upload']; 447 | }; 448 | 449 | export type CreateChannelInput = { 450 | code: Scalars['String']; 451 | token: Scalars['String']; 452 | defaultLanguageCode: LanguageCode; 453 | pricesIncludeTax: Scalars['Boolean']; 454 | currencyCode: CurrencyCode; 455 | defaultTaxZoneId: Scalars['ID']; 456 | defaultShippingZoneId: Scalars['ID']; 457 | }; 458 | 459 | export type CreateCollectionInput = { 460 | isPrivate?: Maybe; 461 | featuredAssetId?: Maybe; 462 | assetIds?: Maybe>; 463 | parentId?: Maybe; 464 | filters: Array; 465 | translations: Array; 466 | customFields?: Maybe; 467 | }; 468 | 469 | export type CreateCollectionTranslationInput = { 470 | languageCode: LanguageCode; 471 | name: Scalars['String']; 472 | slug: Scalars['String']; 473 | description: Scalars['String']; 474 | customFields?: Maybe; 475 | }; 476 | 477 | export type CreateCountryInput = { 478 | code: Scalars['String']; 479 | translations: Array; 480 | enabled: Scalars['Boolean']; 481 | }; 482 | 483 | export type CreateCustomerGroupInput = { 484 | name: Scalars['String']; 485 | customerIds?: Maybe>; 486 | }; 487 | 488 | export type CreateCustomerInput = { 489 | title?: Maybe; 490 | firstName: Scalars['String']; 491 | lastName: Scalars['String']; 492 | phoneNumber?: Maybe; 493 | emailAddress: Scalars['String']; 494 | customFields?: Maybe; 495 | }; 496 | 497 | export type CreateExampleInput = { 498 | name: Scalars['String']; 499 | }; 500 | 501 | export type CreateFacetInput = { 502 | code: Scalars['String']; 503 | isPrivate: Scalars['Boolean']; 504 | translations: Array; 505 | values?: Maybe>; 506 | customFields?: Maybe; 507 | }; 508 | 509 | export type CreateFacetValueInput = { 510 | facetId: Scalars['ID']; 511 | code: Scalars['String']; 512 | translations: Array; 513 | customFields?: Maybe; 514 | }; 515 | 516 | export type CreateFacetValueWithFacetInput = { 517 | code: Scalars['String']; 518 | translations: Array; 519 | }; 520 | 521 | export type CreateGroupOptionInput = { 522 | code: Scalars['String']; 523 | translations: Array; 524 | }; 525 | 526 | export type CreateProductInput = { 527 | featuredAssetId?: Maybe; 528 | assetIds?: Maybe>; 529 | facetValueIds?: Maybe>; 530 | translations: Array; 531 | customFields?: Maybe; 532 | }; 533 | 534 | export type CreateProductOptionGroupInput = { 535 | code: Scalars['String']; 536 | translations: Array; 537 | options: Array; 538 | customFields?: Maybe; 539 | }; 540 | 541 | export type CreateProductOptionInput = { 542 | productOptionGroupId: Scalars['ID']; 543 | code: Scalars['String']; 544 | translations: Array; 545 | customFields?: Maybe; 546 | }; 547 | 548 | export type CreateProductVariantInput = { 549 | productId: Scalars['ID']; 550 | translations: Array; 551 | facetValueIds?: Maybe>; 552 | sku: Scalars['String']; 553 | price?: Maybe; 554 | taxCategoryId?: Maybe; 555 | optionIds?: Maybe>; 556 | featuredAssetId?: Maybe; 557 | assetIds?: Maybe>; 558 | stockOnHand?: Maybe; 559 | trackInventory?: Maybe; 560 | customFields?: Maybe; 561 | }; 562 | 563 | export type CreateProductVariantOptionInput = { 564 | optionGroupId: Scalars['ID']; 565 | code: Scalars['String']; 566 | translations: Array; 567 | }; 568 | 569 | export type CreatePromotionInput = { 570 | name: Scalars['String']; 571 | enabled: Scalars['Boolean']; 572 | startsAt?: Maybe; 573 | endsAt?: Maybe; 574 | couponCode?: Maybe; 575 | perCustomerUsageLimit?: Maybe; 576 | conditions: Array; 577 | actions: Array; 578 | }; 579 | 580 | export type CreateRoleInput = { 581 | code: Scalars['String']; 582 | description: Scalars['String']; 583 | permissions: Array; 584 | channelIds?: Maybe>; 585 | }; 586 | 587 | export type CreateShippingMethodInput = { 588 | code: Scalars['String']; 589 | description: Scalars['String']; 590 | checker: ConfigurableOperationInput; 591 | calculator: ConfigurableOperationInput; 592 | customFields?: Maybe; 593 | }; 594 | 595 | export type CreateTaxCategoryInput = { 596 | name: Scalars['String']; 597 | }; 598 | 599 | export type CreateTaxRateInput = { 600 | name: Scalars['String']; 601 | enabled: Scalars['Boolean']; 602 | value: Scalars['Float']; 603 | categoryId: Scalars['ID']; 604 | zoneId: Scalars['ID']; 605 | customerGroupId?: Maybe; 606 | }; 607 | 608 | export type CreateZoneInput = { 609 | name: Scalars['String']; 610 | memberIds?: Maybe>; 611 | }; 612 | 613 | /** 614 | * @description 615 | * ISO 4217 currency code 616 | * 617 | * @docsCategory common 618 | */ 619 | export enum CurrencyCode { 620 | /** United Arab Emirates dirham */ 621 | Aed = 'AED', 622 | /** Afghan afghani */ 623 | Afn = 'AFN', 624 | /** Albanian lek */ 625 | All = 'ALL', 626 | /** Armenian dram */ 627 | Amd = 'AMD', 628 | /** Netherlands Antillean guilder */ 629 | Ang = 'ANG', 630 | /** Angolan kwanza */ 631 | Aoa = 'AOA', 632 | /** Argentine peso */ 633 | Ars = 'ARS', 634 | /** Australian dollar */ 635 | Aud = 'AUD', 636 | /** Aruban florin */ 637 | Awg = 'AWG', 638 | /** Azerbaijani manat */ 639 | Azn = 'AZN', 640 | /** Bosnia and Herzegovina convertible mark */ 641 | Bam = 'BAM', 642 | /** Barbados dollar */ 643 | Bbd = 'BBD', 644 | /** Bangladeshi taka */ 645 | Bdt = 'BDT', 646 | /** Bulgarian lev */ 647 | Bgn = 'BGN', 648 | /** Bahraini dinar */ 649 | Bhd = 'BHD', 650 | /** Burundian franc */ 651 | Bif = 'BIF', 652 | /** Bermudian dollar */ 653 | Bmd = 'BMD', 654 | /** Brunei dollar */ 655 | Bnd = 'BND', 656 | /** Boliviano */ 657 | Bob = 'BOB', 658 | /** Brazilian real */ 659 | Brl = 'BRL', 660 | /** Bahamian dollar */ 661 | Bsd = 'BSD', 662 | /** Bhutanese ngultrum */ 663 | Btn = 'BTN', 664 | /** Botswana pula */ 665 | Bwp = 'BWP', 666 | /** Belarusian ruble */ 667 | Byn = 'BYN', 668 | /** Belize dollar */ 669 | Bzd = 'BZD', 670 | /** Canadian dollar */ 671 | Cad = 'CAD', 672 | /** Congolese franc */ 673 | Cdf = 'CDF', 674 | /** Swiss franc */ 675 | Chf = 'CHF', 676 | /** Chilean peso */ 677 | Clp = 'CLP', 678 | /** Renminbi (Chinese) yuan */ 679 | Cny = 'CNY', 680 | /** Colombian peso */ 681 | Cop = 'COP', 682 | /** Costa Rican colon */ 683 | Crc = 'CRC', 684 | /** Cuban convertible peso */ 685 | Cuc = 'CUC', 686 | /** Cuban peso */ 687 | Cup = 'CUP', 688 | /** Cape Verde escudo */ 689 | Cve = 'CVE', 690 | /** Czech koruna */ 691 | Czk = 'CZK', 692 | /** Djiboutian franc */ 693 | Djf = 'DJF', 694 | /** Danish krone */ 695 | Dkk = 'DKK', 696 | /** Dominican peso */ 697 | Dop = 'DOP', 698 | /** Algerian dinar */ 699 | Dzd = 'DZD', 700 | /** Egyptian pound */ 701 | Egp = 'EGP', 702 | /** Eritrean nakfa */ 703 | Ern = 'ERN', 704 | /** Ethiopian birr */ 705 | Etb = 'ETB', 706 | /** Euro */ 707 | Eur = 'EUR', 708 | /** Fiji dollar */ 709 | Fjd = 'FJD', 710 | /** Falkland Islands pound */ 711 | Fkp = 'FKP', 712 | /** Pound sterling */ 713 | Gbp = 'GBP', 714 | /** Georgian lari */ 715 | Gel = 'GEL', 716 | /** Ghanaian cedi */ 717 | Ghs = 'GHS', 718 | /** Gibraltar pound */ 719 | Gip = 'GIP', 720 | /** Gambian dalasi */ 721 | Gmd = 'GMD', 722 | /** Guinean franc */ 723 | Gnf = 'GNF', 724 | /** Guatemalan quetzal */ 725 | Gtq = 'GTQ', 726 | /** Guyanese dollar */ 727 | Gyd = 'GYD', 728 | /** Hong Kong dollar */ 729 | Hkd = 'HKD', 730 | /** Honduran lempira */ 731 | Hnl = 'HNL', 732 | /** Croatian kuna */ 733 | Hrk = 'HRK', 734 | /** Haitian gourde */ 735 | Htg = 'HTG', 736 | /** Hungarian forint */ 737 | Huf = 'HUF', 738 | /** Indonesian rupiah */ 739 | Idr = 'IDR', 740 | /** Israeli new shekel */ 741 | Ils = 'ILS', 742 | /** Indian rupee */ 743 | Inr = 'INR', 744 | /** Iraqi dinar */ 745 | Iqd = 'IQD', 746 | /** Iranian rial */ 747 | Irr = 'IRR', 748 | /** Icelandic króna */ 749 | Isk = 'ISK', 750 | /** Jamaican dollar */ 751 | Jmd = 'JMD', 752 | /** Jordanian dinar */ 753 | Jod = 'JOD', 754 | /** Japanese yen */ 755 | Jpy = 'JPY', 756 | /** Kenyan shilling */ 757 | Kes = 'KES', 758 | /** Kyrgyzstani som */ 759 | Kgs = 'KGS', 760 | /** Cambodian riel */ 761 | Khr = 'KHR', 762 | /** Comoro franc */ 763 | Kmf = 'KMF', 764 | /** North Korean won */ 765 | Kpw = 'KPW', 766 | /** South Korean won */ 767 | Krw = 'KRW', 768 | /** Kuwaiti dinar */ 769 | Kwd = 'KWD', 770 | /** Cayman Islands dollar */ 771 | Kyd = 'KYD', 772 | /** Kazakhstani tenge */ 773 | Kzt = 'KZT', 774 | /** Lao kip */ 775 | Lak = 'LAK', 776 | /** Lebanese pound */ 777 | Lbp = 'LBP', 778 | /** Sri Lankan rupee */ 779 | Lkr = 'LKR', 780 | /** Liberian dollar */ 781 | Lrd = 'LRD', 782 | /** Lesotho loti */ 783 | Lsl = 'LSL', 784 | /** Libyan dinar */ 785 | Lyd = 'LYD', 786 | /** Moroccan dirham */ 787 | Mad = 'MAD', 788 | /** Moldovan leu */ 789 | Mdl = 'MDL', 790 | /** Malagasy ariary */ 791 | Mga = 'MGA', 792 | /** Macedonian denar */ 793 | Mkd = 'MKD', 794 | /** Myanmar kyat */ 795 | Mmk = 'MMK', 796 | /** Mongolian tögrög */ 797 | Mnt = 'MNT', 798 | /** Macanese pataca */ 799 | Mop = 'MOP', 800 | /** Mauritanian ouguiya */ 801 | Mru = 'MRU', 802 | /** Mauritian rupee */ 803 | Mur = 'MUR', 804 | /** Maldivian rufiyaa */ 805 | Mvr = 'MVR', 806 | /** Malawian kwacha */ 807 | Mwk = 'MWK', 808 | /** Mexican peso */ 809 | Mxn = 'MXN', 810 | /** Malaysian ringgit */ 811 | Myr = 'MYR', 812 | /** Mozambican metical */ 813 | Mzn = 'MZN', 814 | /** Namibian dollar */ 815 | Nad = 'NAD', 816 | /** Nigerian naira */ 817 | Ngn = 'NGN', 818 | /** Nicaraguan córdoba */ 819 | Nio = 'NIO', 820 | /** Norwegian krone */ 821 | Nok = 'NOK', 822 | /** Nepalese rupee */ 823 | Npr = 'NPR', 824 | /** New Zealand dollar */ 825 | Nzd = 'NZD', 826 | /** Omani rial */ 827 | Omr = 'OMR', 828 | /** Panamanian balboa */ 829 | Pab = 'PAB', 830 | /** Peruvian sol */ 831 | Pen = 'PEN', 832 | /** Papua New Guinean kina */ 833 | Pgk = 'PGK', 834 | /** Philippine peso */ 835 | Php = 'PHP', 836 | /** Pakistani rupee */ 837 | Pkr = 'PKR', 838 | /** Polish złoty */ 839 | Pln = 'PLN', 840 | /** Paraguayan guaraní */ 841 | Pyg = 'PYG', 842 | /** Qatari riyal */ 843 | Qar = 'QAR', 844 | /** Romanian leu */ 845 | Ron = 'RON', 846 | /** Serbian dinar */ 847 | Rsd = 'RSD', 848 | /** Russian ruble */ 849 | Rub = 'RUB', 850 | /** Rwandan franc */ 851 | Rwf = 'RWF', 852 | /** Saudi riyal */ 853 | Sar = 'SAR', 854 | /** Solomon Islands dollar */ 855 | Sbd = 'SBD', 856 | /** Seychelles rupee */ 857 | Scr = 'SCR', 858 | /** Sudanese pound */ 859 | Sdg = 'SDG', 860 | /** Swedish krona/kronor */ 861 | Sek = 'SEK', 862 | /** Singapore dollar */ 863 | Sgd = 'SGD', 864 | /** Saint Helena pound */ 865 | Shp = 'SHP', 866 | /** Sierra Leonean leone */ 867 | Sll = 'SLL', 868 | /** Somali shilling */ 869 | Sos = 'SOS', 870 | /** Surinamese dollar */ 871 | Srd = 'SRD', 872 | /** South Sudanese pound */ 873 | Ssp = 'SSP', 874 | /** São Tomé and Príncipe dobra */ 875 | Stn = 'STN', 876 | /** Salvadoran colón */ 877 | Svc = 'SVC', 878 | /** Syrian pound */ 879 | Syp = 'SYP', 880 | /** Swazi lilangeni */ 881 | Szl = 'SZL', 882 | /** Thai baht */ 883 | Thb = 'THB', 884 | /** Tajikistani somoni */ 885 | Tjs = 'TJS', 886 | /** Turkmenistan manat */ 887 | Tmt = 'TMT', 888 | /** Tunisian dinar */ 889 | Tnd = 'TND', 890 | /** Tongan paʻanga */ 891 | Top = 'TOP', 892 | /** Turkish lira */ 893 | Try = 'TRY', 894 | /** Trinidad and Tobago dollar */ 895 | Ttd = 'TTD', 896 | /** New Taiwan dollar */ 897 | Twd = 'TWD', 898 | /** Tanzanian shilling */ 899 | Tzs = 'TZS', 900 | /** Ukrainian hryvnia */ 901 | Uah = 'UAH', 902 | /** Ugandan shilling */ 903 | Ugx = 'UGX', 904 | /** United States dollar */ 905 | Usd = 'USD', 906 | /** Uruguayan peso */ 907 | Uyu = 'UYU', 908 | /** Uzbekistan som */ 909 | Uzs = 'UZS', 910 | /** Venezuelan bolívar soberano */ 911 | Ves = 'VES', 912 | /** Vietnamese đồng */ 913 | Vnd = 'VND', 914 | /** Vanuatu vatu */ 915 | Vuv = 'VUV', 916 | /** Samoan tala */ 917 | Wst = 'WST', 918 | /** CFA franc BEAC */ 919 | Xaf = 'XAF', 920 | /** East Caribbean dollar */ 921 | Xcd = 'XCD', 922 | /** CFA franc BCEAO */ 923 | Xof = 'XOF', 924 | /** CFP franc (franc Pacifique) */ 925 | Xpf = 'XPF', 926 | /** Yemeni rial */ 927 | Yer = 'YER', 928 | /** South African rand */ 929 | Zar = 'ZAR', 930 | /** Zambian kwacha */ 931 | Zmw = 'ZMW', 932 | /** Zimbabwean dollar */ 933 | Zwl = 'ZWL' 934 | } 935 | 936 | export type CurrentUser = { 937 | __typename?: 'CurrentUser'; 938 | id: Scalars['ID']; 939 | identifier: Scalars['String']; 940 | channels: Array; 941 | }; 942 | 943 | export type CurrentUserChannel = { 944 | __typename?: 'CurrentUserChannel'; 945 | id: Scalars['ID']; 946 | token: Scalars['String']; 947 | code: Scalars['String']; 948 | permissions: Array; 949 | }; 950 | 951 | export type Customer = Node & { 952 | __typename?: 'Customer'; 953 | groups: Array; 954 | history: HistoryEntryList; 955 | id: Scalars['ID']; 956 | createdAt: Scalars['DateTime']; 957 | updatedAt: Scalars['DateTime']; 958 | title?: Maybe; 959 | firstName: Scalars['String']; 960 | lastName: Scalars['String']; 961 | phoneNumber?: Maybe; 962 | emailAddress: Scalars['String']; 963 | addresses?: Maybe>; 964 | orders: OrderList; 965 | user?: Maybe; 966 | customFields?: Maybe; 967 | }; 968 | 969 | 970 | export type CustomerHistoryArgs = { 971 | options?: Maybe; 972 | }; 973 | 974 | 975 | export type CustomerOrdersArgs = { 976 | options?: Maybe; 977 | }; 978 | 979 | export type CustomerFilterParameter = { 980 | createdAt?: Maybe; 981 | updatedAt?: Maybe; 982 | title?: Maybe; 983 | firstName?: Maybe; 984 | lastName?: Maybe; 985 | phoneNumber?: Maybe; 986 | emailAddress?: Maybe; 987 | }; 988 | 989 | export type CustomerGroup = Node & { 990 | __typename?: 'CustomerGroup'; 991 | id: Scalars['ID']; 992 | createdAt: Scalars['DateTime']; 993 | updatedAt: Scalars['DateTime']; 994 | name: Scalars['String']; 995 | customers: CustomerList; 996 | }; 997 | 998 | 999 | export type CustomerGroupCustomersArgs = { 1000 | options?: Maybe; 1001 | }; 1002 | 1003 | export type CustomerGroupFilterParameter = { 1004 | createdAt?: Maybe; 1005 | updatedAt?: Maybe; 1006 | name?: Maybe; 1007 | }; 1008 | 1009 | export type CustomerGroupList = PaginatedList & { 1010 | __typename?: 'CustomerGroupList'; 1011 | items: Array; 1012 | totalItems: Scalars['Int']; 1013 | }; 1014 | 1015 | export type CustomerGroupListOptions = { 1016 | skip?: Maybe; 1017 | take?: Maybe; 1018 | sort?: Maybe; 1019 | filter?: Maybe; 1020 | }; 1021 | 1022 | export type CustomerGroupSortParameter = { 1023 | id?: Maybe; 1024 | createdAt?: Maybe; 1025 | updatedAt?: Maybe; 1026 | name?: Maybe; 1027 | }; 1028 | 1029 | export type CustomerList = PaginatedList & { 1030 | __typename?: 'CustomerList'; 1031 | items: Array; 1032 | totalItems: Scalars['Int']; 1033 | }; 1034 | 1035 | export type CustomerListOptions = { 1036 | skip?: Maybe; 1037 | take?: Maybe; 1038 | sort?: Maybe; 1039 | filter?: Maybe; 1040 | }; 1041 | 1042 | export type CustomerSortParameter = { 1043 | id?: Maybe; 1044 | createdAt?: Maybe; 1045 | updatedAt?: Maybe; 1046 | title?: Maybe; 1047 | firstName?: Maybe; 1048 | lastName?: Maybe; 1049 | phoneNumber?: Maybe; 1050 | emailAddress?: Maybe; 1051 | }; 1052 | 1053 | export type CustomField = { 1054 | name: Scalars['String']; 1055 | type: Scalars['String']; 1056 | label?: Maybe>; 1057 | description?: Maybe>; 1058 | readonly?: Maybe; 1059 | internal?: Maybe; 1060 | }; 1061 | 1062 | export type CustomFieldConfig = StringCustomFieldConfig | LocaleStringCustomFieldConfig | IntCustomFieldConfig | FloatCustomFieldConfig | BooleanCustomFieldConfig | DateTimeCustomFieldConfig; 1063 | 1064 | export type CustomFields = { 1065 | __typename?: 'CustomFields'; 1066 | Address: Array; 1067 | Collection: Array; 1068 | Customer: Array; 1069 | Facet: Array; 1070 | FacetValue: Array; 1071 | GlobalSettings: Array; 1072 | Order: Array; 1073 | OrderLine: Array; 1074 | Product: Array; 1075 | ProductOption: Array; 1076 | ProductOptionGroup: Array; 1077 | ProductVariant: Array; 1078 | User: Array; 1079 | ShippingMethod: Array; 1080 | }; 1081 | 1082 | export type DateOperators = { 1083 | eq?: Maybe; 1084 | before?: Maybe; 1085 | after?: Maybe; 1086 | between?: Maybe; 1087 | }; 1088 | 1089 | export type DateRange = { 1090 | start: Scalars['DateTime']; 1091 | end: Scalars['DateTime']; 1092 | }; 1093 | 1094 | 1095 | /** 1096 | * Expects the same validation formats as the `` HTML element. 1097 | * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes 1098 | */ 1099 | export type DateTimeCustomFieldConfig = CustomField & { 1100 | __typename?: 'DateTimeCustomFieldConfig'; 1101 | name: Scalars['String']; 1102 | type: Scalars['String']; 1103 | label?: Maybe>; 1104 | description?: Maybe>; 1105 | readonly?: Maybe; 1106 | internal?: Maybe; 1107 | min?: Maybe; 1108 | max?: Maybe; 1109 | step?: Maybe; 1110 | }; 1111 | 1112 | export type DeletionResponse = { 1113 | __typename?: 'DeletionResponse'; 1114 | result: DeletionResult; 1115 | message?: Maybe; 1116 | }; 1117 | 1118 | export enum DeletionResult { 1119 | /** The entity was successfully deleted */ 1120 | Deleted = 'DELETED', 1121 | /** Deletion did not take place, reason given in message */ 1122 | NotDeleted = 'NOT_DELETED' 1123 | } 1124 | 1125 | export type Example = Node & { 1126 | __typename?: 'Example'; 1127 | id: Scalars['ID']; 1128 | createdAt: Scalars['DateTime']; 1129 | updatedAt: Scalars['DateTime']; 1130 | name: Scalars['String']; 1131 | }; 1132 | 1133 | export type ExampleFilterParameter = { 1134 | createdAt?: Maybe; 1135 | updatedAt?: Maybe; 1136 | name?: Maybe; 1137 | }; 1138 | 1139 | export type ExampleList = PaginatedList & { 1140 | __typename?: 'ExampleList'; 1141 | items: Array; 1142 | totalItems: Scalars['Int']; 1143 | }; 1144 | 1145 | export type ExampleListOptions = { 1146 | skip?: Maybe; 1147 | take?: Maybe; 1148 | sort?: Maybe; 1149 | filter?: Maybe; 1150 | }; 1151 | 1152 | export type ExampleSortParameter = { 1153 | id?: Maybe; 1154 | createdAt?: Maybe; 1155 | updatedAt?: Maybe; 1156 | name?: Maybe; 1157 | }; 1158 | 1159 | export type Facet = Node & { 1160 | __typename?: 'Facet'; 1161 | isPrivate: Scalars['Boolean']; 1162 | id: Scalars['ID']; 1163 | createdAt: Scalars['DateTime']; 1164 | updatedAt: Scalars['DateTime']; 1165 | languageCode: LanguageCode; 1166 | name: Scalars['String']; 1167 | code: Scalars['String']; 1168 | values: Array; 1169 | translations: Array; 1170 | customFields?: Maybe; 1171 | }; 1172 | 1173 | export type FacetFilterParameter = { 1174 | isPrivate?: Maybe; 1175 | createdAt?: Maybe; 1176 | updatedAt?: Maybe; 1177 | languageCode?: Maybe; 1178 | name?: Maybe; 1179 | code?: Maybe; 1180 | }; 1181 | 1182 | export type FacetList = PaginatedList & { 1183 | __typename?: 'FacetList'; 1184 | items: Array; 1185 | totalItems: Scalars['Int']; 1186 | }; 1187 | 1188 | export type FacetListOptions = { 1189 | skip?: Maybe; 1190 | take?: Maybe; 1191 | sort?: Maybe; 1192 | filter?: Maybe; 1193 | }; 1194 | 1195 | export type FacetSortParameter = { 1196 | id?: Maybe; 1197 | createdAt?: Maybe; 1198 | updatedAt?: Maybe; 1199 | name?: Maybe; 1200 | code?: Maybe; 1201 | }; 1202 | 1203 | export type FacetTranslation = { 1204 | __typename?: 'FacetTranslation'; 1205 | id: Scalars['ID']; 1206 | createdAt: Scalars['DateTime']; 1207 | updatedAt: Scalars['DateTime']; 1208 | languageCode: LanguageCode; 1209 | name: Scalars['String']; 1210 | }; 1211 | 1212 | export type FacetTranslationInput = { 1213 | id?: Maybe; 1214 | languageCode: LanguageCode; 1215 | name?: Maybe; 1216 | customFields?: Maybe; 1217 | }; 1218 | 1219 | export type FacetValue = Node & { 1220 | __typename?: 'FacetValue'; 1221 | id: Scalars['ID']; 1222 | createdAt: Scalars['DateTime']; 1223 | updatedAt: Scalars['DateTime']; 1224 | languageCode: LanguageCode; 1225 | facet: Facet; 1226 | name: Scalars['String']; 1227 | code: Scalars['String']; 1228 | translations: Array; 1229 | customFields?: Maybe; 1230 | }; 1231 | 1232 | /** 1233 | * Which FacetValues are present in the products returned 1234 | * by the search, and in what quantity. 1235 | */ 1236 | export type FacetValueResult = { 1237 | __typename?: 'FacetValueResult'; 1238 | facetValue: FacetValue; 1239 | count: Scalars['Int']; 1240 | }; 1241 | 1242 | export type FacetValueTranslation = { 1243 | __typename?: 'FacetValueTranslation'; 1244 | id: Scalars['ID']; 1245 | createdAt: Scalars['DateTime']; 1246 | updatedAt: Scalars['DateTime']; 1247 | languageCode: LanguageCode; 1248 | name: Scalars['String']; 1249 | }; 1250 | 1251 | export type FacetValueTranslationInput = { 1252 | id?: Maybe; 1253 | languageCode: LanguageCode; 1254 | name?: Maybe; 1255 | customFields?: Maybe; 1256 | }; 1257 | 1258 | export type FloatCustomFieldConfig = CustomField & { 1259 | __typename?: 'FloatCustomFieldConfig'; 1260 | name: Scalars['String']; 1261 | type: Scalars['String']; 1262 | label?: Maybe>; 1263 | description?: Maybe>; 1264 | readonly?: Maybe; 1265 | internal?: Maybe; 1266 | min?: Maybe; 1267 | max?: Maybe; 1268 | step?: Maybe; 1269 | }; 1270 | 1271 | export type Fulfillment = Node & { 1272 | __typename?: 'Fulfillment'; 1273 | id: Scalars['ID']; 1274 | createdAt: Scalars['DateTime']; 1275 | updatedAt: Scalars['DateTime']; 1276 | orderItems: Array; 1277 | method: Scalars['String']; 1278 | trackingCode?: Maybe; 1279 | }; 1280 | 1281 | export type FulfillOrderInput = { 1282 | lines: Array; 1283 | method: Scalars['String']; 1284 | trackingCode?: Maybe; 1285 | }; 1286 | 1287 | export type GlobalSettings = { 1288 | __typename?: 'GlobalSettings'; 1289 | id: Scalars['ID']; 1290 | createdAt: Scalars['DateTime']; 1291 | updatedAt: Scalars['DateTime']; 1292 | availableLanguages: Array; 1293 | trackInventory: Scalars['Boolean']; 1294 | serverConfig: ServerConfig; 1295 | customFields?: Maybe; 1296 | }; 1297 | 1298 | export type HistoryEntry = Node & { 1299 | __typename?: 'HistoryEntry'; 1300 | id: Scalars['ID']; 1301 | createdAt: Scalars['DateTime']; 1302 | updatedAt: Scalars['DateTime']; 1303 | isPublic: Scalars['Boolean']; 1304 | type: HistoryEntryType; 1305 | administrator?: Maybe; 1306 | data: Scalars['JSON']; 1307 | }; 1308 | 1309 | export type HistoryEntryFilterParameter = { 1310 | createdAt?: Maybe; 1311 | updatedAt?: Maybe; 1312 | isPublic?: Maybe; 1313 | type?: Maybe; 1314 | }; 1315 | 1316 | export type HistoryEntryList = PaginatedList & { 1317 | __typename?: 'HistoryEntryList'; 1318 | items: Array; 1319 | totalItems: Scalars['Int']; 1320 | }; 1321 | 1322 | export type HistoryEntryListOptions = { 1323 | skip?: Maybe; 1324 | take?: Maybe; 1325 | sort?: Maybe; 1326 | filter?: Maybe; 1327 | }; 1328 | 1329 | export type HistoryEntrySortParameter = { 1330 | id?: Maybe; 1331 | createdAt?: Maybe; 1332 | updatedAt?: Maybe; 1333 | }; 1334 | 1335 | export enum HistoryEntryType { 1336 | CustomerRegistered = 'CUSTOMER_REGISTERED', 1337 | CustomerVerified = 'CUSTOMER_VERIFIED', 1338 | CustomerDetailUpdated = 'CUSTOMER_DETAIL_UPDATED', 1339 | CustomerAddedToGroup = 'CUSTOMER_ADDED_TO_GROUP', 1340 | CustomerRemovedFromGroup = 'CUSTOMER_REMOVED_FROM_GROUP', 1341 | CustomerAddressCreated = 'CUSTOMER_ADDRESS_CREATED', 1342 | CustomerAddressUpdated = 'CUSTOMER_ADDRESS_UPDATED', 1343 | CustomerAddressDeleted = 'CUSTOMER_ADDRESS_DELETED', 1344 | CustomerPasswordUpdated = 'CUSTOMER_PASSWORD_UPDATED', 1345 | CustomerPasswordResetRequested = 'CUSTOMER_PASSWORD_RESET_REQUESTED', 1346 | CustomerPasswordResetVerified = 'CUSTOMER_PASSWORD_RESET_VERIFIED', 1347 | CustomerEmailUpdateRequested = 'CUSTOMER_EMAIL_UPDATE_REQUESTED', 1348 | CustomerEmailUpdateVerified = 'CUSTOMER_EMAIL_UPDATE_VERIFIED', 1349 | CustomerNote = 'CUSTOMER_NOTE', 1350 | OrderStateTransition = 'ORDER_STATE_TRANSITION', 1351 | OrderPaymentTransition = 'ORDER_PAYMENT_TRANSITION', 1352 | OrderFullfillment = 'ORDER_FULLFILLMENT', 1353 | OrderCancellation = 'ORDER_CANCELLATION', 1354 | OrderRefundTransition = 'ORDER_REFUND_TRANSITION', 1355 | OrderNote = 'ORDER_NOTE', 1356 | OrderCouponApplied = 'ORDER_COUPON_APPLIED', 1357 | OrderCouponRemoved = 'ORDER_COUPON_REMOVED' 1358 | } 1359 | 1360 | export type ImportInfo = { 1361 | __typename?: 'ImportInfo'; 1362 | errors?: Maybe>; 1363 | processed: Scalars['Int']; 1364 | imported: Scalars['Int']; 1365 | }; 1366 | 1367 | export type IntCustomFieldConfig = CustomField & { 1368 | __typename?: 'IntCustomFieldConfig'; 1369 | name: Scalars['String']; 1370 | type: Scalars['String']; 1371 | label?: Maybe>; 1372 | description?: Maybe>; 1373 | readonly?: Maybe; 1374 | internal?: Maybe; 1375 | min?: Maybe; 1376 | max?: Maybe; 1377 | step?: Maybe; 1378 | }; 1379 | 1380 | export type Job = Node & { 1381 | __typename?: 'Job'; 1382 | id: Scalars['ID']; 1383 | createdAt: Scalars['DateTime']; 1384 | startedAt?: Maybe; 1385 | settledAt?: Maybe; 1386 | queueName: Scalars['String']; 1387 | state: JobState; 1388 | progress: Scalars['Float']; 1389 | data?: Maybe; 1390 | result?: Maybe; 1391 | error?: Maybe; 1392 | isSettled: Scalars['Boolean']; 1393 | duration: Scalars['Int']; 1394 | }; 1395 | 1396 | export type JobFilterParameter = { 1397 | createdAt?: Maybe; 1398 | startedAt?: Maybe; 1399 | settledAt?: Maybe; 1400 | queueName?: Maybe; 1401 | state?: Maybe; 1402 | progress?: Maybe; 1403 | isSettled?: Maybe; 1404 | duration?: Maybe; 1405 | }; 1406 | 1407 | export type JobList = PaginatedList & { 1408 | __typename?: 'JobList'; 1409 | items: Array; 1410 | totalItems: Scalars['Int']; 1411 | }; 1412 | 1413 | export type JobListOptions = { 1414 | skip?: Maybe; 1415 | take?: Maybe; 1416 | sort?: Maybe; 1417 | filter?: Maybe; 1418 | }; 1419 | 1420 | export type JobQueue = { 1421 | __typename?: 'JobQueue'; 1422 | name: Scalars['String']; 1423 | running: Scalars['Boolean']; 1424 | }; 1425 | 1426 | export type JobSortParameter = { 1427 | id?: Maybe; 1428 | createdAt?: Maybe; 1429 | startedAt?: Maybe; 1430 | settledAt?: Maybe; 1431 | queueName?: Maybe; 1432 | progress?: Maybe; 1433 | duration?: Maybe; 1434 | }; 1435 | 1436 | /** 1437 | * @description 1438 | * The state of a Job in the JobQueue 1439 | * 1440 | * @docsCategory common 1441 | */ 1442 | export enum JobState { 1443 | Pending = 'PENDING', 1444 | Running = 'RUNNING', 1445 | Completed = 'COMPLETED', 1446 | Retrying = 'RETRYING', 1447 | Failed = 'FAILED' 1448 | } 1449 | 1450 | 1451 | /** 1452 | * @description 1453 | * Languages in the form of a ISO 639-1 language code with optional 1454 | * region or script modifier (e.g. de_AT). The selection available is based 1455 | * on the [Unicode CLDR summary list](https://unicode-org.github.io/cldr-staging/charts/37/summary/root.html) 1456 | * and includes the major spoken languages of the world and any widely-used variants. 1457 | * 1458 | * @docsCategory common 1459 | */ 1460 | export enum LanguageCode { 1461 | /** Afrikaans */ 1462 | Af = 'af', 1463 | /** Akan */ 1464 | Ak = 'ak', 1465 | /** Albanian */ 1466 | Sq = 'sq', 1467 | /** Amharic */ 1468 | Am = 'am', 1469 | /** Arabic */ 1470 | Ar = 'ar', 1471 | /** Armenian */ 1472 | Hy = 'hy', 1473 | /** Assamese */ 1474 | As = 'as', 1475 | /** Azerbaijani */ 1476 | Az = 'az', 1477 | /** Bambara */ 1478 | Bm = 'bm', 1479 | /** Bangla */ 1480 | Bn = 'bn', 1481 | /** Basque */ 1482 | Eu = 'eu', 1483 | /** Belarusian */ 1484 | Be = 'be', 1485 | /** Bosnian */ 1486 | Bs = 'bs', 1487 | /** Breton */ 1488 | Br = 'br', 1489 | /** Bulgarian */ 1490 | Bg = 'bg', 1491 | /** Burmese */ 1492 | My = 'my', 1493 | /** Catalan */ 1494 | Ca = 'ca', 1495 | /** Chechen */ 1496 | Ce = 'ce', 1497 | /** Chinese */ 1498 | Zh = 'zh', 1499 | /** Simplified Chinese */ 1500 | ZhHans = 'zh_Hans', 1501 | /** Traditional Chinese */ 1502 | ZhHant = 'zh_Hant', 1503 | /** Church Slavic */ 1504 | Cu = 'cu', 1505 | /** Cornish */ 1506 | Kw = 'kw', 1507 | /** Corsican */ 1508 | Co = 'co', 1509 | /** Croatian */ 1510 | Hr = 'hr', 1511 | /** Czech */ 1512 | Cs = 'cs', 1513 | /** Danish */ 1514 | Da = 'da', 1515 | /** Dutch */ 1516 | Nl = 'nl', 1517 | /** Flemish */ 1518 | NlBe = 'nl_BE', 1519 | /** Dzongkha */ 1520 | Dz = 'dz', 1521 | /** English */ 1522 | En = 'en', 1523 | /** Australian English */ 1524 | EnAu = 'en_AU', 1525 | /** Canadian English */ 1526 | EnCa = 'en_CA', 1527 | /** British English */ 1528 | EnGb = 'en_GB', 1529 | /** American English */ 1530 | EnUs = 'en_US', 1531 | /** Esperanto */ 1532 | Eo = 'eo', 1533 | /** Estonian */ 1534 | Et = 'et', 1535 | /** Ewe */ 1536 | Ee = 'ee', 1537 | /** Faroese */ 1538 | Fo = 'fo', 1539 | /** Finnish */ 1540 | Fi = 'fi', 1541 | /** French */ 1542 | Fr = 'fr', 1543 | /** Canadian French */ 1544 | FrCa = 'fr_CA', 1545 | /** Swiss French */ 1546 | FrCh = 'fr_CH', 1547 | /** Fulah */ 1548 | Ff = 'ff', 1549 | /** Galician */ 1550 | Gl = 'gl', 1551 | /** Ganda */ 1552 | Lg = 'lg', 1553 | /** Georgian */ 1554 | Ka = 'ka', 1555 | /** German */ 1556 | De = 'de', 1557 | /** Austrian German */ 1558 | DeAt = 'de_AT', 1559 | /** Swiss High German */ 1560 | DeCh = 'de_CH', 1561 | /** Greek */ 1562 | El = 'el', 1563 | /** Gujarati */ 1564 | Gu = 'gu', 1565 | /** Haitian Creole */ 1566 | Ht = 'ht', 1567 | /** Hausa */ 1568 | Ha = 'ha', 1569 | /** Hebrew */ 1570 | He = 'he', 1571 | /** Hindi */ 1572 | Hi = 'hi', 1573 | /** Hungarian */ 1574 | Hu = 'hu', 1575 | /** Icelandic */ 1576 | Is = 'is', 1577 | /** Igbo */ 1578 | Ig = 'ig', 1579 | /** Indonesian */ 1580 | Id = 'id', 1581 | /** Interlingua */ 1582 | Ia = 'ia', 1583 | /** Irish */ 1584 | Ga = 'ga', 1585 | /** Italian */ 1586 | It = 'it', 1587 | /** Japanese */ 1588 | Ja = 'ja', 1589 | /** Javanese */ 1590 | Jv = 'jv', 1591 | /** Kalaallisut */ 1592 | Kl = 'kl', 1593 | /** Kannada */ 1594 | Kn = 'kn', 1595 | /** Kashmiri */ 1596 | Ks = 'ks', 1597 | /** Kazakh */ 1598 | Kk = 'kk', 1599 | /** Khmer */ 1600 | Km = 'km', 1601 | /** Kikuyu */ 1602 | Ki = 'ki', 1603 | /** Kinyarwanda */ 1604 | Rw = 'rw', 1605 | /** Korean */ 1606 | Ko = 'ko', 1607 | /** Kurdish */ 1608 | Ku = 'ku', 1609 | /** Kyrgyz */ 1610 | Ky = 'ky', 1611 | /** Lao */ 1612 | Lo = 'lo', 1613 | /** Latin */ 1614 | La = 'la', 1615 | /** Latvian */ 1616 | Lv = 'lv', 1617 | /** Lingala */ 1618 | Ln = 'ln', 1619 | /** Lithuanian */ 1620 | Lt = 'lt', 1621 | /** Luba-Katanga */ 1622 | Lu = 'lu', 1623 | /** Luxembourgish */ 1624 | Lb = 'lb', 1625 | /** Macedonian */ 1626 | Mk = 'mk', 1627 | /** Malagasy */ 1628 | Mg = 'mg', 1629 | /** Malay */ 1630 | Ms = 'ms', 1631 | /** Malayalam */ 1632 | Ml = 'ml', 1633 | /** Maltese */ 1634 | Mt = 'mt', 1635 | /** Manx */ 1636 | Gv = 'gv', 1637 | /** Maori */ 1638 | Mi = 'mi', 1639 | /** Marathi */ 1640 | Mr = 'mr', 1641 | /** Mongolian */ 1642 | Mn = 'mn', 1643 | /** Nepali */ 1644 | Ne = 'ne', 1645 | /** North Ndebele */ 1646 | Nd = 'nd', 1647 | /** Northern Sami */ 1648 | Se = 'se', 1649 | /** Norwegian Bokmål */ 1650 | Nb = 'nb', 1651 | /** Norwegian Nynorsk */ 1652 | Nn = 'nn', 1653 | /** Nyanja */ 1654 | Ny = 'ny', 1655 | /** Odia */ 1656 | Or = 'or', 1657 | /** Oromo */ 1658 | Om = 'om', 1659 | /** Ossetic */ 1660 | Os = 'os', 1661 | /** Pashto */ 1662 | Ps = 'ps', 1663 | /** Persian */ 1664 | Fa = 'fa', 1665 | /** Dari */ 1666 | FaAf = 'fa_AF', 1667 | /** Polish */ 1668 | Pl = 'pl', 1669 | /** Portuguese */ 1670 | Pt = 'pt', 1671 | /** Brazilian Portuguese */ 1672 | PtBr = 'pt_BR', 1673 | /** European Portuguese */ 1674 | PtPt = 'pt_PT', 1675 | /** Punjabi */ 1676 | Pa = 'pa', 1677 | /** Quechua */ 1678 | Qu = 'qu', 1679 | /** Romanian */ 1680 | Ro = 'ro', 1681 | /** Moldavian */ 1682 | RoMd = 'ro_MD', 1683 | /** Romansh */ 1684 | Rm = 'rm', 1685 | /** Rundi */ 1686 | Rn = 'rn', 1687 | /** Russian */ 1688 | Ru = 'ru', 1689 | /** Samoan */ 1690 | Sm = 'sm', 1691 | /** Sango */ 1692 | Sg = 'sg', 1693 | /** Sanskrit */ 1694 | Sa = 'sa', 1695 | /** Scottish Gaelic */ 1696 | Gd = 'gd', 1697 | /** Serbian */ 1698 | Sr = 'sr', 1699 | /** Shona */ 1700 | Sn = 'sn', 1701 | /** Sichuan Yi */ 1702 | Ii = 'ii', 1703 | /** Sindhi */ 1704 | Sd = 'sd', 1705 | /** Sinhala */ 1706 | Si = 'si', 1707 | /** Slovak */ 1708 | Sk = 'sk', 1709 | /** Slovenian */ 1710 | Sl = 'sl', 1711 | /** Somali */ 1712 | So = 'so', 1713 | /** Southern Sotho */ 1714 | St = 'st', 1715 | /** Spanish */ 1716 | Es = 'es', 1717 | /** European Spanish */ 1718 | EsEs = 'es_ES', 1719 | /** Mexican Spanish */ 1720 | EsMx = 'es_MX', 1721 | /** Sundanese */ 1722 | Su = 'su', 1723 | /** Swahili */ 1724 | Sw = 'sw', 1725 | /** Congo Swahili */ 1726 | SwCd = 'sw_CD', 1727 | /** Swedish */ 1728 | Sv = 'sv', 1729 | /** Tajik */ 1730 | Tg = 'tg', 1731 | /** Tamil */ 1732 | Ta = 'ta', 1733 | /** Tatar */ 1734 | Tt = 'tt', 1735 | /** Telugu */ 1736 | Te = 'te', 1737 | /** Thai */ 1738 | Th = 'th', 1739 | /** Tibetan */ 1740 | Bo = 'bo', 1741 | /** Tigrinya */ 1742 | Ti = 'ti', 1743 | /** Tongan */ 1744 | To = 'to', 1745 | /** Turkish */ 1746 | Tr = 'tr', 1747 | /** Turkmen */ 1748 | Tk = 'tk', 1749 | /** Ukrainian */ 1750 | Uk = 'uk', 1751 | /** Urdu */ 1752 | Ur = 'ur', 1753 | /** Uyghur */ 1754 | Ug = 'ug', 1755 | /** Uzbek */ 1756 | Uz = 'uz', 1757 | /** Vietnamese */ 1758 | Vi = 'vi', 1759 | /** Volapük */ 1760 | Vo = 'vo', 1761 | /** Welsh */ 1762 | Cy = 'cy', 1763 | /** Western Frisian */ 1764 | Fy = 'fy', 1765 | /** Wolof */ 1766 | Wo = 'wo', 1767 | /** Xhosa */ 1768 | Xh = 'xh', 1769 | /** Yiddish */ 1770 | Yi = 'yi', 1771 | /** Yoruba */ 1772 | Yo = 'yo', 1773 | /** Zulu */ 1774 | Zu = 'zu' 1775 | } 1776 | 1777 | export type LocaleStringCustomFieldConfig = CustomField & { 1778 | __typename?: 'LocaleStringCustomFieldConfig'; 1779 | name: Scalars['String']; 1780 | type: Scalars['String']; 1781 | label?: Maybe>; 1782 | description?: Maybe>; 1783 | readonly?: Maybe; 1784 | internal?: Maybe; 1785 | pattern?: Maybe; 1786 | }; 1787 | 1788 | export type LocalizedString = { 1789 | __typename?: 'LocalizedString'; 1790 | languageCode: LanguageCode; 1791 | value: Scalars['String']; 1792 | }; 1793 | 1794 | export enum LogicalOperator { 1795 | And = 'AND', 1796 | Or = 'OR' 1797 | } 1798 | 1799 | export type LoginResult = { 1800 | __typename?: 'LoginResult'; 1801 | user: CurrentUser; 1802 | }; 1803 | 1804 | export type MoveCollectionInput = { 1805 | collectionId: Scalars['ID']; 1806 | parentId: Scalars['ID']; 1807 | index: Scalars['Int']; 1808 | }; 1809 | 1810 | export type Mutation = { 1811 | __typename?: 'Mutation'; 1812 | /** Create a new Administrator */ 1813 | createAdministrator: Administrator; 1814 | /** Update an existing Administrator */ 1815 | updateAdministrator: Administrator; 1816 | /** Delete an Administrator */ 1817 | deleteAdministrator: DeletionResponse; 1818 | /** Assign a Role to an Administrator */ 1819 | assignRoleToAdministrator: Administrator; 1820 | /** Create a new Asset */ 1821 | createAssets: Array; 1822 | /** Update an existing Asset */ 1823 | updateAsset: Asset; 1824 | /** Delete an Asset */ 1825 | deleteAsset: DeletionResponse; 1826 | /** Delete multiple Assets */ 1827 | deleteAssets: DeletionResponse; 1828 | /** 1829 | * Authenticates the user using the native authentication strategy. This mutation 1830 | * is an alias for `authenticate({ native: { ... }})` 1831 | */ 1832 | login: LoginResult; 1833 | /** Authenticates the user using a named authentication strategy */ 1834 | authenticate: LoginResult; 1835 | logout: Scalars['Boolean']; 1836 | /** Create a new Channel */ 1837 | createChannel: Channel; 1838 | /** Update an existing Channel */ 1839 | updateChannel: Channel; 1840 | /** Delete a Channel */ 1841 | deleteChannel: DeletionResponse; 1842 | /** Create a new Collection */ 1843 | createCollection: Collection; 1844 | /** Update an existing Collection */ 1845 | updateCollection: Collection; 1846 | /** Delete a Collection and all of its descendants */ 1847 | deleteCollection: DeletionResponse; 1848 | /** Move a Collection to a different parent or index */ 1849 | moveCollection: Collection; 1850 | /** Create a new Country */ 1851 | createCountry: Country; 1852 | /** Update an existing Country */ 1853 | updateCountry: Country; 1854 | /** Delete a Country */ 1855 | deleteCountry: DeletionResponse; 1856 | /** Create a new CustomerGroup */ 1857 | createCustomerGroup: CustomerGroup; 1858 | /** Update an existing CustomerGroup */ 1859 | updateCustomerGroup: CustomerGroup; 1860 | /** Delete a CustomerGroup */ 1861 | deleteCustomerGroup: DeletionResponse; 1862 | /** Add Customers to a CustomerGroup */ 1863 | addCustomersToGroup: CustomerGroup; 1864 | /** Remove Customers from a CustomerGroup */ 1865 | removeCustomersFromGroup: CustomerGroup; 1866 | /** Create a new Customer. If a password is provided, a new User will also be created an linked to the Customer. */ 1867 | createCustomer: Customer; 1868 | /** Update an existing Customer */ 1869 | updateCustomer: Customer; 1870 | /** Delete a Customer */ 1871 | deleteCustomer: DeletionResponse; 1872 | /** Create a new Address and associate it with the Customer specified by customerId */ 1873 | createCustomerAddress: Address; 1874 | /** Update an existing Address */ 1875 | updateCustomerAddress: Address; 1876 | /** Update an existing Address */ 1877 | deleteCustomerAddress: Scalars['Boolean']; 1878 | addNoteToCustomer: Customer; 1879 | updateCustomerNote: HistoryEntry; 1880 | deleteCustomerNote: DeletionResponse; 1881 | /** Create a new Facet */ 1882 | createFacet: Facet; 1883 | /** Update an existing Facet */ 1884 | updateFacet: Facet; 1885 | /** Delete an existing Facet */ 1886 | deleteFacet: DeletionResponse; 1887 | /** Create one or more FacetValues */ 1888 | createFacetValues: Array; 1889 | /** Update one or more FacetValues */ 1890 | updateFacetValues: Array; 1891 | /** Delete one or more FacetValues */ 1892 | deleteFacetValues: Array; 1893 | updateGlobalSettings: GlobalSettings; 1894 | importProducts?: Maybe; 1895 | /** Remove all settled jobs in the given queues olfer than the given date. Returns the number of jobs deleted. */ 1896 | removeSettledJobs: Scalars['Int']; 1897 | settlePayment: Payment; 1898 | fulfillOrder: Fulfillment; 1899 | cancelOrder: Order; 1900 | refundOrder: Refund; 1901 | settleRefund: Refund; 1902 | addNoteToOrder: Order; 1903 | updateOrderNote: HistoryEntry; 1904 | deleteOrderNote: DeletionResponse; 1905 | transitionOrderToState?: Maybe; 1906 | setOrderCustomFields?: Maybe; 1907 | /** Update an existing PaymentMethod */ 1908 | updatePaymentMethod: PaymentMethod; 1909 | /** Create a new ProductOptionGroup */ 1910 | createProductOptionGroup: ProductOptionGroup; 1911 | /** Update an existing ProductOptionGroup */ 1912 | updateProductOptionGroup: ProductOptionGroup; 1913 | /** Create a new ProductOption within a ProductOptionGroup */ 1914 | createProductOption: ProductOption; 1915 | /** Create a new ProductOption within a ProductOptionGroup */ 1916 | updateProductOption: ProductOption; 1917 | reindex: Job; 1918 | /** Create a new Product */ 1919 | createProduct: Product; 1920 | /** Update an existing Product */ 1921 | updateProduct: Product; 1922 | /** Delete a Product */ 1923 | deleteProduct: DeletionResponse; 1924 | /** Add an OptionGroup to a Product */ 1925 | addOptionGroupToProduct: Product; 1926 | /** Remove an OptionGroup from a Product */ 1927 | removeOptionGroupFromProduct: Product; 1928 | /** Create a set of ProductVariants based on the OptionGroups assigned to the given Product */ 1929 | createProductVariants: Array>; 1930 | /** Update existing ProductVariants */ 1931 | updateProductVariants: Array>; 1932 | /** Delete a ProductVariant */ 1933 | deleteProductVariant: DeletionResponse; 1934 | /** Assigns Products to the specified Channel */ 1935 | assignProductsToChannel: Array; 1936 | /** Removes Products from the specified Channel */ 1937 | removeProductsFromChannel: Array; 1938 | createPromotion: Promotion; 1939 | updatePromotion: Promotion; 1940 | deletePromotion: DeletionResponse; 1941 | /** Create a new Role */ 1942 | createRole: Role; 1943 | /** Update an existing Role */ 1944 | updateRole: Role; 1945 | /** Delete an existing Role */ 1946 | deleteRole: DeletionResponse; 1947 | /** Create a new ShippingMethod */ 1948 | createShippingMethod: ShippingMethod; 1949 | /** Update an existing ShippingMethod */ 1950 | updateShippingMethod: ShippingMethod; 1951 | /** Delete a ShippingMethod */ 1952 | deleteShippingMethod: DeletionResponse; 1953 | /** Create a new TaxCategory */ 1954 | createTaxCategory: TaxCategory; 1955 | /** Update an existing TaxCategory */ 1956 | updateTaxCategory: TaxCategory; 1957 | /** Deletes a TaxCategory */ 1958 | deleteTaxCategory: DeletionResponse; 1959 | /** Create a new TaxRate */ 1960 | createTaxRate: TaxRate; 1961 | /** Update an existing TaxRate */ 1962 | updateTaxRate: TaxRate; 1963 | /** Delete a TaxRate */ 1964 | deleteTaxRate: DeletionResponse; 1965 | /** Create a new Zone */ 1966 | createZone: Zone; 1967 | /** Update an existing Zone */ 1968 | updateZone: Zone; 1969 | /** Delete a Zone */ 1970 | deleteZone: DeletionResponse; 1971 | /** Add members to a Zone */ 1972 | addMembersToZone: Zone; 1973 | /** Remove members from a Zone */ 1974 | removeMembersFromZone: Zone; 1975 | addExample: Example; 1976 | updateExample: Example; 1977 | }; 1978 | 1979 | 1980 | export type MutationCreateAdministratorArgs = { 1981 | input: CreateAdministratorInput; 1982 | }; 1983 | 1984 | 1985 | export type MutationUpdateAdministratorArgs = { 1986 | input: UpdateAdministratorInput; 1987 | }; 1988 | 1989 | 1990 | export type MutationDeleteAdministratorArgs = { 1991 | id: Scalars['ID']; 1992 | }; 1993 | 1994 | 1995 | export type MutationAssignRoleToAdministratorArgs = { 1996 | administratorId: Scalars['ID']; 1997 | roleId: Scalars['ID']; 1998 | }; 1999 | 2000 | 2001 | export type MutationCreateAssetsArgs = { 2002 | input: Array; 2003 | }; 2004 | 2005 | 2006 | export type MutationUpdateAssetArgs = { 2007 | input: UpdateAssetInput; 2008 | }; 2009 | 2010 | 2011 | export type MutationDeleteAssetArgs = { 2012 | id: Scalars['ID']; 2013 | force?: Maybe; 2014 | }; 2015 | 2016 | 2017 | export type MutationDeleteAssetsArgs = { 2018 | ids: Array; 2019 | force?: Maybe; 2020 | }; 2021 | 2022 | 2023 | export type MutationLoginArgs = { 2024 | username: Scalars['String']; 2025 | password: Scalars['String']; 2026 | rememberMe?: Maybe; 2027 | }; 2028 | 2029 | 2030 | export type MutationAuthenticateArgs = { 2031 | input: AuthenticationInput; 2032 | rememberMe?: Maybe; 2033 | }; 2034 | 2035 | 2036 | export type MutationCreateChannelArgs = { 2037 | input: CreateChannelInput; 2038 | }; 2039 | 2040 | 2041 | export type MutationUpdateChannelArgs = { 2042 | input: UpdateChannelInput; 2043 | }; 2044 | 2045 | 2046 | export type MutationDeleteChannelArgs = { 2047 | id: Scalars['ID']; 2048 | }; 2049 | 2050 | 2051 | export type MutationCreateCollectionArgs = { 2052 | input: CreateCollectionInput; 2053 | }; 2054 | 2055 | 2056 | export type MutationUpdateCollectionArgs = { 2057 | input: UpdateCollectionInput; 2058 | }; 2059 | 2060 | 2061 | export type MutationDeleteCollectionArgs = { 2062 | id: Scalars['ID']; 2063 | }; 2064 | 2065 | 2066 | export type MutationMoveCollectionArgs = { 2067 | input: MoveCollectionInput; 2068 | }; 2069 | 2070 | 2071 | export type MutationCreateCountryArgs = { 2072 | input: CreateCountryInput; 2073 | }; 2074 | 2075 | 2076 | export type MutationUpdateCountryArgs = { 2077 | input: UpdateCountryInput; 2078 | }; 2079 | 2080 | 2081 | export type MutationDeleteCountryArgs = { 2082 | id: Scalars['ID']; 2083 | }; 2084 | 2085 | 2086 | export type MutationCreateCustomerGroupArgs = { 2087 | input: CreateCustomerGroupInput; 2088 | }; 2089 | 2090 | 2091 | export type MutationUpdateCustomerGroupArgs = { 2092 | input: UpdateCustomerGroupInput; 2093 | }; 2094 | 2095 | 2096 | export type MutationDeleteCustomerGroupArgs = { 2097 | id: Scalars['ID']; 2098 | }; 2099 | 2100 | 2101 | export type MutationAddCustomersToGroupArgs = { 2102 | customerGroupId: Scalars['ID']; 2103 | customerIds: Array; 2104 | }; 2105 | 2106 | 2107 | export type MutationRemoveCustomersFromGroupArgs = { 2108 | customerGroupId: Scalars['ID']; 2109 | customerIds: Array; 2110 | }; 2111 | 2112 | 2113 | export type MutationCreateCustomerArgs = { 2114 | input: CreateCustomerInput; 2115 | password?: Maybe; 2116 | }; 2117 | 2118 | 2119 | export type MutationUpdateCustomerArgs = { 2120 | input: UpdateCustomerInput; 2121 | }; 2122 | 2123 | 2124 | export type MutationDeleteCustomerArgs = { 2125 | id: Scalars['ID']; 2126 | }; 2127 | 2128 | 2129 | export type MutationCreateCustomerAddressArgs = { 2130 | customerId: Scalars['ID']; 2131 | input: CreateAddressInput; 2132 | }; 2133 | 2134 | 2135 | export type MutationUpdateCustomerAddressArgs = { 2136 | input: UpdateAddressInput; 2137 | }; 2138 | 2139 | 2140 | export type MutationDeleteCustomerAddressArgs = { 2141 | id: Scalars['ID']; 2142 | }; 2143 | 2144 | 2145 | export type MutationAddNoteToCustomerArgs = { 2146 | input: AddNoteToCustomerInput; 2147 | }; 2148 | 2149 | 2150 | export type MutationUpdateCustomerNoteArgs = { 2151 | input: UpdateCustomerNoteInput; 2152 | }; 2153 | 2154 | 2155 | export type MutationDeleteCustomerNoteArgs = { 2156 | id: Scalars['ID']; 2157 | }; 2158 | 2159 | 2160 | export type MutationCreateFacetArgs = { 2161 | input: CreateFacetInput; 2162 | }; 2163 | 2164 | 2165 | export type MutationUpdateFacetArgs = { 2166 | input: UpdateFacetInput; 2167 | }; 2168 | 2169 | 2170 | export type MutationDeleteFacetArgs = { 2171 | id: Scalars['ID']; 2172 | force?: Maybe; 2173 | }; 2174 | 2175 | 2176 | export type MutationCreateFacetValuesArgs = { 2177 | input: Array; 2178 | }; 2179 | 2180 | 2181 | export type MutationUpdateFacetValuesArgs = { 2182 | input: Array; 2183 | }; 2184 | 2185 | 2186 | export type MutationDeleteFacetValuesArgs = { 2187 | ids: Array; 2188 | force?: Maybe; 2189 | }; 2190 | 2191 | 2192 | export type MutationUpdateGlobalSettingsArgs = { 2193 | input: UpdateGlobalSettingsInput; 2194 | }; 2195 | 2196 | 2197 | export type MutationImportProductsArgs = { 2198 | csvFile: Scalars['Upload']; 2199 | }; 2200 | 2201 | 2202 | export type MutationRemoveSettledJobsArgs = { 2203 | queueNames?: Maybe>; 2204 | olderThan?: Maybe; 2205 | }; 2206 | 2207 | 2208 | export type MutationSettlePaymentArgs = { 2209 | id: Scalars['ID']; 2210 | }; 2211 | 2212 | 2213 | export type MutationFulfillOrderArgs = { 2214 | input: FulfillOrderInput; 2215 | }; 2216 | 2217 | 2218 | export type MutationCancelOrderArgs = { 2219 | input: CancelOrderInput; 2220 | }; 2221 | 2222 | 2223 | export type MutationRefundOrderArgs = { 2224 | input: RefundOrderInput; 2225 | }; 2226 | 2227 | 2228 | export type MutationSettleRefundArgs = { 2229 | input: SettleRefundInput; 2230 | }; 2231 | 2232 | 2233 | export type MutationAddNoteToOrderArgs = { 2234 | input: AddNoteToOrderInput; 2235 | }; 2236 | 2237 | 2238 | export type MutationUpdateOrderNoteArgs = { 2239 | input: UpdateOrderNoteInput; 2240 | }; 2241 | 2242 | 2243 | export type MutationDeleteOrderNoteArgs = { 2244 | id: Scalars['ID']; 2245 | }; 2246 | 2247 | 2248 | export type MutationTransitionOrderToStateArgs = { 2249 | id: Scalars['ID']; 2250 | state: Scalars['String']; 2251 | }; 2252 | 2253 | 2254 | export type MutationSetOrderCustomFieldsArgs = { 2255 | input: UpdateOrderInput; 2256 | }; 2257 | 2258 | 2259 | export type MutationUpdatePaymentMethodArgs = { 2260 | input: UpdatePaymentMethodInput; 2261 | }; 2262 | 2263 | 2264 | export type MutationCreateProductOptionGroupArgs = { 2265 | input: CreateProductOptionGroupInput; 2266 | }; 2267 | 2268 | 2269 | export type MutationUpdateProductOptionGroupArgs = { 2270 | input: UpdateProductOptionGroupInput; 2271 | }; 2272 | 2273 | 2274 | export type MutationCreateProductOptionArgs = { 2275 | input: CreateProductOptionInput; 2276 | }; 2277 | 2278 | 2279 | export type MutationUpdateProductOptionArgs = { 2280 | input: UpdateProductOptionInput; 2281 | }; 2282 | 2283 | 2284 | export type MutationCreateProductArgs = { 2285 | input: CreateProductInput; 2286 | }; 2287 | 2288 | 2289 | export type MutationUpdateProductArgs = { 2290 | input: UpdateProductInput; 2291 | }; 2292 | 2293 | 2294 | export type MutationDeleteProductArgs = { 2295 | id: Scalars['ID']; 2296 | }; 2297 | 2298 | 2299 | export type MutationAddOptionGroupToProductArgs = { 2300 | productId: Scalars['ID']; 2301 | optionGroupId: Scalars['ID']; 2302 | }; 2303 | 2304 | 2305 | export type MutationRemoveOptionGroupFromProductArgs = { 2306 | productId: Scalars['ID']; 2307 | optionGroupId: Scalars['ID']; 2308 | }; 2309 | 2310 | 2311 | export type MutationCreateProductVariantsArgs = { 2312 | input: Array; 2313 | }; 2314 | 2315 | 2316 | export type MutationUpdateProductVariantsArgs = { 2317 | input: Array; 2318 | }; 2319 | 2320 | 2321 | export type MutationDeleteProductVariantArgs = { 2322 | id: Scalars['ID']; 2323 | }; 2324 | 2325 | 2326 | export type MutationAssignProductsToChannelArgs = { 2327 | input: AssignProductsToChannelInput; 2328 | }; 2329 | 2330 | 2331 | export type MutationRemoveProductsFromChannelArgs = { 2332 | input: RemoveProductsFromChannelInput; 2333 | }; 2334 | 2335 | 2336 | export type MutationCreatePromotionArgs = { 2337 | input: CreatePromotionInput; 2338 | }; 2339 | 2340 | 2341 | export type MutationUpdatePromotionArgs = { 2342 | input: UpdatePromotionInput; 2343 | }; 2344 | 2345 | 2346 | export type MutationDeletePromotionArgs = { 2347 | id: Scalars['ID']; 2348 | }; 2349 | 2350 | 2351 | export type MutationCreateRoleArgs = { 2352 | input: CreateRoleInput; 2353 | }; 2354 | 2355 | 2356 | export type MutationUpdateRoleArgs = { 2357 | input: UpdateRoleInput; 2358 | }; 2359 | 2360 | 2361 | export type MutationDeleteRoleArgs = { 2362 | id: Scalars['ID']; 2363 | }; 2364 | 2365 | 2366 | export type MutationCreateShippingMethodArgs = { 2367 | input: CreateShippingMethodInput; 2368 | }; 2369 | 2370 | 2371 | export type MutationUpdateShippingMethodArgs = { 2372 | input: UpdateShippingMethodInput; 2373 | }; 2374 | 2375 | 2376 | export type MutationDeleteShippingMethodArgs = { 2377 | id: Scalars['ID']; 2378 | }; 2379 | 2380 | 2381 | export type MutationCreateTaxCategoryArgs = { 2382 | input: CreateTaxCategoryInput; 2383 | }; 2384 | 2385 | 2386 | export type MutationUpdateTaxCategoryArgs = { 2387 | input: UpdateTaxCategoryInput; 2388 | }; 2389 | 2390 | 2391 | export type MutationDeleteTaxCategoryArgs = { 2392 | id: Scalars['ID']; 2393 | }; 2394 | 2395 | 2396 | export type MutationCreateTaxRateArgs = { 2397 | input: CreateTaxRateInput; 2398 | }; 2399 | 2400 | 2401 | export type MutationUpdateTaxRateArgs = { 2402 | input: UpdateTaxRateInput; 2403 | }; 2404 | 2405 | 2406 | export type MutationDeleteTaxRateArgs = { 2407 | id: Scalars['ID']; 2408 | }; 2409 | 2410 | 2411 | export type MutationCreateZoneArgs = { 2412 | input: CreateZoneInput; 2413 | }; 2414 | 2415 | 2416 | export type MutationUpdateZoneArgs = { 2417 | input: UpdateZoneInput; 2418 | }; 2419 | 2420 | 2421 | export type MutationDeleteZoneArgs = { 2422 | id: Scalars['ID']; 2423 | }; 2424 | 2425 | 2426 | export type MutationAddMembersToZoneArgs = { 2427 | zoneId: Scalars['ID']; 2428 | memberIds: Array; 2429 | }; 2430 | 2431 | 2432 | export type MutationRemoveMembersFromZoneArgs = { 2433 | zoneId: Scalars['ID']; 2434 | memberIds: Array; 2435 | }; 2436 | 2437 | 2438 | export type MutationAddExampleArgs = { 2439 | input: CreateExampleInput; 2440 | }; 2441 | 2442 | 2443 | export type MutationUpdateExampleArgs = { 2444 | input: UpdateExampleInput; 2445 | }; 2446 | 2447 | export type NativeAuthInput = { 2448 | username: Scalars['String']; 2449 | password: Scalars['String']; 2450 | }; 2451 | 2452 | export type Node = { 2453 | id: Scalars['ID']; 2454 | }; 2455 | 2456 | export type NumberOperators = { 2457 | eq?: Maybe; 2458 | lt?: Maybe; 2459 | lte?: Maybe; 2460 | gt?: Maybe; 2461 | gte?: Maybe; 2462 | between?: Maybe; 2463 | }; 2464 | 2465 | export type NumberRange = { 2466 | start: Scalars['Float']; 2467 | end: Scalars['Float']; 2468 | }; 2469 | 2470 | export type Order = Node & { 2471 | __typename?: 'Order'; 2472 | nextStates: Array; 2473 | id: Scalars['ID']; 2474 | createdAt: Scalars['DateTime']; 2475 | updatedAt: Scalars['DateTime']; 2476 | /** A unique code for the Order */ 2477 | code: Scalars['String']; 2478 | state: Scalars['String']; 2479 | /** An order is active as long as the payment process has not been completed */ 2480 | active: Scalars['Boolean']; 2481 | customer?: Maybe; 2482 | shippingAddress?: Maybe; 2483 | billingAddress?: Maybe; 2484 | lines: Array; 2485 | /** Order-level adjustments to the order total, such as discounts from promotions */ 2486 | adjustments: Array; 2487 | couponCodes: Array; 2488 | /** Promotions applied to the order. Only gets populated after the payment process has completed. */ 2489 | promotions: Array; 2490 | payments?: Maybe>; 2491 | fulfillments?: Maybe>; 2492 | subTotalBeforeTax: Scalars['Int']; 2493 | /** The subTotal is the total of the OrderLines, before order-level promotions and shipping has been applied. */ 2494 | subTotal: Scalars['Int']; 2495 | currencyCode: CurrencyCode; 2496 | shipping: Scalars['Int']; 2497 | shippingWithTax: Scalars['Int']; 2498 | shippingMethod?: Maybe; 2499 | totalBeforeTax: Scalars['Int']; 2500 | total: Scalars['Int']; 2501 | history: HistoryEntryList; 2502 | customFields?: Maybe; 2503 | }; 2504 | 2505 | 2506 | export type OrderHistoryArgs = { 2507 | options?: Maybe; 2508 | }; 2509 | 2510 | export type OrderAddress = { 2511 | __typename?: 'OrderAddress'; 2512 | fullName?: Maybe; 2513 | company?: Maybe; 2514 | streetLine1?: Maybe; 2515 | streetLine2?: Maybe; 2516 | city?: Maybe; 2517 | province?: Maybe; 2518 | postalCode?: Maybe; 2519 | country?: Maybe; 2520 | countryCode?: Maybe; 2521 | phoneNumber?: Maybe; 2522 | }; 2523 | 2524 | export type OrderFilterParameter = { 2525 | createdAt?: Maybe; 2526 | updatedAt?: Maybe; 2527 | code?: Maybe; 2528 | state?: Maybe; 2529 | active?: Maybe; 2530 | subTotalBeforeTax?: Maybe; 2531 | subTotal?: Maybe; 2532 | currencyCode?: Maybe; 2533 | shipping?: Maybe; 2534 | shippingWithTax?: Maybe; 2535 | totalBeforeTax?: Maybe; 2536 | total?: Maybe; 2537 | }; 2538 | 2539 | export type OrderItem = Node & { 2540 | __typename?: 'OrderItem'; 2541 | id: Scalars['ID']; 2542 | createdAt: Scalars['DateTime']; 2543 | updatedAt: Scalars['DateTime']; 2544 | cancelled: Scalars['Boolean']; 2545 | unitPrice: Scalars['Int']; 2546 | unitPriceWithTax: Scalars['Int']; 2547 | unitPriceIncludesTax: Scalars['Boolean']; 2548 | taxRate: Scalars['Float']; 2549 | adjustments: Array; 2550 | fulfillment?: Maybe; 2551 | refundId?: Maybe; 2552 | }; 2553 | 2554 | export type OrderLine = Node & { 2555 | __typename?: 'OrderLine'; 2556 | id: Scalars['ID']; 2557 | createdAt: Scalars['DateTime']; 2558 | updatedAt: Scalars['DateTime']; 2559 | productVariant: ProductVariant; 2560 | featuredAsset?: Maybe; 2561 | unitPrice: Scalars['Int']; 2562 | unitPriceWithTax: Scalars['Int']; 2563 | quantity: Scalars['Int']; 2564 | items: Array; 2565 | totalPrice: Scalars['Int']; 2566 | adjustments: Array; 2567 | order: Order; 2568 | customFields?: Maybe; 2569 | }; 2570 | 2571 | export type OrderLineInput = { 2572 | orderLineId: Scalars['ID']; 2573 | quantity: Scalars['Int']; 2574 | }; 2575 | 2576 | export type OrderList = PaginatedList & { 2577 | __typename?: 'OrderList'; 2578 | items: Array; 2579 | totalItems: Scalars['Int']; 2580 | }; 2581 | 2582 | export type OrderListOptions = { 2583 | skip?: Maybe; 2584 | take?: Maybe; 2585 | sort?: Maybe; 2586 | filter?: Maybe; 2587 | }; 2588 | 2589 | export type OrderProcessState = { 2590 | __typename?: 'OrderProcessState'; 2591 | name: Scalars['String']; 2592 | to: Array; 2593 | }; 2594 | 2595 | export type OrderSortParameter = { 2596 | id?: Maybe; 2597 | createdAt?: Maybe; 2598 | updatedAt?: Maybe; 2599 | code?: Maybe; 2600 | state?: Maybe; 2601 | subTotalBeforeTax?: Maybe; 2602 | subTotal?: Maybe; 2603 | shipping?: Maybe; 2604 | shippingWithTax?: Maybe; 2605 | totalBeforeTax?: Maybe; 2606 | total?: Maybe; 2607 | }; 2608 | 2609 | export type PaginatedList = { 2610 | items: Array; 2611 | totalItems: Scalars['Int']; 2612 | }; 2613 | 2614 | export type Payment = Node & { 2615 | __typename?: 'Payment'; 2616 | id: Scalars['ID']; 2617 | createdAt: Scalars['DateTime']; 2618 | updatedAt: Scalars['DateTime']; 2619 | method: Scalars['String']; 2620 | amount: Scalars['Int']; 2621 | state: Scalars['String']; 2622 | transactionId?: Maybe; 2623 | errorMessage?: Maybe; 2624 | refunds: Array; 2625 | metadata?: Maybe; 2626 | }; 2627 | 2628 | export type PaymentMethod = Node & { 2629 | __typename?: 'PaymentMethod'; 2630 | id: Scalars['ID']; 2631 | createdAt: Scalars['DateTime']; 2632 | updatedAt: Scalars['DateTime']; 2633 | code: Scalars['String']; 2634 | enabled: Scalars['Boolean']; 2635 | configArgs: Array; 2636 | }; 2637 | 2638 | export type PaymentMethodFilterParameter = { 2639 | createdAt?: Maybe; 2640 | updatedAt?: Maybe; 2641 | code?: Maybe; 2642 | enabled?: Maybe; 2643 | }; 2644 | 2645 | export type PaymentMethodList = PaginatedList & { 2646 | __typename?: 'PaymentMethodList'; 2647 | items: Array; 2648 | totalItems: Scalars['Int']; 2649 | }; 2650 | 2651 | export type PaymentMethodListOptions = { 2652 | skip?: Maybe; 2653 | take?: Maybe; 2654 | sort?: Maybe; 2655 | filter?: Maybe; 2656 | }; 2657 | 2658 | export type PaymentMethodSortParameter = { 2659 | id?: Maybe; 2660 | createdAt?: Maybe; 2661 | updatedAt?: Maybe; 2662 | code?: Maybe; 2663 | }; 2664 | 2665 | /** 2666 | * " 2667 | * @description 2668 | * Permissions for administrators and customers. Used to control access to 2669 | * GraphQL resolvers via the {@link Allow} decorator. 2670 | * 2671 | * @docsCategory common 2672 | */ 2673 | export enum Permission { 2674 | /** The Authenticated role means simply that the user is logged in */ 2675 | Authenticated = 'Authenticated', 2676 | /** SuperAdmin can perform the most sensitive tasks */ 2677 | SuperAdmin = 'SuperAdmin', 2678 | /** Owner means the user owns this entity, e.g. a Customer's own Order */ 2679 | Owner = 'Owner', 2680 | /** Public means any unauthenticated user may perform the operation */ 2681 | Public = 'Public', 2682 | CreateCatalog = 'CreateCatalog', 2683 | ReadCatalog = 'ReadCatalog', 2684 | UpdateCatalog = 'UpdateCatalog', 2685 | DeleteCatalog = 'DeleteCatalog', 2686 | CreateCustomer = 'CreateCustomer', 2687 | ReadCustomer = 'ReadCustomer', 2688 | UpdateCustomer = 'UpdateCustomer', 2689 | DeleteCustomer = 'DeleteCustomer', 2690 | CreateAdministrator = 'CreateAdministrator', 2691 | ReadAdministrator = 'ReadAdministrator', 2692 | UpdateAdministrator = 'UpdateAdministrator', 2693 | DeleteAdministrator = 'DeleteAdministrator', 2694 | CreateOrder = 'CreateOrder', 2695 | ReadOrder = 'ReadOrder', 2696 | UpdateOrder = 'UpdateOrder', 2697 | DeleteOrder = 'DeleteOrder', 2698 | CreatePromotion = 'CreatePromotion', 2699 | ReadPromotion = 'ReadPromotion', 2700 | UpdatePromotion = 'UpdatePromotion', 2701 | DeletePromotion = 'DeletePromotion', 2702 | CreateSettings = 'CreateSettings', 2703 | ReadSettings = 'ReadSettings', 2704 | UpdateSettings = 'UpdateSettings', 2705 | DeleteSettings = 'DeleteSettings' 2706 | } 2707 | 2708 | /** The price range where the result has more than one price */ 2709 | export type PriceRange = { 2710 | __typename?: 'PriceRange'; 2711 | min: Scalars['Int']; 2712 | max: Scalars['Int']; 2713 | }; 2714 | 2715 | export type Product = Node & { 2716 | __typename?: 'Product'; 2717 | enabled: Scalars['Boolean']; 2718 | channels: Array; 2719 | id: Scalars['ID']; 2720 | createdAt: Scalars['DateTime']; 2721 | updatedAt: Scalars['DateTime']; 2722 | languageCode: LanguageCode; 2723 | name: Scalars['String']; 2724 | slug: Scalars['String']; 2725 | description: Scalars['String']; 2726 | featuredAsset?: Maybe; 2727 | assets: Array; 2728 | variants: Array; 2729 | optionGroups: Array; 2730 | facetValues: Array; 2731 | translations: Array; 2732 | collections: Array; 2733 | customFields?: Maybe; 2734 | }; 2735 | 2736 | export type ProductFilterParameter = { 2737 | enabled?: Maybe; 2738 | createdAt?: Maybe; 2739 | updatedAt?: Maybe; 2740 | languageCode?: Maybe; 2741 | name?: Maybe; 2742 | slug?: Maybe; 2743 | description?: Maybe; 2744 | }; 2745 | 2746 | export type ProductList = PaginatedList & { 2747 | __typename?: 'ProductList'; 2748 | items: Array; 2749 | totalItems: Scalars['Int']; 2750 | }; 2751 | 2752 | export type ProductListOptions = { 2753 | skip?: Maybe; 2754 | take?: Maybe; 2755 | sort?: Maybe; 2756 | filter?: Maybe; 2757 | }; 2758 | 2759 | export type ProductOption = Node & { 2760 | __typename?: 'ProductOption'; 2761 | id: Scalars['ID']; 2762 | createdAt: Scalars['DateTime']; 2763 | updatedAt: Scalars['DateTime']; 2764 | languageCode: LanguageCode; 2765 | code: Scalars['String']; 2766 | name: Scalars['String']; 2767 | groupId: Scalars['ID']; 2768 | group: ProductOptionGroup; 2769 | translations: Array; 2770 | customFields?: Maybe; 2771 | }; 2772 | 2773 | export type ProductOptionGroup = Node & { 2774 | __typename?: 'ProductOptionGroup'; 2775 | id: Scalars['ID']; 2776 | createdAt: Scalars['DateTime']; 2777 | updatedAt: Scalars['DateTime']; 2778 | languageCode: LanguageCode; 2779 | code: Scalars['String']; 2780 | name: Scalars['String']; 2781 | options: Array; 2782 | translations: Array; 2783 | customFields?: Maybe; 2784 | }; 2785 | 2786 | export type ProductOptionGroupTranslation = { 2787 | __typename?: 'ProductOptionGroupTranslation'; 2788 | id: Scalars['ID']; 2789 | createdAt: Scalars['DateTime']; 2790 | updatedAt: Scalars['DateTime']; 2791 | languageCode: LanguageCode; 2792 | name: Scalars['String']; 2793 | }; 2794 | 2795 | export type ProductOptionGroupTranslationInput = { 2796 | id?: Maybe; 2797 | languageCode: LanguageCode; 2798 | name?: Maybe; 2799 | customFields?: Maybe; 2800 | }; 2801 | 2802 | export type ProductOptionTranslation = { 2803 | __typename?: 'ProductOptionTranslation'; 2804 | id: Scalars['ID']; 2805 | createdAt: Scalars['DateTime']; 2806 | updatedAt: Scalars['DateTime']; 2807 | languageCode: LanguageCode; 2808 | name: Scalars['String']; 2809 | }; 2810 | 2811 | export type ProductOptionTranslationInput = { 2812 | id?: Maybe; 2813 | languageCode: LanguageCode; 2814 | name?: Maybe; 2815 | customFields?: Maybe; 2816 | }; 2817 | 2818 | export type ProductSortParameter = { 2819 | id?: Maybe; 2820 | createdAt?: Maybe; 2821 | updatedAt?: Maybe; 2822 | name?: Maybe; 2823 | slug?: Maybe; 2824 | description?: Maybe; 2825 | }; 2826 | 2827 | export type ProductTranslation = { 2828 | __typename?: 'ProductTranslation'; 2829 | id: Scalars['ID']; 2830 | createdAt: Scalars['DateTime']; 2831 | updatedAt: Scalars['DateTime']; 2832 | languageCode: LanguageCode; 2833 | name: Scalars['String']; 2834 | slug: Scalars['String']; 2835 | description: Scalars['String']; 2836 | }; 2837 | 2838 | export type ProductTranslationInput = { 2839 | id?: Maybe; 2840 | languageCode: LanguageCode; 2841 | name?: Maybe; 2842 | slug?: Maybe; 2843 | description?: Maybe; 2844 | customFields?: Maybe; 2845 | }; 2846 | 2847 | export type ProductVariant = Node & { 2848 | __typename?: 'ProductVariant'; 2849 | enabled: Scalars['Boolean']; 2850 | stockOnHand: Scalars['Int']; 2851 | trackInventory: Scalars['Boolean']; 2852 | stockMovements: StockMovementList; 2853 | id: Scalars['ID']; 2854 | product: Product; 2855 | productId: Scalars['ID']; 2856 | createdAt: Scalars['DateTime']; 2857 | updatedAt: Scalars['DateTime']; 2858 | languageCode: LanguageCode; 2859 | sku: Scalars['String']; 2860 | name: Scalars['String']; 2861 | featuredAsset?: Maybe; 2862 | assets: Array; 2863 | price: Scalars['Int']; 2864 | currencyCode: CurrencyCode; 2865 | priceIncludesTax: Scalars['Boolean']; 2866 | priceWithTax: Scalars['Int']; 2867 | taxRateApplied: TaxRate; 2868 | taxCategory: TaxCategory; 2869 | options: Array; 2870 | facetValues: Array; 2871 | translations: Array; 2872 | customFields?: Maybe; 2873 | }; 2874 | 2875 | 2876 | export type ProductVariantStockMovementsArgs = { 2877 | options?: Maybe; 2878 | }; 2879 | 2880 | export type ProductVariantFilterParameter = { 2881 | enabled?: Maybe; 2882 | stockOnHand?: Maybe; 2883 | trackInventory?: Maybe; 2884 | createdAt?: Maybe; 2885 | updatedAt?: Maybe; 2886 | languageCode?: Maybe; 2887 | sku?: Maybe; 2888 | name?: Maybe; 2889 | price?: Maybe; 2890 | currencyCode?: Maybe; 2891 | priceIncludesTax?: Maybe; 2892 | priceWithTax?: Maybe; 2893 | }; 2894 | 2895 | export type ProductVariantList = PaginatedList & { 2896 | __typename?: 'ProductVariantList'; 2897 | items: Array; 2898 | totalItems: Scalars['Int']; 2899 | }; 2900 | 2901 | export type ProductVariantListOptions = { 2902 | skip?: Maybe; 2903 | take?: Maybe; 2904 | sort?: Maybe; 2905 | filter?: Maybe; 2906 | }; 2907 | 2908 | export type ProductVariantSortParameter = { 2909 | stockOnHand?: Maybe; 2910 | id?: Maybe; 2911 | productId?: Maybe; 2912 | createdAt?: Maybe; 2913 | updatedAt?: Maybe; 2914 | sku?: Maybe; 2915 | name?: Maybe; 2916 | price?: Maybe; 2917 | priceWithTax?: Maybe; 2918 | }; 2919 | 2920 | export type ProductVariantTranslation = { 2921 | __typename?: 'ProductVariantTranslation'; 2922 | id: Scalars['ID']; 2923 | createdAt: Scalars['DateTime']; 2924 | updatedAt: Scalars['DateTime']; 2925 | languageCode: LanguageCode; 2926 | name: Scalars['String']; 2927 | }; 2928 | 2929 | export type ProductVariantTranslationInput = { 2930 | id?: Maybe; 2931 | languageCode: LanguageCode; 2932 | name?: Maybe; 2933 | customFields?: Maybe; 2934 | }; 2935 | 2936 | export type Promotion = Node & { 2937 | __typename?: 'Promotion'; 2938 | id: Scalars['ID']; 2939 | createdAt: Scalars['DateTime']; 2940 | updatedAt: Scalars['DateTime']; 2941 | startsAt?: Maybe; 2942 | endsAt?: Maybe; 2943 | couponCode?: Maybe; 2944 | perCustomerUsageLimit?: Maybe; 2945 | name: Scalars['String']; 2946 | enabled: Scalars['Boolean']; 2947 | conditions: Array; 2948 | actions: Array; 2949 | }; 2950 | 2951 | export type PromotionFilterParameter = { 2952 | createdAt?: Maybe; 2953 | updatedAt?: Maybe; 2954 | startsAt?: Maybe; 2955 | endsAt?: Maybe; 2956 | couponCode?: Maybe; 2957 | perCustomerUsageLimit?: Maybe; 2958 | name?: Maybe; 2959 | enabled?: Maybe; 2960 | }; 2961 | 2962 | export type PromotionList = PaginatedList & { 2963 | __typename?: 'PromotionList'; 2964 | items: Array; 2965 | totalItems: Scalars['Int']; 2966 | }; 2967 | 2968 | export type PromotionListOptions = { 2969 | skip?: Maybe; 2970 | take?: Maybe; 2971 | sort?: Maybe; 2972 | filter?: Maybe; 2973 | }; 2974 | 2975 | export type PromotionSortParameter = { 2976 | id?: Maybe; 2977 | createdAt?: Maybe; 2978 | updatedAt?: Maybe; 2979 | startsAt?: Maybe; 2980 | endsAt?: Maybe; 2981 | couponCode?: Maybe; 2982 | perCustomerUsageLimit?: Maybe; 2983 | name?: Maybe; 2984 | }; 2985 | 2986 | export type Query = { 2987 | __typename?: 'Query'; 2988 | administrators: AdministratorList; 2989 | administrator?: Maybe; 2990 | /** Get a list of Assets */ 2991 | assets: AssetList; 2992 | /** Get a single Asset by id */ 2993 | asset?: Maybe; 2994 | me?: Maybe; 2995 | channels: Array; 2996 | channel?: Maybe; 2997 | activeChannel: Channel; 2998 | collections: CollectionList; 2999 | /** Get a Collection either by id or slug. If neither id nor slug is speicified, an error will result. */ 3000 | collection?: Maybe; 3001 | collectionFilters: Array; 3002 | countries: CountryList; 3003 | country?: Maybe; 3004 | customerGroups: CustomerGroupList; 3005 | customerGroup?: Maybe; 3006 | customers: CustomerList; 3007 | customer?: Maybe; 3008 | facets: FacetList; 3009 | facet?: Maybe; 3010 | globalSettings: GlobalSettings; 3011 | job?: Maybe; 3012 | jobs: JobList; 3013 | jobsById: Array; 3014 | jobQueues: Array; 3015 | order?: Maybe; 3016 | orders: OrderList; 3017 | paymentMethods: PaymentMethodList; 3018 | paymentMethod?: Maybe; 3019 | productOptionGroups: Array; 3020 | productOptionGroup?: Maybe; 3021 | search: SearchResponse; 3022 | products: ProductList; 3023 | /** Get a Product either by id or slug. If neither id nor slug is speicified, an error will result. */ 3024 | product?: Maybe; 3025 | promotion?: Maybe; 3026 | promotions: PromotionList; 3027 | promotionConditions: Array; 3028 | promotionActions: Array; 3029 | roles: RoleList; 3030 | role?: Maybe; 3031 | shippingMethods: ShippingMethodList; 3032 | shippingMethod?: Maybe; 3033 | shippingEligibilityCheckers: Array; 3034 | shippingCalculators: Array; 3035 | testShippingMethod: TestShippingMethodResult; 3036 | testEligibleShippingMethods: Array; 3037 | taxCategories: Array; 3038 | taxCategory?: Maybe; 3039 | taxRates: TaxRateList; 3040 | taxRate?: Maybe; 3041 | zones: Array; 3042 | zone?: Maybe; 3043 | examples: ExampleList; 3044 | example?: Maybe; 3045 | }; 3046 | 3047 | 3048 | export type QueryAdministratorsArgs = { 3049 | options?: Maybe; 3050 | }; 3051 | 3052 | 3053 | export type QueryAdministratorArgs = { 3054 | id: Scalars['ID']; 3055 | }; 3056 | 3057 | 3058 | export type QueryAssetsArgs = { 3059 | options?: Maybe; 3060 | }; 3061 | 3062 | 3063 | export type QueryAssetArgs = { 3064 | id: Scalars['ID']; 3065 | }; 3066 | 3067 | 3068 | export type QueryChannelArgs = { 3069 | id: Scalars['ID']; 3070 | }; 3071 | 3072 | 3073 | export type QueryCollectionsArgs = { 3074 | options?: Maybe; 3075 | }; 3076 | 3077 | 3078 | export type QueryCollectionArgs = { 3079 | id?: Maybe; 3080 | slug?: Maybe; 3081 | }; 3082 | 3083 | 3084 | export type QueryCountriesArgs = { 3085 | options?: Maybe; 3086 | }; 3087 | 3088 | 3089 | export type QueryCountryArgs = { 3090 | id: Scalars['ID']; 3091 | }; 3092 | 3093 | 3094 | export type QueryCustomerGroupsArgs = { 3095 | options?: Maybe; 3096 | }; 3097 | 3098 | 3099 | export type QueryCustomerGroupArgs = { 3100 | id: Scalars['ID']; 3101 | }; 3102 | 3103 | 3104 | export type QueryCustomersArgs = { 3105 | options?: Maybe; 3106 | }; 3107 | 3108 | 3109 | export type QueryCustomerArgs = { 3110 | id: Scalars['ID']; 3111 | }; 3112 | 3113 | 3114 | export type QueryFacetsArgs = { 3115 | options?: Maybe; 3116 | }; 3117 | 3118 | 3119 | export type QueryFacetArgs = { 3120 | id: Scalars['ID']; 3121 | }; 3122 | 3123 | 3124 | export type QueryJobArgs = { 3125 | jobId: Scalars['ID']; 3126 | }; 3127 | 3128 | 3129 | export type QueryJobsArgs = { 3130 | options?: Maybe; 3131 | }; 3132 | 3133 | 3134 | export type QueryJobsByIdArgs = { 3135 | jobIds: Array; 3136 | }; 3137 | 3138 | 3139 | export type QueryOrderArgs = { 3140 | id: Scalars['ID']; 3141 | }; 3142 | 3143 | 3144 | export type QueryOrdersArgs = { 3145 | options?: Maybe; 3146 | }; 3147 | 3148 | 3149 | export type QueryPaymentMethodsArgs = { 3150 | options?: Maybe; 3151 | }; 3152 | 3153 | 3154 | export type QueryPaymentMethodArgs = { 3155 | id: Scalars['ID']; 3156 | }; 3157 | 3158 | 3159 | export type QueryProductOptionGroupsArgs = { 3160 | filterTerm?: Maybe; 3161 | }; 3162 | 3163 | 3164 | export type QueryProductOptionGroupArgs = { 3165 | id: Scalars['ID']; 3166 | }; 3167 | 3168 | 3169 | export type QuerySearchArgs = { 3170 | input: SearchInput; 3171 | }; 3172 | 3173 | 3174 | export type QueryProductsArgs = { 3175 | options?: Maybe; 3176 | }; 3177 | 3178 | 3179 | export type QueryProductArgs = { 3180 | id?: Maybe; 3181 | slug?: Maybe; 3182 | }; 3183 | 3184 | 3185 | export type QueryPromotionArgs = { 3186 | id: Scalars['ID']; 3187 | }; 3188 | 3189 | 3190 | export type QueryPromotionsArgs = { 3191 | options?: Maybe; 3192 | }; 3193 | 3194 | 3195 | export type QueryRolesArgs = { 3196 | options?: Maybe; 3197 | }; 3198 | 3199 | 3200 | export type QueryRoleArgs = { 3201 | id: Scalars['ID']; 3202 | }; 3203 | 3204 | 3205 | export type QueryShippingMethodsArgs = { 3206 | options?: Maybe; 3207 | }; 3208 | 3209 | 3210 | export type QueryShippingMethodArgs = { 3211 | id: Scalars['ID']; 3212 | }; 3213 | 3214 | 3215 | export type QueryTestShippingMethodArgs = { 3216 | input: TestShippingMethodInput; 3217 | }; 3218 | 3219 | 3220 | export type QueryTestEligibleShippingMethodsArgs = { 3221 | input: TestEligibleShippingMethodsInput; 3222 | }; 3223 | 3224 | 3225 | export type QueryTaxCategoryArgs = { 3226 | id: Scalars['ID']; 3227 | }; 3228 | 3229 | 3230 | export type QueryTaxRatesArgs = { 3231 | options?: Maybe; 3232 | }; 3233 | 3234 | 3235 | export type QueryTaxRateArgs = { 3236 | id: Scalars['ID']; 3237 | }; 3238 | 3239 | 3240 | export type QueryZoneArgs = { 3241 | id: Scalars['ID']; 3242 | }; 3243 | 3244 | 3245 | export type QueryExamplesArgs = { 3246 | options?: Maybe; 3247 | }; 3248 | 3249 | 3250 | export type QueryExampleArgs = { 3251 | id: Scalars['ID']; 3252 | }; 3253 | 3254 | export type Refund = Node & { 3255 | __typename?: 'Refund'; 3256 | id: Scalars['ID']; 3257 | createdAt: Scalars['DateTime']; 3258 | updatedAt: Scalars['DateTime']; 3259 | items: Scalars['Int']; 3260 | shipping: Scalars['Int']; 3261 | adjustment: Scalars['Int']; 3262 | total: Scalars['Int']; 3263 | method?: Maybe; 3264 | state: Scalars['String']; 3265 | transactionId?: Maybe; 3266 | reason?: Maybe; 3267 | orderItems: Array; 3268 | paymentId: Scalars['ID']; 3269 | metadata?: Maybe; 3270 | }; 3271 | 3272 | export type RefundOrderInput = { 3273 | lines: Array; 3274 | shipping: Scalars['Int']; 3275 | adjustment: Scalars['Int']; 3276 | paymentId: Scalars['ID']; 3277 | reason?: Maybe; 3278 | }; 3279 | 3280 | export type RemoveProductsFromChannelInput = { 3281 | productIds: Array; 3282 | channelId: Scalars['ID']; 3283 | }; 3284 | 3285 | export type Return = Node & StockMovement & { 3286 | __typename?: 'Return'; 3287 | id: Scalars['ID']; 3288 | createdAt: Scalars['DateTime']; 3289 | updatedAt: Scalars['DateTime']; 3290 | productVariant: ProductVariant; 3291 | type: StockMovementType; 3292 | quantity: Scalars['Int']; 3293 | orderItem: OrderItem; 3294 | }; 3295 | 3296 | export type Role = Node & { 3297 | __typename?: 'Role'; 3298 | id: Scalars['ID']; 3299 | createdAt: Scalars['DateTime']; 3300 | updatedAt: Scalars['DateTime']; 3301 | code: Scalars['String']; 3302 | description: Scalars['String']; 3303 | permissions: Array; 3304 | channels: Array; 3305 | }; 3306 | 3307 | export type RoleFilterParameter = { 3308 | createdAt?: Maybe; 3309 | updatedAt?: Maybe; 3310 | code?: Maybe; 3311 | description?: Maybe; 3312 | }; 3313 | 3314 | export type RoleList = PaginatedList & { 3315 | __typename?: 'RoleList'; 3316 | items: Array; 3317 | totalItems: Scalars['Int']; 3318 | }; 3319 | 3320 | export type RoleListOptions = { 3321 | skip?: Maybe; 3322 | take?: Maybe; 3323 | sort?: Maybe; 3324 | filter?: Maybe; 3325 | }; 3326 | 3327 | export type RoleSortParameter = { 3328 | id?: Maybe; 3329 | createdAt?: Maybe; 3330 | updatedAt?: Maybe; 3331 | code?: Maybe; 3332 | description?: Maybe; 3333 | }; 3334 | 3335 | export type Sale = Node & StockMovement & { 3336 | __typename?: 'Sale'; 3337 | id: Scalars['ID']; 3338 | createdAt: Scalars['DateTime']; 3339 | updatedAt: Scalars['DateTime']; 3340 | productVariant: ProductVariant; 3341 | type: StockMovementType; 3342 | quantity: Scalars['Int']; 3343 | orderLine: OrderLine; 3344 | }; 3345 | 3346 | export type SearchInput = { 3347 | term?: Maybe; 3348 | facetValueIds?: Maybe>; 3349 | facetValueOperator?: Maybe; 3350 | collectionId?: Maybe; 3351 | groupByProduct?: Maybe; 3352 | take?: Maybe; 3353 | skip?: Maybe; 3354 | sort?: Maybe; 3355 | }; 3356 | 3357 | export type SearchReindexResponse = { 3358 | __typename?: 'SearchReindexResponse'; 3359 | success: Scalars['Boolean']; 3360 | }; 3361 | 3362 | export type SearchResponse = { 3363 | __typename?: 'SearchResponse'; 3364 | items: Array; 3365 | totalItems: Scalars['Int']; 3366 | facetValues: Array; 3367 | }; 3368 | 3369 | export type SearchResult = { 3370 | __typename?: 'SearchResult'; 3371 | enabled: Scalars['Boolean']; 3372 | /** An array of ids of the Collections in which this result appears */ 3373 | channelIds: Array; 3374 | sku: Scalars['String']; 3375 | slug: Scalars['String']; 3376 | productId: Scalars['ID']; 3377 | productName: Scalars['String']; 3378 | /** @deprecated Use `productAsset.preview` instead */ 3379 | productPreview: Scalars['String']; 3380 | productAsset?: Maybe; 3381 | productVariantId: Scalars['ID']; 3382 | productVariantName: Scalars['String']; 3383 | /** @deprecated Use `productVariantAsset.preview` instead */ 3384 | productVariantPreview: Scalars['String']; 3385 | productVariantAsset?: Maybe; 3386 | price: SearchResultPrice; 3387 | priceWithTax: SearchResultPrice; 3388 | currencyCode: CurrencyCode; 3389 | description: Scalars['String']; 3390 | facetIds: Array; 3391 | facetValueIds: Array; 3392 | /** An array of ids of the Collections in which this result appears */ 3393 | collectionIds: Array; 3394 | /** A relevence score for the result. Differs between database implementations */ 3395 | score: Scalars['Float']; 3396 | }; 3397 | 3398 | export type SearchResultAsset = { 3399 | __typename?: 'SearchResultAsset'; 3400 | id: Scalars['ID']; 3401 | preview: Scalars['String']; 3402 | focalPoint?: Maybe; 3403 | }; 3404 | 3405 | /** The price of a search result product, either as a range or as a single price */ 3406 | export type SearchResultPrice = PriceRange | SinglePrice; 3407 | 3408 | export type SearchResultSortParameter = { 3409 | name?: Maybe; 3410 | price?: Maybe; 3411 | }; 3412 | 3413 | export type ServerConfig = { 3414 | __typename?: 'ServerConfig'; 3415 | orderProcess: Array; 3416 | customFieldConfig: CustomFields; 3417 | }; 3418 | 3419 | export type SettleRefundInput = { 3420 | id: Scalars['ID']; 3421 | transactionId: Scalars['String']; 3422 | }; 3423 | 3424 | export type ShippingMethod = Node & { 3425 | __typename?: 'ShippingMethod'; 3426 | id: Scalars['ID']; 3427 | createdAt: Scalars['DateTime']; 3428 | updatedAt: Scalars['DateTime']; 3429 | code: Scalars['String']; 3430 | description: Scalars['String']; 3431 | checker: ConfigurableOperation; 3432 | calculator: ConfigurableOperation; 3433 | customFields?: Maybe; 3434 | }; 3435 | 3436 | export type ShippingMethodFilterParameter = { 3437 | createdAt?: Maybe; 3438 | updatedAt?: Maybe; 3439 | code?: Maybe; 3440 | description?: Maybe; 3441 | }; 3442 | 3443 | export type ShippingMethodList = PaginatedList & { 3444 | __typename?: 'ShippingMethodList'; 3445 | items: Array; 3446 | totalItems: Scalars['Int']; 3447 | }; 3448 | 3449 | export type ShippingMethodListOptions = { 3450 | skip?: Maybe; 3451 | take?: Maybe; 3452 | sort?: Maybe; 3453 | filter?: Maybe; 3454 | }; 3455 | 3456 | export type ShippingMethodQuote = { 3457 | __typename?: 'ShippingMethodQuote'; 3458 | id: Scalars['ID']; 3459 | price: Scalars['Int']; 3460 | priceWithTax: Scalars['Int']; 3461 | description: Scalars['String']; 3462 | metadata?: Maybe; 3463 | }; 3464 | 3465 | export type ShippingMethodSortParameter = { 3466 | id?: Maybe; 3467 | createdAt?: Maybe; 3468 | updatedAt?: Maybe; 3469 | code?: Maybe; 3470 | description?: Maybe; 3471 | }; 3472 | 3473 | /** The price value where the result has a single price */ 3474 | export type SinglePrice = { 3475 | __typename?: 'SinglePrice'; 3476 | value: Scalars['Int']; 3477 | }; 3478 | 3479 | export enum SortOrder { 3480 | Asc = 'ASC', 3481 | Desc = 'DESC' 3482 | } 3483 | 3484 | export type StockAdjustment = Node & StockMovement & { 3485 | __typename?: 'StockAdjustment'; 3486 | id: Scalars['ID']; 3487 | createdAt: Scalars['DateTime']; 3488 | updatedAt: Scalars['DateTime']; 3489 | productVariant: ProductVariant; 3490 | type: StockMovementType; 3491 | quantity: Scalars['Int']; 3492 | }; 3493 | 3494 | export type StockMovement = { 3495 | id: Scalars['ID']; 3496 | createdAt: Scalars['DateTime']; 3497 | updatedAt: Scalars['DateTime']; 3498 | productVariant: ProductVariant; 3499 | type: StockMovementType; 3500 | quantity: Scalars['Int']; 3501 | }; 3502 | 3503 | export type StockMovementItem = StockAdjustment | Sale | Cancellation | Return; 3504 | 3505 | export type StockMovementList = { 3506 | __typename?: 'StockMovementList'; 3507 | items: Array; 3508 | totalItems: Scalars['Int']; 3509 | }; 3510 | 3511 | export type StockMovementListOptions = { 3512 | type?: Maybe; 3513 | skip?: Maybe; 3514 | take?: Maybe; 3515 | }; 3516 | 3517 | export enum StockMovementType { 3518 | Adjustment = 'ADJUSTMENT', 3519 | Sale = 'SALE', 3520 | Cancellation = 'CANCELLATION', 3521 | Return = 'RETURN' 3522 | } 3523 | 3524 | export type StringCustomFieldConfig = CustomField & { 3525 | __typename?: 'StringCustomFieldConfig'; 3526 | name: Scalars['String']; 3527 | type: Scalars['String']; 3528 | length?: Maybe; 3529 | label?: Maybe>; 3530 | description?: Maybe>; 3531 | readonly?: Maybe; 3532 | internal?: Maybe; 3533 | pattern?: Maybe; 3534 | options?: Maybe>; 3535 | }; 3536 | 3537 | export type StringFieldOption = { 3538 | __typename?: 'StringFieldOption'; 3539 | value: Scalars['String']; 3540 | label?: Maybe>; 3541 | }; 3542 | 3543 | export type StringOperators = { 3544 | eq?: Maybe; 3545 | contains?: Maybe; 3546 | }; 3547 | 3548 | export type TaxCategory = Node & { 3549 | __typename?: 'TaxCategory'; 3550 | id: Scalars['ID']; 3551 | createdAt: Scalars['DateTime']; 3552 | updatedAt: Scalars['DateTime']; 3553 | name: Scalars['String']; 3554 | }; 3555 | 3556 | export type TaxRate = Node & { 3557 | __typename?: 'TaxRate'; 3558 | id: Scalars['ID']; 3559 | createdAt: Scalars['DateTime']; 3560 | updatedAt: Scalars['DateTime']; 3561 | name: Scalars['String']; 3562 | enabled: Scalars['Boolean']; 3563 | value: Scalars['Float']; 3564 | category: TaxCategory; 3565 | zone: Zone; 3566 | customerGroup?: Maybe; 3567 | }; 3568 | 3569 | export type TaxRateFilterParameter = { 3570 | createdAt?: Maybe; 3571 | updatedAt?: Maybe; 3572 | name?: Maybe; 3573 | enabled?: Maybe; 3574 | value?: Maybe; 3575 | }; 3576 | 3577 | export type TaxRateList = PaginatedList & { 3578 | __typename?: 'TaxRateList'; 3579 | items: Array; 3580 | totalItems: Scalars['Int']; 3581 | }; 3582 | 3583 | export type TaxRateListOptions = { 3584 | skip?: Maybe; 3585 | take?: Maybe; 3586 | sort?: Maybe; 3587 | filter?: Maybe; 3588 | }; 3589 | 3590 | export type TaxRateSortParameter = { 3591 | id?: Maybe; 3592 | createdAt?: Maybe; 3593 | updatedAt?: Maybe; 3594 | name?: Maybe; 3595 | value?: Maybe; 3596 | }; 3597 | 3598 | export type TestEligibleShippingMethodsInput = { 3599 | shippingAddress: CreateAddressInput; 3600 | lines: Array; 3601 | }; 3602 | 3603 | export type TestShippingMethodInput = { 3604 | checker: ConfigurableOperationInput; 3605 | calculator: ConfigurableOperationInput; 3606 | shippingAddress: CreateAddressInput; 3607 | lines: Array; 3608 | }; 3609 | 3610 | export type TestShippingMethodOrderLineInput = { 3611 | productVariantId: Scalars['ID']; 3612 | quantity: Scalars['Int']; 3613 | }; 3614 | 3615 | export type TestShippingMethodQuote = { 3616 | __typename?: 'TestShippingMethodQuote'; 3617 | price: Scalars['Int']; 3618 | priceWithTax: Scalars['Int']; 3619 | description: Scalars['String']; 3620 | metadata?: Maybe; 3621 | }; 3622 | 3623 | export type TestShippingMethodResult = { 3624 | __typename?: 'TestShippingMethodResult'; 3625 | eligible: Scalars['Boolean']; 3626 | quote?: Maybe; 3627 | }; 3628 | 3629 | export type UpdateAddressInput = { 3630 | id: Scalars['ID']; 3631 | fullName?: Maybe; 3632 | company?: Maybe; 3633 | streetLine1?: Maybe; 3634 | streetLine2?: Maybe; 3635 | city?: Maybe; 3636 | province?: Maybe; 3637 | postalCode?: Maybe; 3638 | countryCode?: Maybe; 3639 | phoneNumber?: Maybe; 3640 | defaultShippingAddress?: Maybe; 3641 | defaultBillingAddress?: Maybe; 3642 | customFields?: Maybe; 3643 | }; 3644 | 3645 | export type UpdateAdministratorInput = { 3646 | id: Scalars['ID']; 3647 | firstName?: Maybe; 3648 | lastName?: Maybe; 3649 | emailAddress?: Maybe; 3650 | password?: Maybe; 3651 | roleIds?: Maybe>; 3652 | }; 3653 | 3654 | export type UpdateAssetInput = { 3655 | id: Scalars['ID']; 3656 | name?: Maybe; 3657 | focalPoint?: Maybe; 3658 | }; 3659 | 3660 | export type UpdateChannelInput = { 3661 | id: Scalars['ID']; 3662 | code?: Maybe; 3663 | token?: Maybe; 3664 | defaultLanguageCode?: Maybe; 3665 | pricesIncludeTax?: Maybe; 3666 | currencyCode?: Maybe; 3667 | defaultTaxZoneId?: Maybe; 3668 | defaultShippingZoneId?: Maybe; 3669 | }; 3670 | 3671 | export type UpdateCollectionInput = { 3672 | id: Scalars['ID']; 3673 | isPrivate?: Maybe; 3674 | featuredAssetId?: Maybe; 3675 | parentId?: Maybe; 3676 | assetIds?: Maybe>; 3677 | filters?: Maybe>; 3678 | translations?: Maybe>; 3679 | customFields?: Maybe; 3680 | }; 3681 | 3682 | export type UpdateCollectionTranslationInput = { 3683 | id?: Maybe; 3684 | languageCode: LanguageCode; 3685 | name?: Maybe; 3686 | slug?: Maybe; 3687 | description?: Maybe; 3688 | customFields?: Maybe; 3689 | }; 3690 | 3691 | export type UpdateCountryInput = { 3692 | id: Scalars['ID']; 3693 | code?: Maybe; 3694 | translations?: Maybe>; 3695 | enabled?: Maybe; 3696 | }; 3697 | 3698 | export type UpdateCustomerGroupInput = { 3699 | id: Scalars['ID']; 3700 | name?: Maybe; 3701 | }; 3702 | 3703 | export type UpdateCustomerInput = { 3704 | id: Scalars['ID']; 3705 | title?: Maybe; 3706 | firstName?: Maybe; 3707 | lastName?: Maybe; 3708 | phoneNumber?: Maybe; 3709 | emailAddress?: Maybe; 3710 | customFields?: Maybe; 3711 | }; 3712 | 3713 | export type UpdateCustomerNoteInput = { 3714 | noteId: Scalars['ID']; 3715 | note: Scalars['String']; 3716 | }; 3717 | 3718 | export type UpdateExampleInput = { 3719 | id: Scalars['ID']; 3720 | name: Scalars['String']; 3721 | }; 3722 | 3723 | export type UpdateFacetInput = { 3724 | id: Scalars['ID']; 3725 | isPrivate?: Maybe; 3726 | code?: Maybe; 3727 | translations?: Maybe>; 3728 | customFields?: Maybe; 3729 | }; 3730 | 3731 | export type UpdateFacetValueInput = { 3732 | id: Scalars['ID']; 3733 | code?: Maybe; 3734 | translations?: Maybe>; 3735 | customFields?: Maybe; 3736 | }; 3737 | 3738 | export type UpdateGlobalSettingsInput = { 3739 | availableLanguages?: Maybe>; 3740 | trackInventory?: Maybe; 3741 | customFields?: Maybe; 3742 | }; 3743 | 3744 | export type UpdateOrderInput = { 3745 | id: Scalars['ID']; 3746 | customFields?: Maybe; 3747 | }; 3748 | 3749 | export type UpdateOrderNoteInput = { 3750 | noteId: Scalars['ID']; 3751 | note?: Maybe; 3752 | isPublic?: Maybe; 3753 | }; 3754 | 3755 | export type UpdatePaymentMethodInput = { 3756 | id: Scalars['ID']; 3757 | code?: Maybe; 3758 | enabled?: Maybe; 3759 | configArgs?: Maybe>; 3760 | }; 3761 | 3762 | export type UpdateProductInput = { 3763 | id: Scalars['ID']; 3764 | enabled?: Maybe; 3765 | featuredAssetId?: Maybe; 3766 | assetIds?: Maybe>; 3767 | facetValueIds?: Maybe>; 3768 | translations?: Maybe>; 3769 | customFields?: Maybe; 3770 | }; 3771 | 3772 | export type UpdateProductOptionGroupInput = { 3773 | id: Scalars['ID']; 3774 | code?: Maybe; 3775 | translations?: Maybe>; 3776 | customFields?: Maybe; 3777 | }; 3778 | 3779 | export type UpdateProductOptionInput = { 3780 | id: Scalars['ID']; 3781 | code?: Maybe; 3782 | translations?: Maybe>; 3783 | customFields?: Maybe; 3784 | }; 3785 | 3786 | export type UpdateProductVariantInput = { 3787 | id: Scalars['ID']; 3788 | enabled?: Maybe; 3789 | translations?: Maybe>; 3790 | facetValueIds?: Maybe>; 3791 | sku?: Maybe; 3792 | taxCategoryId?: Maybe; 3793 | price?: Maybe; 3794 | featuredAssetId?: Maybe; 3795 | assetIds?: Maybe>; 3796 | stockOnHand?: Maybe; 3797 | trackInventory?: Maybe; 3798 | customFields?: Maybe; 3799 | }; 3800 | 3801 | export type UpdatePromotionInput = { 3802 | id: Scalars['ID']; 3803 | name?: Maybe; 3804 | enabled?: Maybe; 3805 | startsAt?: Maybe; 3806 | endsAt?: Maybe; 3807 | couponCode?: Maybe; 3808 | perCustomerUsageLimit?: Maybe; 3809 | conditions?: Maybe>; 3810 | actions?: Maybe>; 3811 | }; 3812 | 3813 | export type UpdateRoleInput = { 3814 | id: Scalars['ID']; 3815 | code?: Maybe; 3816 | description?: Maybe; 3817 | permissions?: Maybe>; 3818 | channelIds?: Maybe>; 3819 | }; 3820 | 3821 | export type UpdateShippingMethodInput = { 3822 | id: Scalars['ID']; 3823 | code?: Maybe; 3824 | description?: Maybe; 3825 | checker?: Maybe; 3826 | calculator?: Maybe; 3827 | customFields?: Maybe; 3828 | }; 3829 | 3830 | export type UpdateTaxCategoryInput = { 3831 | id: Scalars['ID']; 3832 | name?: Maybe; 3833 | }; 3834 | 3835 | export type UpdateTaxRateInput = { 3836 | id: Scalars['ID']; 3837 | name?: Maybe; 3838 | value?: Maybe; 3839 | enabled?: Maybe; 3840 | categoryId?: Maybe; 3841 | zoneId?: Maybe; 3842 | customerGroupId?: Maybe; 3843 | }; 3844 | 3845 | export type UpdateZoneInput = { 3846 | id: Scalars['ID']; 3847 | name?: Maybe; 3848 | }; 3849 | 3850 | 3851 | export type User = Node & { 3852 | __typename?: 'User'; 3853 | id: Scalars['ID']; 3854 | createdAt: Scalars['DateTime']; 3855 | updatedAt: Scalars['DateTime']; 3856 | identifier: Scalars['String']; 3857 | verified: Scalars['Boolean']; 3858 | roles: Array; 3859 | lastLogin?: Maybe; 3860 | authenticationMethods: Array; 3861 | customFields?: Maybe; 3862 | }; 3863 | 3864 | export type Zone = Node & { 3865 | __typename?: 'Zone'; 3866 | id: Scalars['ID']; 3867 | createdAt: Scalars['DateTime']; 3868 | updatedAt: Scalars['DateTime']; 3869 | name: Scalars['String']; 3870 | members: Array; 3871 | }; 3872 | 3873 | export namespace AddExample { 3874 | export type Variables = AddExampleMutationVariables; 3875 | export type Mutation = AddExampleMutation; 3876 | export type AddExample = AddExampleMutation['addExample']; 3877 | } 3878 | 3879 | export namespace UpdateExample { 3880 | export type Variables = UpdateExampleMutationVariables; 3881 | export type Mutation = UpdateExampleMutation; 3882 | export type UpdateExample = UpdateExampleMutation['updateExample']; 3883 | } 3884 | 3885 | export namespace GetExamples { 3886 | export type Variables = GetExamplesQueryVariables; 3887 | export type Query = GetExamplesQuery; 3888 | export type Examples = GetExamplesQuery['examples']; 3889 | export type Items = (NonNullable); 3890 | } 3891 | 3892 | export namespace GetExample { 3893 | export type Variables = GetExampleQueryVariables; 3894 | export type Query = GetExampleQuery; 3895 | export type Example = (NonNullable); 3896 | } 3897 | 3898 | export type AddExampleMutationVariables = Exact<{ 3899 | input: CreateExampleInput; 3900 | }>; 3901 | 3902 | 3903 | export type AddExampleMutation = ( 3904 | { __typename?: 'Mutation' } 3905 | & { addExample: ( 3906 | { __typename?: 'Example' } 3907 | & Pick 3908 | ) } 3909 | ); 3910 | 3911 | export type UpdateExampleMutationVariables = Exact<{ 3912 | input: UpdateExampleInput; 3913 | }>; 3914 | 3915 | 3916 | export type UpdateExampleMutation = ( 3917 | { __typename?: 'Mutation' } 3918 | & { updateExample: ( 3919 | { __typename?: 'Example' } 3920 | & Pick 3921 | ) } 3922 | ); 3923 | 3924 | export type GetExamplesQueryVariables = Exact<{ 3925 | options?: Maybe; 3926 | }>; 3927 | 3928 | 3929 | export type GetExamplesQuery = ( 3930 | { __typename?: 'Query' } 3931 | & { examples: ( 3932 | { __typename?: 'ExampleList' } 3933 | & Pick 3934 | & { items: Array<( 3935 | { __typename?: 'Example' } 3936 | & Pick 3937 | )> } 3938 | ) } 3939 | ); 3940 | 3941 | export type GetExampleQueryVariables = Exact<{ 3942 | id: Scalars['ID']; 3943 | }>; 3944 | 3945 | 3946 | export type GetExampleQuery = ( 3947 | { __typename?: 'Query' } 3948 | & { example?: Maybe<( 3949 | { __typename?: 'Example' } 3950 | & Pick 3951 | )> } 3952 | ); 3953 | -------------------------------------------------------------------------------- /plugins/extended-shipments/src/ui/geo-selector.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { NgSelectModule } from '@ng-select/ng-select'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { SharedModule } from '@vendure/admin-ui/core'; 5 | import { registerFormInputComponent } from '@vendure/admin-ui/core'; 6 | import { ZoneSelectorInputComponent } from './components/zone-selector-component/zone-selector.component'; 7 | import { CountrySelectorInputComponent } from './components/country-selector-component/country-selector.component'; 8 | 9 | @NgModule({ 10 | imports: [NgSelectModule, FormsModule, SharedModule], 11 | declarations: [ZoneSelectorInputComponent, CountrySelectorInputComponent], 12 | providers: [ 13 | registerFormInputComponent('zone-selector', ZoneSelectorInputComponent), 14 | registerFormInputComponent('country-selector', CountrySelectorInputComponent), 15 | ] 16 | }) 17 | export class GeoSelectorModule {} -------------------------------------------------------------------------------- /plugins/extended-shipments/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets total weight from an order, with output in a certain weight unit (g or kg) 3 | */ 4 | 5 | import { Order, OrderLine } from "@vendure/core"; 6 | import { WeightUnit } from "./types"; 7 | 8 | export const getOrderWeight: (order: Order, resultUnit: WeightUnit) => number = 9 | (order, resultUnit) => 10 | order.lines 11 | .map((line: OrderLine) => { 12 | const lineWeightUoM = (line.productVariant.customFields as any) 13 | .weightUoM; 14 | const lineWeight = 15 | (line.productVariant.customFields as any).weight ?? 0; 16 | if (lineWeightUoM === resultUnit) return lineWeight * line.quantity; 17 | else { 18 | if (lineWeightUoM === "g") return (lineWeight / 1000) * line.quantity; 19 | else if (lineWeightUoM === "kg") 20 | return lineWeight * 1000 * line.quantity; 21 | } 22 | return 0; 23 | }) 24 | .reduce((total, lineWeight) => total + lineWeight, 0); 25 | -------------------------------------------------------------------------------- /plugins/extended-shipments/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"], 20 | "exclude": ["src/ui/*"] 21 | } 22 | -------------------------------------------------------------------------------- /plugins/featured-plugin/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artcoded-net/vendure-plugins/38e022ccef8eb6ae1635eaf47db7f51821c89a17/plugins/featured-plugin/.DS_Store -------------------------------------------------------------------------------- /plugins/featured-plugin/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/featured-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Featured collections and products plugin for Vendure 2 | 3 | This simple plugin just introduces "featured" checkboxes for collections and products in order to allow the shop maintainer to mark that collection/product to be shown with more relevance, respectively in a list of collections and in a product list (e.g. products in a specific collection) 4 | -------------------------------------------------------------------------------- /plugins/featured-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/vendure-featured-plugin", 3 | "version": "0.2.5", 4 | "author": { 5 | "name": "Artcoded", 6 | "email": "dev@artcoded.net", 7 | "url": "https://artcoded.net" 8 | }, 9 | "description": "Simple plugin for Vendure that adds the capability to set collections and products as 'featured'", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "README.md", 15 | "LICENSE.md" 16 | ], 17 | "dependencies": { 18 | "@vendure/core": "^1.2.0" 19 | }, 20 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817", 21 | "license": "MIT", 22 | "publishConfig": { 23 | "access": "public" 24 | }, 25 | "scripts": { 26 | "build": "rimraf dist && tsc", 27 | "prepare": "yarn build", 28 | "link": "yarn link" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugins/featured-plugin/src/custom-fields.ts: -------------------------------------------------------------------------------- 1 | import { LanguageCode, CustomFields } from '@vendure/core'; 2 | 3 | const CollectionCustomFields: CustomFields['Collection'] = [ 4 | { 5 | name: 'featured', 6 | type: 'boolean', 7 | label: [ 8 | {languageCode: LanguageCode.en, value: 'Mark as featured'}, 9 | {languageCode: LanguageCode.it, value: 'Metti in evidenza'} 10 | ], 11 | description: [ 12 | {languageCode: LanguageCode.en, value: 'Check this box to show this facet in featured facets selection (e.g. home page slider)'}, 13 | {languageCode: LanguageCode.it, value: 'Spunta questa casella per inserire questo attributo tra quelli in evidenza (es. slider nella home page)'} 14 | ], 15 | defaultValue: false 16 | } 17 | ]; 18 | 19 | const ProductCustomFields: CustomFields['Product'] = [ 20 | { 21 | name: 'featured', 22 | type: 'boolean', 23 | label: [ 24 | {languageCode: LanguageCode.en, value: 'Mark as featured'}, 25 | {languageCode: LanguageCode.it, value: 'Metti in evidenza'} 26 | ], 27 | description: [ 28 | {languageCode: LanguageCode.en, value: 'Check this box to show this product with more relevance in its facets'}, 29 | {languageCode: LanguageCode.it, value: 'Spunta questa casella mostrare il prodotto con maggiore evidenza nelle rispettive pagine'} 30 | ], 31 | defaultValue: false 32 | } 33 | ]; 34 | 35 | export { ProductCustomFields, CollectionCustomFields }; -------------------------------------------------------------------------------- /plugins/featured-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export { FeaturedPlugin } from './plugin'; -------------------------------------------------------------------------------- /plugins/featured-plugin/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginCommonModule, VendurePlugin } from "@vendure/core"; 2 | import { CollectionCustomFields, ProductCustomFields } from "./custom-fields"; 3 | 4 | @VendurePlugin({ 5 | imports: [PluginCommonModule], 6 | providers: [], 7 | configuration: (config) => { 8 | config.customFields.Collection.push(...CollectionCustomFields!); 9 | config.customFields.Product.push(...ProductCustomFields!); 10 | return config; 11 | }, 12 | }) 13 | export class FeaturedPlugin {} 14 | -------------------------------------------------------------------------------- /plugins/featured-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"] 20 | } 21 | -------------------------------------------------------------------------------- /plugins/gcp-storage/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artcoded-net/vendure-plugins/38e022ccef8eb6ae1635eaf47db7f51821c89a17/plugins/gcp-storage/.DS_Store -------------------------------------------------------------------------------- /plugins/gcp-storage/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/gcp-storage/README.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | 3 | This is just a slight adaptation of this great [plugin by Pinelab](https://github.com/martijnvdbrug/pinelab-vendure-plugins/tree/master/packages/vendure-plugin-google-storage-assets) 4 | -------------------------------------------------------------------------------- /plugins/gcp-storage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/gcp-asset-server-plugin", 3 | "version": "1.0.6", 4 | "author": { 5 | "name": "Artcoded", 6 | "email": "dev@artcoded.net", 7 | "url": "https://artcoded.net" 8 | }, 9 | "description": "Plugin for using Google Cloud Storage for Vendure Assets (full credits to Pinelab, see README)", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "README.md", 15 | "LICENSE.md" 16 | ], 17 | "dependencies": { 18 | "@google-cloud/storage": "latest", 19 | "@vendure/asset-server-plugin": "^1.2.0", 20 | "mime-types": "latest", 21 | "sharp": "^0.28.3", 22 | "@vendure/core": "^1.2.0" 23 | }, 24 | "devDependencies": { 25 | "@types/mime-types": "latest", 26 | "@types/sharp": "latest" 27 | }, 28 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817", 29 | "license": "MIT", 30 | "publishConfig": { 31 | "access": "public" 32 | }, 33 | "scripts": { 34 | "build": "rimraf dist && tsc", 35 | "prepare": "yarn build", 36 | "link": "yarn link" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/asset-thumbnail.resolvers.ts: -------------------------------------------------------------------------------- 1 | import { Parent, ResolveField, Resolver } from '@nestjs/graphql'; 2 | import { Asset, ConfigService, Ctx, RequestContext } from '@vendure/core'; 3 | 4 | @Resolver() 5 | export class AssetThumbnailResolvers { 6 | constructor(private configService: ConfigService) {} 7 | 8 | @ResolveField('thumbnail') 9 | @Resolver('Asset') 10 | thumbnail(@Ctx() ctx: RequestContext, @Parent() asset: Asset): string { 11 | const { assetOptions } = this.configService; 12 | if (assetOptions.assetStorageStrategy.toAbsoluteUrl) { 13 | return assetOptions.assetStorageStrategy.toAbsoluteUrl( 14 | ctx.req!, 15 | `${asset.preview}_thumbnail.jpg` 16 | ); 17 | } else { 18 | return `${asset.preview}_thumbnail.jpg`; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/asset-thumbnail.schema.ts: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | 3 | export const assetThumbnailSchema = gql` 4 | extend type Asset { 5 | thumbnail: String! 6 | } 7 | `; 8 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/google-storage-config.ts: -------------------------------------------------------------------------------- 1 | export interface GoogleStorageConfig { 2 | bucketName: string; 3 | thumbnails?: { 4 | height: number; 5 | width: number; 6 | }; 7 | cdnUrl?: string; 8 | } 9 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/google-storage-plugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginCommonModule, VendurePlugin } from '@vendure/core'; 2 | import { assetThumbnailSchema } from './asset-thumbnail.schema'; 3 | import { AssetThumbnailResolvers } from './asset-thumbnail.resolvers'; 4 | 5 | @VendurePlugin({ 6 | imports: [PluginCommonModule], 7 | shopApiExtensions: { 8 | schema: assetThumbnailSchema, 9 | resolvers: [AssetThumbnailResolvers], 10 | }, 11 | adminApiExtensions: { 12 | schema: assetThumbnailSchema, 13 | resolvers: [AssetThumbnailResolvers], 14 | }, 15 | }) 16 | export class GoogleStoragePlugin { 17 | context = 'GoogleStoragePlugin'; 18 | } 19 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/google-storage-strategy.ts: -------------------------------------------------------------------------------- 1 | import { AssetStorageStrategy } from "@vendure/core"; 2 | import { Storage } from "@google-cloud/storage"; 3 | import { Request } from "express"; 4 | import { Stream } from "stream"; 5 | import * as tmp from "tmp"; 6 | import * as fs from "fs"; 7 | import { GoogleStorageConfig } from "./google-storage-config"; 8 | import sharp from "sharp"; 9 | 10 | export class GoogleStorageStrategy implements AssetStorageStrategy { 11 | storage: Storage; 12 | urlPrefix = "https://storage.googleapis.com"; 13 | cdnUrl: string | undefined; 14 | bucketName: string; 15 | 16 | constructor(private config: GoogleStorageConfig) { 17 | this.bucketName = config.bucketName; 18 | if (!config.thumbnails) { 19 | config.thumbnails = { 20 | height: 300, 21 | width: 300, 22 | }; 23 | } 24 | this.storage = new Storage(); 25 | this.cdnUrl = config.cdnUrl; 26 | } 27 | 28 | toAbsoluteUrl(request: Request | undefined, identifier: string): string { 29 | if ((request as any)?.vendureRequestContext?._apiType === "admin") { 30 | // go via assetServer if admin 31 | return `${request!.protocol}://${request!.get( 32 | "host" 33 | )}/assets/${identifier}`; 34 | } 35 | if (this.cdnUrl) return `${this.cdnUrl}/${identifier}`; 36 | return `${this.urlPrefix}/${this.bucketName}/${identifier}`; 37 | } 38 | 39 | async deleteFile(identifier: string): Promise { 40 | await this.storage.bucket(this.bucketName).file(identifier).delete(); 41 | } 42 | 43 | async fileExists(fileName: string): Promise { 44 | const [exists] = await this.storage 45 | .bucket(this.bucketName) 46 | .file(fileName) 47 | .exists(); 48 | return exists; 49 | } 50 | 51 | async readFileToBuffer(identifier: string): Promise { 52 | if (identifier?.startsWith("/")) { 53 | identifier = identifier.replace("/", ""); 54 | } 55 | const tmpFile = tmp.fileSync(); 56 | await this.storage 57 | .bucket(this.bucketName) 58 | .file(identifier) 59 | .download({ destination: tmpFile.name }); 60 | return fs.readFileSync(tmpFile.name); 61 | } 62 | 63 | async readFileToStream(identifier: string): Promise { 64 | if (identifier?.startsWith("/")) { 65 | identifier = identifier.replace("/", ""); 66 | } 67 | return this.storage 68 | .bucket(this.bucketName) 69 | .file(identifier) 70 | .createReadStream(); 71 | } 72 | 73 | async writeFileFromBuffer(fileName: string, data: Buffer): Promise { 74 | const tmpFile = tmp.fileSync(); 75 | fs.writeFileSync(tmpFile.name, data); 76 | await this.storage.bucket(this.bucketName).upload(tmpFile.name, { 77 | destination: fileName, 78 | }); 79 | if (fileName.startsWith("preview/")) { 80 | await this.writeThumbnail(fileName, tmpFile.name); 81 | } 82 | return fileName; 83 | } 84 | 85 | async writeFileFromStream(fileName: string, data: Stream): Promise { 86 | const blob = this.storage.bucket(this.bucketName).file(fileName); 87 | const uploadStream = blob.createWriteStream(); 88 | await Promise.all([ 89 | this.streamToPromise(data.pipe(uploadStream)), 90 | this.streamToPromise(uploadStream), 91 | ]); 92 | return fileName; 93 | } 94 | 95 | streamToPromise(stream: Stream): Promise { 96 | return new Promise(function (resolve, reject) { 97 | stream.on("end", resolve); 98 | stream.on("finish", resolve); 99 | stream.on("close", resolve); 100 | stream.on("error", reject); 101 | }); 102 | } 103 | 104 | /** 105 | * Transforms local file to thumbnail (jpg) and uploads to Storage 106 | */ 107 | async writeThumbnail(fileName: string, localFilePath: string): Promise { 108 | const tmpFile = tmp.fileSync({ postfix: ".jpg" }); 109 | await sharp(localFilePath) 110 | .resize({ 111 | width: this.config.thumbnails!.width, 112 | height: this.config.thumbnails!.height, 113 | }) 114 | .toFile(tmpFile.name); 115 | await this.storage.bucket(this.bucketName).upload(tmpFile.name, { 116 | destination: `${fileName}_thumbnail.jpg`, 117 | }); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /plugins/gcp-storage/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './google-storage-strategy'; 2 | export * from './google-storage-plugin'; 3 | export * from './google-storage-config'; 4 | -------------------------------------------------------------------------------- /plugins/gcp-storage/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"] 20 | } 21 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artcoded-net/vendure-plugins/38e022ccef8eb6ae1635eaf47db7f51821c89a17/plugins/jobqueue-plugin/.DS_Store -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Vendure plugin for Worker's Job Queue based Google Cloud Platform PubSub 2 | 3 | This plugin is now deprecated, as we have found better results using Google Cloud Tasks and the related [great plugin](https://github.com/martijnvdbrug/pinelab-vendure-plugins/tree/master/packages/vendure-plugin-google-cloud-tasks) by Pinelab 4 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/job-queue-plugin", 3 | "main": "dist/index.js", 4 | "types": "dist/index.d.ts", 5 | "files": [ 6 | "dist", 7 | "README.md", 8 | "LICENSE.md" 9 | ], 10 | "version": "0.2.11", 11 | "author": { 12 | "name": "Artcoded", 13 | "email": "dev@artcoded.net", 14 | "url": "https://artcoded.net" 15 | }, 16 | "description": "Vendure plugin for JobQueue implementation using Google Cloud PubSub, taken from Vendure main repo", 17 | "dependencies": { 18 | "@google-cloud/pubsub": "latest", 19 | "@vendure/core": "^1.2.0" 20 | }, 21 | "license": "MIT", 22 | "publishConfig": { 23 | "access": "public" 24 | }, 25 | "scripts": { 26 | "build": "rimraf dist && tsc", 27 | "prepare": "yarn build" 28 | }, 29 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817" 30 | } 31 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const PUB_SUB_OPTIONS = Symbol('PUB_SUB_OPTIONS'); 2 | export const loggerCtx = 'PubSubPlugin'; 3 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './plugin'; 2 | export * from './options'; 3 | export * from './jobs-queues'; 4 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/jobs-queues.ts: -------------------------------------------------------------------------------- 1 | export const jobsQueues = [ 2 | "apply-collection-filters", 3 | "send-email", 4 | "update-search-index", 5 | ]; 6 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/options.ts: -------------------------------------------------------------------------------- 1 | export interface PubSubOptions { 2 | /** 3 | * @description 4 | * Number of jobs that can be inflight at the same time. 5 | */ 6 | concurrency?: number; 7 | /** 8 | * @description 9 | * This is the mapping of Vendure queue names to PubSub Topics and Subscriptions 10 | * For each queue a topic and subscription is required to exist. 11 | */ 12 | queueNamePubSubPair?: Map; 13 | } 14 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { PubSub } from "@google-cloud/pubsub"; 2 | import { PluginCommonModule, Type, VendurePlugin } from "@vendure/core"; 3 | 4 | import { PUB_SUB_OPTIONS } from "./constants"; 5 | import { PubSubOptions } from "./options"; 6 | import { PubSubJobQueueStrategy } from "./pub-sub-job-queue-strategy"; 7 | 8 | @VendurePlugin({ 9 | imports: [PluginCommonModule], 10 | providers: [ 11 | { provide: PUB_SUB_OPTIONS, useFactory: () => PubSubPlugin.options }, 12 | { provide: PubSub, useFactory: () => new PubSub() }, 13 | ], 14 | configuration: (config) => { 15 | config.jobQueueOptions.jobQueueStrategy = new PubSubJobQueueStrategy(); 16 | return config; 17 | }, 18 | }) 19 | export class PubSubPlugin { 20 | private static options: PubSubOptions; 21 | 22 | static init(options: PubSubOptions): Type { 23 | this.options = options; 24 | return PubSubPlugin; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/pub-sub-job-queue-strategy.spec.ts: -------------------------------------------------------------------------------- 1 | import { PubSub } from '@google-cloud/pubsub'; 2 | import { ModuleRef } from '@nestjs/core'; 3 | import { Test } from '@nestjs/testing'; 4 | import { Injector, Job } from '@vendure/core'; 5 | 6 | import { PUB_SUB_OPTIONS } from './constants'; 7 | import { PubSubOptions } from './options'; 8 | import { PubSubJobQueueStrategy } from './pub-sub-job-queue-strategy'; 9 | 10 | describe('PubSubJobQueueStrategy', () => { 11 | let strategy: PubSubJobQueueStrategy; 12 | let pubsub: any; 13 | let topic: any; 14 | 15 | beforeEach(async () => { 16 | topic = { 17 | publish: jest.fn(), 18 | }; 19 | pubsub = { 20 | topic: jest.fn(() => { 21 | return topic; 22 | }), 23 | }; 24 | 25 | const options = { 26 | concurrency: 1, 27 | queueNamePubSubPair: new Map([['test-queue', ['test-topic', 'test-subscription']]]), 28 | } as PubSubOptions; 29 | 30 | const moduleRef = await Test.createTestingModule({ 31 | providers: [ 32 | { provide: PubSub, useValue: pubsub }, 33 | { provide: PUB_SUB_OPTIONS, useValue: options }, 34 | ], 35 | }).compile(); 36 | 37 | strategy = new PubSubJobQueueStrategy(); 38 | strategy.init(new Injector(moduleRef.get(ModuleRef))); 39 | }); 40 | 41 | it('cannot publish to not configured queue', async () => { 42 | expect.assertions(2); 43 | try { 44 | await strategy.add( 45 | new Job({ 46 | queueName: 'some-queue', 47 | data: {}, 48 | }), 49 | ); 50 | } catch (err) { 51 | expect(err).toEqual(new Error('Topic name not set for queue: some-queue')); 52 | } 53 | expect(pubsub.topic).not.toHaveBeenCalled(); 54 | }); 55 | 56 | it('publishes new jobs to topic', async () => { 57 | const data = { 58 | some: 'data', 59 | }; 60 | await strategy.add( 61 | new Job({ 62 | queueName: 'test-queue', 63 | data, 64 | }), 65 | ); 66 | expect(pubsub.topic).toHaveBeenCalledWith('test-topic'); 67 | expect(topic.publish).toHaveBeenCalledWith(Buffer.from(JSON.stringify(data))); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/src/pub-sub-job-queue-strategy.ts: -------------------------------------------------------------------------------- 1 | import { Message, PubSub, Subscription, Topic } from "@google-cloud/pubsub"; 2 | import { JobState } from "@vendure/common/lib/generated-types"; 3 | import { 4 | InjectableJobQueueStrategy, 5 | Injector, 6 | Job, 7 | JobData, 8 | JobQueueStrategy, 9 | Logger, 10 | QueueNameProcessStorage, 11 | } from "@vendure/core"; 12 | 13 | import { loggerCtx, PUB_SUB_OPTIONS } from "./constants"; 14 | import { PubSubOptions } from "./options"; 15 | 16 | export class PubSubJobQueueStrategy 17 | extends InjectableJobQueueStrategy 18 | implements JobQueueStrategy 19 | { 20 | //@ts-ignore 21 | private concurrency: number; 22 | //@ts-ignore 23 | private queueNamePubSubPair: Map; 24 | //@ts-ignore 25 | private pubSubClient: PubSub; 26 | //@ts-ignore 27 | private topics = new Map(); 28 | //@ts-ignore 29 | private subscriptions = new Map(); 30 | //@ts-ignore 31 | private listeners = new QueueNameProcessStorage<(message: Message) => void>(); 32 | 33 | init(injector: Injector) { 34 | this.pubSubClient = injector.get(PubSub); 35 | const options = injector.get(PUB_SUB_OPTIONS); 36 | this.concurrency = options.concurrency ?? 20; 37 | this.queueNamePubSubPair = options.queueNamePubSubPair ?? new Map(); 38 | 39 | super.init(injector); 40 | } 41 | 42 | destroy() { 43 | super.destroy(); 44 | for (const subscription of this.subscriptions.values()) { 45 | subscription.removeAllListeners("message"); 46 | } 47 | this.subscriptions.clear(); 48 | this.topics.clear(); 49 | } 50 | 51 | async add = {}>( 52 | job: Job 53 | ): Promise> { 54 | if (!this.hasInitialized) { 55 | throw new Error("Cannot add job before init"); 56 | } 57 | 58 | const id = await this.topic(job.queueName).publish( 59 | Buffer.from(JSON.stringify(job.data)) 60 | ); 61 | Logger.debug(`Sent message ${job.queueName}: ${id}`); 62 | 63 | return new Job({ 64 | id, 65 | queueName: job.queueName, 66 | data: job.data, 67 | attempts: 0, 68 | state: JobState.PENDING, 69 | createdAt: new Date(), 70 | }); 71 | } 72 | 73 | async start = {}>( 74 | queueName: string, 75 | process: (job: Job) => Promise 76 | ) { 77 | if (!this.hasInitialized) { 78 | this.started.set(queueName, process); 79 | return; 80 | } 81 | 82 | if (this.listeners.has(queueName, process)) { 83 | return; 84 | } 85 | 86 | const subscription = this.subscription(queueName); 87 | Logger.debug(`Retrieved subscription: ${subscription}`, loggerCtx); 88 | const listener = (message: Message) => { 89 | Logger.debug( 90 | `Received message (listened): ${queueName}: ${message.id}`, 91 | loggerCtx 92 | ); 93 | 94 | const job = new Job({ 95 | id: message.id, 96 | queueName, 97 | data: JSON.parse(message.data.toString()), 98 | attempts: message.deliveryAttempt, 99 | state: JobState.RUNNING, 100 | startedAt: new Date(), 101 | createdAt: message.publishTime, 102 | }); 103 | 104 | process(job) 105 | .then(() => { 106 | message.ack(); 107 | }) 108 | .catch((err) => { 109 | Logger.error(err, loggerCtx); 110 | message.nack(); 111 | }); 112 | }; 113 | this.listeners.set(queueName, process, listener); 114 | subscription.on("message", listener); 115 | } 116 | 117 | async stop = {}>( 118 | queueName: string, 119 | process: (job: Job) => Promise 120 | ) { 121 | const listener = this.listeners.getAndDelete(queueName, process); 122 | if (!listener) { 123 | return; 124 | } 125 | this.subscription(queueName).off("message", listener); 126 | } 127 | 128 | private topic(queueName: string): Topic { 129 | let topic = this.topics.get(queueName); 130 | if (topic) { 131 | return topic; 132 | } 133 | 134 | const pair = this.queueNamePubSubPair.get(queueName); 135 | if (!pair) { 136 | throw new Error(`Topic name not set for queue: ${queueName}`); 137 | } 138 | 139 | const [topicName, subscriptionName] = pair; 140 | topic = this.pubSubClient.topic(topicName); 141 | this.topics.set(queueName, topic); 142 | 143 | return topic; 144 | } 145 | 146 | private subscription(queueName: string): Subscription { 147 | let subscription = this.subscriptions.get(queueName); 148 | if (subscription) { 149 | return subscription; 150 | } 151 | 152 | const pair = this.queueNamePubSubPair.get(queueName); 153 | if (!pair) { 154 | throw new Error(`Subscription name not set for queue: ${queueName}`); 155 | } 156 | 157 | const [topicName, subscriptionName] = pair; 158 | subscription = this.topic(queueName).subscription(subscriptionName, { 159 | flowControl: { 160 | maxMessages: this.concurrency, 161 | }, 162 | }); 163 | this.subscriptions.set(queueName, subscription); 164 | 165 | return subscription; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /plugins/jobqueue-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"], 20 | "exclude": ["pub-sub-job-queue-strategy.spec.ts"] 21 | } 22 | -------------------------------------------------------------------------------- /plugins/seo-plugin/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/artcoded-net/vendure-plugins/38e022ccef8eb6ae1635eaf47db7f51821c89a17/plugins/seo-plugin/.DS_Store -------------------------------------------------------------------------------- /plugins/seo-plugin/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2021 Artcoded 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /plugins/seo-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Vendure SEO plugin 2 | 3 | A very simple plugin to add some SEO-specific fields to products/collections. 4 | -------------------------------------------------------------------------------- /plugins/seo-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@artcoded/vendure-seo-plugin", 3 | "version": "0.2.5", 4 | "author": { 5 | "name": "Artcoded", 6 | "email": "dev@artcoded.net", 7 | "url": "https://artcoded.net" 8 | }, 9 | "description": "Simple plugin for Vendure that adds SEO-specific fields to collections and products", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "README.md", 15 | "LICENSE.md" 16 | ], 17 | "dependencies": { 18 | "@vendure/core": "^1.2.0" 19 | }, 20 | "gitHead": "f27c7b6f24c010b54b5a38daedfd4f34f4bde817", 21 | "license": "MIT", 22 | "publishConfig": { 23 | "access": "public" 24 | }, 25 | "scripts": { 26 | "build": "rimraf dist && tsc", 27 | "prepare": "yarn build", 28 | "link": "yarn link" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugins/seo-plugin/src/custom-fields.ts: -------------------------------------------------------------------------------- 1 | import { LanguageCode, CustomFields } from '@vendure/core'; 2 | 3 | export const ProductSeoFields: CustomFields['Product'] = [ 4 | { 5 | name: 'seoDescription', 6 | type: 'localeString', 7 | length: 65535, 8 | label: [ 9 | {languageCode: LanguageCode.en, value: 'SEO Description'}, 10 | {languageCode: LanguageCode.it, value: 'Descrizione per SEO'} 11 | ], 12 | description: [ 13 | {languageCode: LanguageCode.en, value: 'Set this field if you want to use a specific description for search engines and social media (recommended)'}, 14 | {languageCode: LanguageCode.it, value: 'Imposta questa descrizione se vuoi una specifica descrizione per motori di ricerca e social media (raccomandato)'} 15 | ] 16 | } 17 | ]; 18 | 19 | export const CollectionSeoFields: CustomFields['Collection'] = [ 20 | { 21 | name: 'seoDescription', 22 | type: 'localeString', 23 | length: 65535, 24 | label: [ 25 | {languageCode: LanguageCode.en, value: 'SEO Description'}, 26 | {languageCode: LanguageCode.it, value: 'Descrizione per SEO'} 27 | ], 28 | description: [ 29 | {languageCode: LanguageCode.en, value: 'Set this field if you want to use a specific description for search engines and social media (recommended)'}, 30 | {languageCode: LanguageCode.it, value: 'Imposta questa descrizione se vuoi una specifica descrizione per motori di ricerca e social media (raccomandato)'} 31 | ] 32 | } 33 | ]; -------------------------------------------------------------------------------- /plugins/seo-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | export { SeoPlugin } from './plugin'; -------------------------------------------------------------------------------- /plugins/seo-plugin/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { PluginCommonModule, VendurePlugin, VendureConfig, RuntimeVendureConfig } from '@vendure/core'; 2 | import { ProductSeoFields, CollectionSeoFields } from './custom-fields'; 3 | 4 | @VendurePlugin({ 5 | imports: [PluginCommonModule], 6 | providers: [], 7 | configuration: (config: VendureConfig) => { 8 | config.customFields!.Collection!.push(...CollectionSeoFields!); 9 | config.customFields!.Product!.push(...ProductSeoFields!); 10 | return config as RuntimeVendureConfig; 11 | } 12 | }) 13 | export class SeoPlugin {} -------------------------------------------------------------------------------- /plugins/seo-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noLib": false, 5 | "skipLibCheck": true, 6 | "lib": ["es2017", "esnext.asynciterable"], 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es2017", 12 | "strict": true, 13 | "strictPropertyInitialization": false, 14 | "sourceMap": true, 15 | "newLine": "LF", 16 | "declaration": true, 17 | "outDir": "./dist" 18 | }, 19 | "include": ["src/"] 20 | } 21 | --------------------------------------------------------------------------------