├── .changeset ├── README.md └── config.json ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .flowconfig ├── .git-crypt ├── .gitattributes └── keys │ └── default │ └── 0 │ └── 38A7E5B8F71A29AE5633BE589EFF79E773E14CC9.gpg ├── .gitattributes ├── .github ├── actions │ └── ci │ │ └── action.yml ├── issue_template.md ├── pull_request_template.md └── workflows │ ├── docs.yml │ ├── quality.yml │ └── release.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .renovaterc.json ├── .vscode └── settings.json ├── .watchmanconfig ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── NPM_OWNERS ├── README.md ├── babel.config.js ├── commitlint.config.js ├── docs ├── cli │ ├── README.md │ ├── personal-data-erasure.md │ └── resource-deleter.md ├── index.md └── sdk │ ├── Glossary.md │ ├── Middlewares.md │ ├── README.md │ ├── Testing.md │ ├── api │ ├── README.md │ ├── apiRequestBuilder.md │ ├── getCredentials.md │ ├── httpUserAgent.md │ ├── sdkAuth.md │ ├── sdkClient.md │ ├── sdkMiddlewareAuth.md │ ├── sdkMiddlewareCorrelationId.md │ ├── sdkMiddlewareHttp.md │ ├── sdkMiddlewareLogger.md │ ├── sdkMiddlewareQueue.md │ ├── sdkMiddlewareUserAgent.md │ ├── syncActions.md │ ├── typescriptSdk.md │ └── typescript_tutorial.gif │ └── upgrading-from-sphere-node-sdk.md ├── integration-tests ├── CHANGELOG.md ├── cli │ └── helpers │ │ └── utils.js ├── credentials.js ├── jest.test.config.js ├── package.json ├── sdk │ ├── auth-middleware.it.js │ ├── auth.it.js │ └── channels.it.js └── ts-sdk │ └── ts-sdk.it.js ├── jest-runner-eslint.config.js ├── jest.eslint.config.js ├── jest.flow.config.js ├── jest.test.config.js ├── jest.transform.js ├── lint-staged.config.js ├── logo ├── apple-touch-icon.png └── favicon.ico ├── mise.toml ├── mkdocs.yml ├── package.json ├── packages ├── api-request-builder │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── build-query-string.js │ │ ├── classify.js │ │ ├── create-request-builder.js │ │ ├── create-service.js │ │ ├── data-erasure.js │ │ ├── default-params.js │ │ ├── default-services.js │ │ ├── features.js │ │ ├── index.js │ │ ├── order-edit-apply.js │ │ ├── query-expand.js │ │ ├── query-id.js │ │ ├── query-location.js │ │ ├── query-page.js │ │ ├── query-projection.js │ │ ├── query-search.js │ │ ├── query-suggest.js │ │ ├── query.js │ │ └── version.js │ └── test │ │ ├── __snapshots__ │ │ └── data-erasure.spec.js.snap │ │ ├── build-query-string.spec.js │ │ ├── classify.spec.js │ │ ├── create-request-builder.spec.js │ │ ├── create-service.spec.js │ │ ├── data-erasure.spec.js │ │ ├── default-params.spec.js │ │ ├── exports.spec.js │ │ ├── query-expand.spec.js │ │ ├── query-id.spec.js │ │ ├── query-location.spec.js │ │ ├── query-page.spec.js │ │ ├── query-projection.spec.js │ │ ├── query-search.spec.js │ │ ├── query-suggest.spec.js │ │ ├── query.spec.js │ │ └── version.spec.js ├── category-exporter │ └── readme.md ├── csv-parser-discount-code │ └── readme.md ├── csv-parser-orders │ └── readme.md ├── csv-parser-price │ └── readme.md ├── csv-parser-state │ └── readme.md ├── custom-objects-exporter │ └── readme.md ├── custom-objects-importer │ └── readme.md ├── customer-groups-exporter │ └── readme.md ├── discount-code-exporter │ └── readme.md ├── discount-code-generator │ ├── CHANGELOG.md │ └── readme.md ├── discount-code-importer │ └── readme.md ├── get-credentials │ ├── CHANGELOG.md │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── get-credentials.js │ │ └── index.js │ └── test │ │ └── get-credentials.spec.js ├── http-user-agent │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── create-user-agent.ts │ │ └── index.ts │ ├── test │ │ └── create-user-agent.spec.js │ ├── tsconfig.declarations.json │ └── tsconfig.json ├── inventories-exporter │ └── readme.md ├── personal-data-erasure │ ├── CHANGELOG.md │ ├── bin │ │ └── personal-data-erasure.js │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── cli.js │ │ ├── main.js │ │ └── utils │ │ │ └── silent-logger.js │ └── test │ │ ├── __snapshots__ │ │ └── main.spec.js.snap │ │ └── main.spec.js ├── price-exporter │ └── readme.md ├── product-exporter │ └── readme.md ├── product-json-to-csv │ └── readme.md ├── product-json-to-xlsx │ └── readme.md ├── resource-deleter │ ├── CHANGELOG.md │ ├── bin │ │ └── resource-deleter.js │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── cli.js │ │ ├── constants.js │ │ ├── main.js │ │ └── utils │ │ │ └── silent-logger.js │ └── test │ │ └── main.spec.js ├── sdk-auth │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── auth.js │ │ ├── constants.js │ │ ├── index.js │ │ └── tokenProvider.js │ └── test │ │ ├── anonymous-flow.spec.js │ │ ├── client-credentials-flow.spec.js │ │ ├── client-password-flow.spec.js │ │ ├── common.spec.js │ │ ├── custom-flow.spec.js │ │ ├── customer-password-flow.spec.js │ │ ├── refresh-token-flow.spec.js │ │ ├── resources │ │ ├── sample-config.js │ │ └── sample-response.json │ │ ├── token-introspection.spec.js │ │ └── token-provider.spec.js ├── sdk-client │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── allowed-methods.js │ │ ├── client.js │ │ ├── index.js │ │ └── validate.js │ └── test │ │ └── client.spec.js ├── sdk-middleware-auth │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── anonymous-session-flow.js │ │ ├── base-auth-flow.js │ │ ├── build-requests.js │ │ ├── build-token-cache-key.js │ │ ├── client-credentials-flow.js │ │ ├── existing-token.js │ │ ├── index.js │ │ ├── password-flow.js │ │ ├── refresh-token-flow.js │ │ ├── scopes.js │ │ └── utils.js │ └── test │ │ ├── anonymous-session-flow.spec.js │ │ ├── base-auth-flow.spec.js │ │ ├── build-requests.spec.js │ │ ├── client-crendentials-flow.spec.js │ │ ├── existing-token.spec.js │ │ ├── password-flow.spec.js │ │ └── refresh-token-flow.spec.js ├── sdk-middleware-correlation-id │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── correlation-id.js │ │ └── index.js │ └── test │ │ └── correlation-id.spec.js ├── sdk-middleware-http │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── errors.js │ │ ├── http.js │ │ ├── index.js │ │ └── parse-headers.js │ └── test │ │ ├── errors.spec.js │ │ ├── http.spec.js │ │ └── parse-headers.spec.js ├── sdk-middleware-logger │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.js │ │ └── logger.js │ └── test │ │ └── logger.spec.js ├── sdk-middleware-queue │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.js │ │ └── queue.js │ └── test │ │ └── queue.spec.js ├── sdk-middleware-user-agent │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ │ ├── index.ts │ │ └── user-agent.ts │ ├── test │ │ └── user-agent.spec.ts │ ├── tsconfig.declarations.json │ └── tsconfig.json ├── sdk-types │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── index.ts │ ├── package.json │ └── tsconfig.json ├── state-importer │ └── readme.md └── sync-actions │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ ├── assets-actions.js │ ├── attribute-groups-actions.js │ ├── attribute-groups.js │ ├── cart-discounts-actions.js │ ├── cart-discounts.js │ ├── categories.js │ ├── category-actions.js │ ├── channels-actions.js │ ├── channels.js │ ├── customer-actions.js │ ├── customer-group-actions.js │ ├── customer-group.js │ ├── customers.js │ ├── discount-codes-actions.js │ ├── discount-codes.js │ ├── index.js │ ├── inventories.js │ ├── inventory-actions.js │ ├── order-actions.js │ ├── orders.js │ ├── prices-actions.js │ ├── prices.js │ ├── product-actions.js │ ├── product-discounts-actions.js │ ├── product-discounts.js │ ├── product-selections-actions.js │ ├── product-selections.js │ ├── product-types-actions.js │ ├── product-types.js │ ├── products.js │ ├── projects-actions.js │ ├── projects.js │ ├── quote-requests-actions.js │ ├── quote-requests.js │ ├── quotes-actions.js │ ├── quotes.js │ ├── recurring-orders-actions.js │ ├── recurring-orders.js │ ├── shipping-methods-actions.js │ ├── shipping-methods.js │ ├── staged-quotes-actions.js │ ├── staged-quotes.js │ ├── state-actions.js │ ├── states.js │ ├── stores-actions.js │ ├── stores.js │ ├── tax-categories-actions.js │ ├── tax-categories.js │ ├── types-actions.js │ ├── types.js │ ├── utils │ │ ├── action-map-custom.js │ │ ├── clone.js │ │ ├── combine-validity-actions.js │ │ ├── common-actions.js │ │ ├── copy-empty-array-props.js │ │ ├── create-build-actions.js │ │ ├── create-build-array-actions.js │ │ ├── create-map-action-group.js │ │ ├── diffpatcher.js │ │ ├── extract-matching-pairs.js │ │ ├── find-matching-pairs.js │ │ └── remove-typename.js │ ├── zones-actions.js │ └── zones.js │ └── test │ ├── __snapshots__ │ └── product-types-sync-attribute-hints.spec.js.snap │ ├── attribute-groups-sync.spec.js │ ├── cart-discounts-sync.spec.js │ ├── category-sync.spec.js │ ├── channels-sync-.spec.js │ ├── customer-group-sync.spec.js │ ├── customer-sync.spec.js │ ├── discount-codes-sync.spec.js │ ├── inventory-sync.spec.js │ ├── order-sync.spec.js │ ├── price-sync.spec.js │ ├── product-discounts-sync.spec.js │ ├── product-selections-sync.spec.js │ ├── product-sync-base.spec.js │ ├── product-sync-images.spec.js │ ├── product-sync-prices.spec.js │ ├── product-sync-variants.spec.js │ ├── product-types-sync-attribute-hints.spec.js │ ├── product-types-sync-base.spec.js │ ├── projects-sync.spec.js │ ├── quote-requests-sync.spec.js │ ├── quotes-sync.spec.js │ ├── recurring-orders-sync.spec.js │ ├── shipping-methods.spec.js │ ├── staged-quotes-sync.spec.js │ ├── states-sync.spec.js │ ├── stores-sync.spec.js │ ├── tax-categories-sync.spec.js │ ├── types-sync-base.spec.js │ ├── types-sync-enums.spec.js │ ├── types-sync-fields.spec.js │ ├── utils │ ├── action-map-custom.spec.js │ ├── combine-validity-actions.spec.js │ ├── common-actions.spec.js │ ├── copy-empty-array-props.spec.js │ ├── create-build-array-actions.spec.js │ ├── create-map-action-group.spec.js │ ├── extract-matching-pairs.spec.js │ └── find-matching-pairs.spec.js │ └── zones.spec.js ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── install-npm-packages-for-integration-tests ├── npm-owners-grant ├── npm-owners-list ├── npm-owners-revoke ├── package-readme-entry.sh ├── postinstall.sh └── test-package ├── tsconfig.json └── types ├── categoryExporter.js ├── customObjects.js ├── customerGroups.js ├── discountCodes.js ├── highland.js ├── inventory.js ├── personalDataErasure.js ├── price.js ├── product.js ├── resourceDeleter.js ├── sdk.js └── state.js /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.0/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { 6 | "repo": "commercetools/nodejs" 7 | } 8 | ], 9 | "commit": false, 10 | "access": "restricted", 11 | "baseBranch": "master" 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://github.com/editorconfig/editorconfig 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | # Set default charset to utf-8 8 | charset = utf-8 9 | # Set default indentation to spaces 10 | indent_style = space 11 | # Linux-style newlines with a newline ending every file 12 | end_of_line = lf 13 | insert_final_newline = true 14 | # Remove whitespace characters preceding newline characters 15 | trim_trailing_whitespace = true 16 | 17 | # Two space indentation for JavaScript files 18 | [*.{js,json}] 19 | indent_size = 2 20 | 21 | # Disable trimming trailing whitespaces so that double space newlines work 22 | [*.md] 23 | trim_trailing_whitespace = false 24 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | credentials.js 2 | coverage/* 3 | **/coverage/* 4 | dist/* 5 | **/dist/* 6 | lib/* 7 | **/lib/* 8 | target/* 9 | **/target/* 10 | scripts/* 11 | **/scripts/* 12 | node_modules/* 13 | **/node_modules/* 14 | **/typescript-sdk/* 15 | _book 16 | .changelog 17 | .yarn -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@babel/eslint-parser', 3 | parserOptions: { 4 | ecmaVersion: 8, 5 | sourceType: 'module', 6 | }, 7 | extends: ['airbnb-base', 'plugin:jest/recommended', 'prettier'], 8 | plugins: ['flowtype', 'jest', 'prettier'], 9 | env: { 10 | es6: true, 11 | browser: true, 12 | jest: true, 13 | node: true, 14 | }, 15 | rules: { 16 | 'flowtype/define-flow-type': 1, 17 | 'flowtype/require-parameter-type': 1, 18 | 'flowtype/require-return-type': [ 19 | 1, 20 | 'always', 21 | { annotateUndefined: 'never' }, 22 | ], 23 | 'flowtype/semi': 0, 24 | 'flowtype/space-after-type-colon': [1, 'always'], 25 | 'flowtype/space-before-type-colon': [1, 'never'], 26 | 'flowtype/type-id-match': 0, 27 | 'flowtype/use-flow-type': 1, 28 | 'flowtype/valid-syntax': 1, 29 | 'import/no-extraneous-dependencies': [ 30 | 'error', 31 | { 32 | devDependencies: ['**/test/**/*.js'], 33 | }, 34 | ], 35 | 'jest/no-disabled-tests': 'warn', 36 | 'jest/no-focused-tests': 'error', 37 | 'jest/no-identical-title': 'error', 38 | 'jest/valid-expect': 'error', 39 | 'jest/no-try-expect': 0, 40 | 'no-underscore-dangle': 0, 41 | 'prefer-destructuring': 0, 42 | 'lines-between-class-members': 0, 43 | 'max-classes-per-file': 0, 44 | 'import/extensions': [ 45 | 'error', 46 | 'ignorePackages', 47 | { 48 | js: 'never', 49 | mjs: 'never', 50 | ts: 'never', 51 | }, 52 | ], 53 | }, 54 | settings: { 55 | flowtype: { 56 | onlyFilesWithFlowAnnotation: true, 57 | }, 58 | }, 59 | } 60 | -------------------------------------------------------------------------------- /.git-crypt/.gitattributes: -------------------------------------------------------------------------------- 1 | # Do not edit this file. To specify the files to encrypt, create your own 2 | # .gitattributes file in the directory where your files are. 3 | * !filter !diff 4 | -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/38A7E5B8F71A29AE5633BE589EFF79E773E14CC9.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commercetools/nodejs/ae5f22cb3fb9a745e130dec19ad2c3757e4295f6/.git-crypt/keys/default/0/38A7E5B8F71A29AE5633BE589EFF79E773E14CC9.gpg -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | integration-tests/credentials.js filter=git-crypt diff=git-crypt 2 | -------------------------------------------------------------------------------- /.github/actions/ci/action.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | description: Shared action to install dependencies 4 | 5 | runs: 6 | using: composite 7 | 8 | steps: 9 | - name: Install pnpm 10 | uses: pnpm/action-setup@v4.1.0 11 | with: 12 | run_install: false 13 | 14 | - name: Setup Node.js 15 | uses: actions/setup-node@v4 16 | with: 17 | node-version-file: ".nvmrc" 18 | cache: "pnpm" 19 | 20 | # Whenever on a changeset versioning PR 21 | # Then installing con not fail with lockfile changes 22 | # Because the package.json for integration test changes. 23 | 24 | - name: Install 25 | run: pnpm install --no-frozen-lockfile 26 | shell: bash 27 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Support reference number 2 | 3 | 4 | 5 | ### Description 6 | 7 | 8 | 9 | ```js 10 | var your => (code) => here; 11 | ``` 12 | 13 | ### Expected Behavior 14 | 15 | 16 | 17 | ### Current Behavior 18 | 19 | 20 | 21 | 22 | 23 | ### Context 24 | 25 | 26 | 27 | ### Possible Solution 28 | 29 | 30 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | #### Summary 2 | 3 | 4 | 5 | #### Description 6 | 7 | 8 | 9 | #### Todo 10 | 11 | - Tests 12 | - [ ] Unit 13 | - [ ] Integration 14 | - [ ] Acceptance 15 | - [ ] Documentation 16 | - [ ] `Type` label for the PR 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | on: 3 | workflow_dispatch: 4 | 5 | permissions: 6 | contents: write 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | # Get GitHub token via the CT Changesets App 12 | - name: Generate GitHub token (via CT Changesets App) 13 | id: generate_github_token 14 | uses: tibdex/github-app-token@v2.1.0 15 | with: 16 | app_id: ${{ secrets.CT_CHANGESETS_APP_ID }} 17 | private_key: ${{ secrets.CT_CHANGESETS_APP_PEM }} 18 | 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | # Pass a personal access token (using our CT Changesets App) to be able to trigger other workflows 24 | # https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token 25 | # https://github.community/t/action-does-not-trigger-another-on-push-tag-action/17148/8 26 | token: ${{ steps.generate_github_token.outputs.token }} 27 | 28 | - uses: actions/setup-python@v5 29 | with: 30 | python-version: 3.x 31 | - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV 32 | - uses: actions/cache@v4 33 | with: 34 | key: mkdocs-material-${{ env.cache_id }} 35 | path: .cache 36 | restore-keys: | 37 | mkdocs-material- 38 | - run: pip install mkdocs-material 39 | - run: mkdocs gh-deploy -d temp 40 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | # Get GitHub token via the CT Changesets App 14 | - name: Generate GitHub token (via CT Changesets App) 15 | id: generate_github_token 16 | uses: tibdex/github-app-token@v2.1.0 17 | with: 18 | app_id: ${{ secrets.CT_CHANGESETS_APP_ID }} 19 | private_key: ${{ secrets.CT_CHANGESETS_APP_PEM }} 20 | 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | with: 24 | # Pass a personal access token (using our CT Changesets App) to be able to trigger other workflows 25 | # https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token 26 | # https://github.community/t/action-does-not-trigger-another-on-push-tag-action/17148/8 27 | token: ${{ steps.generate_github_token.outputs.token }} 28 | 29 | - name: Setup 30 | uses: ./.github/actions/ci 31 | 32 | - name: Creating .npmrc 33 | run: | 34 | cat << EOF > "$HOME/.npmrc" 35 | email=npmjs@commercetools.com 36 | //registry.npmjs.org/:_authToken=$NPM_TOKEN 37 | EOF 38 | env: 39 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 40 | 41 | - name: Building packages 42 | run: pnpm build 43 | 44 | - name: Create Release Pull Request or Publish to npm 45 | id: changesets 46 | uses: changesets/action@master 47 | with: 48 | publish: pnpm changeset publish 49 | version: pnpm changeset:version-and-format 50 | commit: 'ci(changesets): version packages' 51 | env: 52 | GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Env files 9 | *.env 10 | # Dependencies 11 | node_modules 12 | .npm 13 | .released-packages 14 | 15 | # Integration tests dependencies cache 16 | *.tgz 17 | package-lock.json 18 | 19 | # Build artifacts 20 | _book 21 | .changelog 22 | dist 23 | lib 24 | coverage 25 | 26 | # OS clutter 27 | .DS_Store 28 | 29 | # IDE tools 30 | .idea 31 | *.swp 32 | 33 | mise.toml 34 | 35 | # Yarn 36 | .yarn/* 37 | !.yarn/patches 38 | !.yarn/plugins 39 | !.yarn/releases 40 | !.yarn/sdks 41 | !.yarn/versions 42 | 43 | # mise-en-place 44 | mise.toml 45 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | pnpm commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm typecheck:ts 2 | 3 | pnpm lint-staged 4 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | credentials.js 2 | package.json 3 | **/dist/ 4 | **/lib/ 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "parser": "babel-flow", 5 | "overrides": [ 6 | { 7 | "files": "*.ts", 8 | "options": { 9 | "parser": "typescript" 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.renovaterc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | ":pinOnlyDevDependencies", 5 | ":enableVulnerabilityAlerts", 6 | ":automergeMinor", 7 | "schedule:weekly" 8 | ], 9 | "separateMajorMinor": true, 10 | "packageRules": [ 11 | { 12 | "packagePatterns": [ 13 | "*" 14 | ], 15 | "updateTypes": ["minor", "patch"], 16 | "groupName": "all dependencies", 17 | "groupSlug": "all" 18 | }, 19 | { 20 | "matchPackageNames": ["flow-bin"], 21 | "allowedVersions": "0.141.0" 22 | }, 23 | { 24 | "matchPackageNames": ["jsondiffpatch"], 25 | "allowedVersions": "<= 0.5.0" 26 | } 27 | ], 28 | "lockFileMaintenance": { 29 | "enabled": true 30 | }, 31 | "labels": [ 32 | "Type: Maintenance" 33 | ], 34 | "ignoreDeps": [] 35 | } 36 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.validate": [ 3 | "javascript", 4 | "typescript" 5 | ], 6 | "flow.useNPMPackagedFlow": true, 7 | "javascript.validate.enable": false, 8 | "typescript.tsdk": "node_modules/typescript/lib" 9 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 commercetools GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NPM_OWNERS: -------------------------------------------------------------------------------- 1 | # This is just a reference list to see who is owner of the npm packages. 2 | # The main user is the "Automation Bot" https://www.npmjs.com/~commercetools. 3 | # To easily grant access to a user, run the `./scripts/npm-owners-grant`. 4 | # To easily revoke access to a user, run the `./scripts/npm-owners-revoke`. 5 | # To easily list owners, run the `./scripts/npm-owners-list`. 6 | 7 | emmenko 8 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const getPresets = () => { 2 | switch (process.env.NODE_ENV) { 3 | case 'development': 4 | return { 5 | targets: { node: 'current' }, 6 | modules: 'commonjs', 7 | } 8 | case 'production': 9 | return { 10 | targets: { 11 | browsers: ['last 2 versions'], 12 | node: '10', 13 | }, 14 | modules: false, 15 | } 16 | case 'cli': 17 | return { 18 | targets: { node: '10' }, 19 | modules: 'commonjs', 20 | } 21 | default: 22 | return {} 23 | } 24 | } 25 | 26 | module.exports = { 27 | presets: [['@babel/preset-env', getPresets()], '@babel/preset-flow'], 28 | plugins: [ 29 | '@babel/plugin-proposal-export-default-from', 30 | '@babel/plugin-proposal-export-namespace-from', 31 | '@babel/plugin-proposal-optional-chaining', 32 | '@babel/plugin-syntax-optional-chaining', 33 | ['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }], 34 | '@babel/plugin-proposal-nullish-coalescing-operator', 35 | ], 36 | overrides: [ 37 | { 38 | test: ['./src/**/*.ts'], 39 | presets: [ 40 | '@babel/preset-typescript', 41 | ['@babel/preset-env', getPresets()], 42 | ], 43 | }, 44 | ], 45 | } 46 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | extends: ['@commitlint/config-conventional'], 4 | parserPreset: { 5 | parserOpts: { 6 | // Allow to write a "scope" with slashes 7 | // E.g. `refactor(app/my-component): something` 8 | headerPattern: /^(\w*)(?:\(([\w\$\.\/\-\* ]*)\))?\: (.*)$/, 9 | }, 10 | }, 11 | rules: { 12 | 'header-max-length': [0, 'always', 100], 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /docs/cli/README.md: -------------------------------------------------------------------------------- 1 | # CLI 2 | 3 | This section contains all information about the command line tools built by the commercetools nodeJS team. 4 | 5 | Our CLI tools perform various functions from importing and exporting to syncing data between various projects in the commercetools platform. 6 | 7 | ### modules 8 | 9 | - [Personal Data Erasure](/cli/personal-data-erasure.md) 10 | - [Resource Deleter](/cli/resource-deleter.md) 11 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | commercetools logo 4 | 5 | Node.js commercetools ecosystem. 6 |

7 | 8 |

9 | 10 | GitHub Actions Status 11 | 12 | 13 | Codecov 14 | 15 |

16 | 17 | The **commercetools nodejs** repo is managed as a [monorepo](https://github.com/lerna/lerna) and contains different npm packages. 18 | -------------------------------------------------------------------------------- /docs/sdk/api/sdkMiddlewareCorrelationId.md: -------------------------------------------------------------------------------- 1 | # `sdk-middleware-correlation-id` 2 | 3 | Middleware add a correlation id to [requests](/sdk/Glossary#clientrequest). 4 | 5 | ## ⚠️ In Maintenance Mode ⚠️ 6 | 7 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 8 | 9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 | 11 | ## Install 12 | 13 | #### Node.js 14 | 15 | ```bash 16 | npm install --save @commercetools/sdk-middleware-correlation-id 17 | ``` 18 | 19 | #### Browser 20 | 21 | ```html 22 | 23 | 26 | ``` 27 | 28 | ## `createCorrelationIdMiddleware(options)` 29 | 30 | Creates a [middleware](/sdk/Glossary#middleware) to add a correlation id to executed requests. 31 | 32 | #### Usage example 33 | 34 | ```js 35 | import { createClient } from '@commercetools/sdk-client' 36 | import { createCorrelationIdMiddleware } from '@commercetools/sdk-middleware-correlation-id' 37 | import { createAuthMiddleware } from '@commercetools/sdk-middleware-auth' 38 | import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' 39 | 40 | const client = createClient({ 41 | middlewares: [ 42 | createAuthMiddleware({...}), 43 | createCorrelationIdMiddleware({ 44 | generate: () => `prefix/${uuid()}/postifx` 45 | }), 46 | createHttpMiddleware({...}), 47 | ], 48 | }) 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/sdk/api/sdkMiddlewareLogger.md: -------------------------------------------------------------------------------- 1 | # `sdk-middleware-logger` 2 | 3 | Middleware to log incoming [request](/sdk/Glossary#clientrequest) and [response](/sdk/Glossary#clientrequest) objects. 4 | 5 | ## ⚠️ In Maintenance Mode ⚠️ 6 | 7 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 8 | 9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 | 11 | ## Install 12 | 13 | #### Node.js 14 | 15 | ```bash 16 | npm install --save @commercetools/sdk-middleware-logger 17 | ``` 18 | 19 | #### Browser 20 | 21 | ```html 22 | 23 | 26 | ``` 27 | 28 | ## `createLoggerMiddleware(options)` 29 | 30 | Creates a [middleware](/sdk/Glossary#middleware) to log request and response objects being executed. 31 | 32 | #### Usage example 33 | 34 | ```js 35 | import { createClient } from '@commercetools/sdk-client' 36 | import { createLoggerMiddleware } from '@commercetools/sdk-middleware-logger' 37 | import { createAuthMiddleware } from '@commercetools/sdk-middleware-auth' 38 | import { createHttpMiddleware } from '@commercetools/sdk-middleware-http' 39 | 40 | const client = createClient({ 41 | middlewares: [ 42 | createAuthMiddleware({...}), 43 | // Log the request / response at this point in the middleware chain, before it gets to the http-middleware 44 | createLoggerMiddleware(), 45 | createHttpMiddleware({...}), 46 | // Log the request / response after it's being handled by the http-middleware 47 | createLoggerMiddleware(), 48 | ], 49 | }) 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/sdk/api/sdkMiddlewareQueue.md: -------------------------------------------------------------------------------- 1 | # `sdk-middleware-queue` 2 | 3 | Middleware to throttle concurrent [request](/sdk/Glossary#clientrequest) to a certain limit. Useful to reduce concurrent HTTP requests. 4 | 5 | ## ⚠️ In Maintenance Mode ⚠️ 6 | 7 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 8 | 9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 | 11 | ## Install 12 | 13 | #### Node.js 14 | 15 | ```bash 16 | npm install --save @commercetools/sdk-middleware-queue 17 | ``` 18 | 19 | #### Browser 20 | 21 | ```html 22 | 23 | 26 | ``` 27 | 28 | ## `createQueueMiddleware(options)` 29 | 30 | Creates a [middleware](/sdk/Glossary#middleware) to handle concurrent requests. 31 | 32 | #### Named arguments (options) 33 | 34 | 1. `concurrency` _(Number)_: the max number of concurrent requests (default `20`) 35 | 36 | #### Usage example 37 | 38 | ```js 39 | import { createClient } from '@commercetools/sdk-client' 40 | import { createQueueMiddleware } from '@commercetools/sdk-middleware-queue' 41 | 42 | const client = createClient({ 43 | middlewares: [ 44 | createQueueMiddleware({ 45 | concurrency: 5, 46 | }), 47 | ], 48 | }) 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/sdk/api/typescript_tutorial.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commercetools/nodejs/ae5f22cb3fb9a745e130dec19ad2c3757e4295f6/docs/sdk/api/typescript_tutorial.gif -------------------------------------------------------------------------------- /integration-tests/credentials.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commercetools/nodejs/ae5f22cb3fb9a745e130dec19ad2c3757e4295f6/integration-tests/credentials.js -------------------------------------------------------------------------------- /integration-tests/jest.test.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testRegex: '(.*)\\.it\\.js$', 3 | } 4 | -------------------------------------------------------------------------------- /integration-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "@commercetools/integration-tests", 4 | "version": "0.1.25", 5 | "dependencies": { 6 | "@commercetools/api-request-builder": "^7.0.0", 7 | "@commercetools/get-credentials": "^5.0.0", 8 | "@commercetools/http-user-agent": "4.0.1", 9 | "@commercetools/personal-data-erasure": "^5.0.0", 10 | "@commercetools/platform-sdk": "^2.2.0", 11 | "@commercetools/resource-deleter": "^4.0.0", 12 | "@commercetools/sdk-auth": "^5.0.0", 13 | "@commercetools/sdk-client": "^4.0.0", 14 | "@commercetools/sdk-middleware-auth": "^8.0.0", 15 | "@commercetools/sdk-middleware-http": "^8.0.0", 16 | "@commercetools/sdk-middleware-logger": "4.0.1", 17 | "@commercetools/sdk-middleware-queue": "^4.0.0", 18 | "@commercetools/sdk-middleware-user-agent": "^4.0.0", 19 | "@commercetools/sync-actions": "^7.1.2", 20 | "lodash.omit": "^4.5.0", 21 | "node-fetch": "^2.6.7" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /jest-runner-eslint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | cliOptions: { 3 | format: 'node_modules/eslint-formatter-pretty', 4 | fix: true, 5 | rules: { 6 | 'import/no-unresolved': 2, 7 | 'prettier/prettier': [ 8 | 'error', 9 | { trailingComma: 'es5', singleQuote: true }, 10 | ], 11 | }, 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /jest.eslint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | runner: 'jest-runner-eslint', 3 | displayName: 'eslint', 4 | modulePathIgnorePatterns: ['dist', 'lib'], 5 | testMatch: ['/**/*.js', '/**/*.ts'], 6 | } 7 | -------------------------------------------------------------------------------- /jest.flow.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | runner: 'jest-runner-flowtype', 3 | displayName: 'flow', 4 | testMatch: [ 5 | '/packages/**/*.js', 6 | '/integration-tests/**/*.js', 7 | ], 8 | } 9 | -------------------------------------------------------------------------------- /jest.test.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'test', 3 | testEnvironment: 'node', 4 | globals: { 5 | 'process.env': { 6 | NODE_ENV: 'test', 7 | }, 8 | // Without this option, somehow CI fails to run the tests with the following error: 9 | // TypeError: Unable to require `.d.ts` file. 10 | // This is usually the result of a faulty configuration or import. Make sure there is a `.js`, `.json` or another executable extension available alongside `core.ts`. 11 | // Fix is based on this comment: 12 | // - https://github.com/kulshekhar/ts-jest/issues/805#issuecomment-456055213 13 | // - https://github.com/kulshekhar/ts-jest/blob/master/docs/user/config/isolatedModules.md 14 | 'ts-jest': { 15 | isolatedModules: true, 16 | }, 17 | }, 18 | transform: { 19 | '^.+\\.js$': '/jest.transform.js', 20 | '^.+\\.ts?$': 'ts-jest', 21 | }, 22 | testRegex: '\\.spec\\.(js|ts)$', 23 | moduleFileExtensions: ['ts', 'js'], 24 | testPathIgnorePatterns: [ 25 | '/node_modules/', 26 | '/integration-tests/', 27 | '/packages/.*/node_modules', 28 | '/packages/.*/dist', 29 | '/packages/.*/lib', 30 | ], 31 | transformIgnorePatterns: [ 32 | '/node_modules/.pnpm/(?!(jsondiffpatch|@jsondiffpatch)@)', 33 | ], 34 | } 35 | -------------------------------------------------------------------------------- /jest.transform.js: -------------------------------------------------------------------------------- 1 | const babelConfig = require('./babel.config') 2 | 3 | // eslint-disable-next-line import/no-extraneous-dependencies 4 | module.exports = require('babel-jest').createTransformer(babelConfig) 5 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.md': ['pnpm format:md'], 3 | 'packages/**/*.js': [ 4 | 'prettier --write', 5 | // NOTE: apparently if you pass some argument that is not a flag AFTER the `reporters` 6 | // flag, jest does not seem correctly parse the arguments. 7 | // 8 | // No tests found related to files changed since last commit. 9 | // Run Jest without `-o` or with `--all` to run all tests. 10 | // Error: An error occurred while adding the reporter at path "/path/to/file".Reporter is not a constructor 11 | // 12 | // For that reason, we move the `--onlyChanged` flag next to it. 13 | 'pnpm lint:js -- --reporters=jest-silent-reporter --onlyChanged', 14 | 'flow focus-check', 15 | ], 16 | } 17 | -------------------------------------------------------------------------------- /logo/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commercetools/nodejs/ae5f22cb3fb9a745e130dec19ad2c3757e4295f6/logo/apple-touch-icon.png -------------------------------------------------------------------------------- /logo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commercetools/nodejs/ae5f22cb3fb9a745e130dec19ad2c3757e4295f6/logo/favicon.ico -------------------------------------------------------------------------------- /mise.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | node = "22" 3 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: commercetools NodeJS 2 | theme: 3 | name: material 4 | features: 5 | - navigation.expand 6 | -------------------------------------------------------------------------------- /packages/api-request-builder/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/api-request-builder 2 | 3 | ## 7.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 7.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 6.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/api-request-builder/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-api-request-builder 2 | 3 | Helper functions collection to easily construct API requests URI in a declarative way, for usage with `@commercetools/sdk-client`. 4 | 5 | https://commercetools.github.io/nodejs/sdk/api/apiRequestBuilder 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install --save @commercetools/api-request-builder 11 | ``` 12 | -------------------------------------------------------------------------------- /packages/api-request-builder/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/api-request-builder", 9 | "version": "7.0.1", 10 | "description": "Helper functions to construct API requests URI for the commercetools platform in a declarative way.", 11 | "keywords": [ 12 | "commercetools", 13 | "api", 14 | "uri", 15 | "builder", 16 | "request" 17 | ], 18 | "homepage": "https://commercetools.github.io/nodejs/", 19 | "bugs": "https://github.com/commercetools/nodejs/issues", 20 | "license": "MIT", 21 | "author": "Nicola Molinari (https://github.com/emmenko)", 22 | "main": "dist/commercetools-api-request-builder.cjs.js", 23 | "module": "dist/commercetools-api-request-builder.esm.js", 24 | "umd:main": "dist/commercetools-api-request-builder.umd.min.js", 25 | "preconstruct": { 26 | "entrypoints": [ 27 | "./index.js" 28 | ], 29 | "umdName": "commercetoolsApiRequestBuilder" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/commercetools/nodejs.git" 34 | }, 35 | "files": [ 36 | "dist" 37 | ], 38 | "scripts": { 39 | "build": "exit 0;" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/classify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an object, return a clone with non-function properties defined as 3 | * non-enumerable, unwritable, and unconfigurable. 4 | * 5 | * @param {Object} 6 | * @return {Object} 7 | */ 8 | export default function classify(object, forceEnumerable = false) { 9 | const clone = {} 10 | 11 | Object.keys(object).forEach((key) => { 12 | Object.defineProperty(clone, key, { 13 | value: object[key], 14 | enumerable: forceEnumerable ? true : typeof object[key] === 'function', 15 | }) 16 | }) 17 | 18 | return clone 19 | } 20 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/create-request-builder.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ApiRequestBuilder } from 'types/sdk' 3 | 4 | import services from './default-services' 5 | import createService from './create-service' 6 | 7 | // pass an options argument of type object containing 8 | // the `projectkey` (string) and `customServices` (object) 9 | // The projectKey property is required 10 | // A sample options object would be: 11 | // 12 | // options: { 13 | // projectKey: 'myProject', 14 | // customServices: { 15 | // foo: { 16 | // type: 'foo', 17 | // endpoint: '/foo', 18 | // features: [ 19 | // features.query, 20 | // ], 21 | // } 22 | // } 23 | // } 24 | export default function createRequestBuilder( 25 | options: Object = {} 26 | ): ApiRequestBuilder { 27 | const allServices = { ...services, ...options.customServices } 28 | 29 | return Object.keys(allServices).reduce( 30 | (acc: {}, key: string) => ({ 31 | ...acc, 32 | [key]: createService(allServices[key], options.projectKey), 33 | }), 34 | {} 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/data-erasure.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /** 3 | * Set the `dataErasure` option to the internal state of the service instance 4 | * in order to generate a DELETE uri that guarantees that all personal data related to 5 | * the particular object, including invisible data, is erased, in compliance with the GDPR. 6 | * 7 | * Users are, however, responsible for identifying and deleting all objects that belong to a customer, and deleting them. 8 | * 9 | * More info here: https://docs.commercetools.com/release-notes#releases-2018-05-24-data-erasure 10 | * 11 | * @return {Object} The instance of the service, can be chained. 12 | */ 13 | 14 | export default function withFullDataErasure(): Object { 15 | this.params.dataErasure = 'dataErasure=true' 16 | return this 17 | } 18 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/features.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NOTE: 3 | * These are so called implicit features 4 | * which work on endpoints automatically as they only 5 | * differ in the http method and request body 6 | * and do not need any further processing. 7 | * We specify these on endpoints for documentation purposes 8 | * only. 9 | */ 10 | export const create = 'create' 11 | export const update = 'update' 12 | // `delete` is a reserved word in JavaScript 13 | export const del = 'delete' 14 | 15 | /** 16 | * NOTE: 17 | * These are so called explicit features 18 | * which only work on a subset of endpoints and perform 19 | * additional manipulation on the request. 20 | */ 21 | export const query = 'query' 22 | export const queryOne = 'queryOne' 23 | export const queryExpand = 'queryExpand' 24 | export const queryLocation = 'queryLocation' 25 | export const search = 'search' 26 | export const projection = 'projection' 27 | export const suggest = 'suggest' 28 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createRequestBuilder } from './create-request-builder' 3 | export * as features from './features' 4 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/order-edit-apply.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /** 3 | * `Apply an OrderEdit` to an `order` by providing a correct Order Edit ID 4 | * 5 | * More info here: https://docs.commercetools.com/http-api-projects-order-edits#apply-an-orderedit 6 | * 7 | * @param {string} orderEditId - The ID of the Order Edit. 8 | * 9 | * @return {Object} The instance of the service, can be chained. 10 | */ 11 | 12 | export default function applyOrderEditTo(orderEditId: string): Object { 13 | if (typeof orderEditId !== 'string') 14 | throw new Error('A resource orderEditId is missing or invalid') 15 | this.params.applyOrderEditTo = orderEditId 16 | return this 17 | } 18 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/query-expand.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /** 3 | * Set the 4 | * [ExpansionPath](http://dev.sphere.io/http-api.html#reference-expansion) 5 | * used for expanding a 6 | * [Reference](http://dev.sphere.io/http-api-types.html#reference) 7 | * of a resource. 8 | * 9 | * @param {string} value - The expand path expression. 10 | * @throws If `value` is missing. 11 | * @return {Object} The instance of the service, can be chained. 12 | */ 13 | // eslint-disable-next-line import/prefer-default-export 14 | export function expand(value: string): Object { 15 | if (!value) throw new Error('Required argument for `expand` is missing') 16 | 17 | const encodedPath = encodeURIComponent(value) 18 | // Note: this goes to base `params`, not `params.query` 19 | // to be compatible with search. 20 | this.params.expand.push(encodedPath) 21 | return this 22 | } 23 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/query-suggest.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /** 3 | * Define a Suggestion used for matching tokens for product projections, 4 | * via a suggest tokenizer. 5 | * 6 | * The suggestions can be used to implement a basic auto-complete functionality. 7 | * The source of data for suggestions is the searchKeyword field in a product. 8 | * 9 | * @param {string} value - A non-URI encoded string representing a 10 | * text to search for. 11 | * @param {string} lang - An ISO language tag, used for search 12 | * the given text in localized content. 13 | * @throws If `value` or `lang` is missing. 14 | * @return {Object} The instance of the service, can be chained. 15 | */ 16 | // eslint-disable-next-line import/prefer-default-export 17 | export function searchKeywords(value: string, lang: string): Object { 18 | if (!value || !lang) 19 | throw new Error('Required arguments for `searchKeywords` are missing') 20 | 21 | this.params.searchKeywords.push({ lang, value: encodeURIComponent(value) }) 22 | return this 23 | } 24 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/query.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Set the given `predicate` to the internal state of the service instance. 3 | * 4 | * @param {string} predicate - A non-URI encoded string representing a 5 | * [Predicate]{@link http://dev.sphere.io/http-api.html#predicates} 6 | * @throws If `predicate` is missing. 7 | * @return {Object} The instance of the service, can be chained. 8 | */ 9 | export function where(predicate: string): Object { 10 | if (!predicate) throw new Error('Required argument for `where` is missing') 11 | 12 | const encodedPredicate = encodeURIComponent(predicate) 13 | this.params.query.where.push(encodedPredicate) 14 | return this 15 | } 16 | 17 | /** 18 | * Set the logical operator to combine multiple query predicates 19 | * {@link module:commons/query.where} 20 | * 21 | * @param {string} operator - A logical operator `and`, `or` 22 | * @throws If `operator` is missing or has a wrong value. 23 | * @return {Object} The instance of the service, can be chained. 24 | */ 25 | export function whereOperator(operator: 'and' | 'or'): Object { 26 | if (!operator) 27 | throw new Error('Required argument for `whereOperator` is missing') 28 | if (!(operator === 'and' || operator === 'or')) 29 | throw new Error( 30 | 'Required argument for `whereOperator` is invalid, ' + 31 | 'allowed values are (`and`, `or`)' 32 | ) 33 | 34 | this.params.query.operator = operator 35 | return this 36 | } 37 | -------------------------------------------------------------------------------- /packages/api-request-builder/src/version.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /** 3 | * Set the `version` number to the internal state of the service instance 4 | * in order to generate a uri with the resource version (for example; to 5 | * perform a `DELETE` request) 6 | * 7 | * @param {number} version - The version of the resource 8 | * @throws if `version` is missing or not a number. 9 | * @return {Object} The instance of the service, can be chained. 10 | */ 11 | 12 | export default function withVersion(version: number): Object { 13 | if (typeof version !== 'number') 14 | throw new Error('A resource version is missing or invalid') 15 | this.params.version = version 16 | return this 17 | } 18 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/__snapshots__/data-erasure.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`withFullDataErasure should set the dataErasure option to true 1`] = `"dataErasure=true"`; 4 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/classify.spec.js: -------------------------------------------------------------------------------- 1 | import classify from '../src/classify' 2 | 3 | describe('classify', () => { 4 | test('should freeze non-function property and make it non-enumerable', () => { 5 | const composed = classify({ 6 | foo: 'bar', 7 | bar: { a: 1, b: 2 }, 8 | getFoo() { 9 | return this.foo 10 | }, 11 | getBar() { 12 | return this.bar 13 | }, 14 | }) 15 | Object.keys(composed).forEach((key) => { 16 | expect(typeof composed[key]).toBe('function') 17 | }) 18 | expect(Object.keys(composed)).toHaveLength(2) 19 | expect(Object.getOwnPropertyNames(composed)).toHaveLength(4) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/data-erasure.spec.js: -------------------------------------------------------------------------------- 1 | import withFullDataErasure from '../src/data-erasure' 2 | 3 | describe('withFullDataErasure', () => { 4 | let service 5 | 6 | beforeEach(() => { 7 | service = { params: {}, withFullDataErasure } 8 | }) 9 | 10 | test('should set the dataErasure option to true', () => { 11 | service.withFullDataErasure() 12 | expect(service.params.dataErasure).toMatchSnapshot() 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/exports.spec.js: -------------------------------------------------------------------------------- 1 | import { createRequestBuilder } from '../src' 2 | import * as features from '../src/features' 3 | 4 | describe('exports', () => { 5 | test('default', () => { 6 | expect(typeof createRequestBuilder).toBe('function') 7 | }) 8 | 9 | test('features', () => { 10 | expect(Object.keys(features).sort()).toEqual( 11 | [ 12 | 'create', 13 | 'update', 14 | 'del', 15 | 'query', 16 | 'queryOne', 17 | 'queryExpand', 18 | 'queryLocation', 19 | 'search', 20 | 'projection', 21 | 'suggest', 22 | ].sort() 23 | ) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/query-expand.spec.js: -------------------------------------------------------------------------------- 1 | import * as queryExpand from '../src/query-expand' 2 | 3 | describe('queryExpand', () => { 4 | let service 5 | 6 | beforeEach(() => { 7 | service = { params: { expand: [] }, ...queryExpand } 8 | }) 9 | 10 | test('should set the expand param', () => { 11 | service.expand('productType') 12 | expect(service.params.expand).toEqual([encodeURIComponent('productType')]) 13 | }) 14 | 15 | test('should throw if expansionPath is missing', () => { 16 | expect(() => service.expand()).toThrow( 17 | /Required argument for `expand` is missing/ 18 | ) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/query-projection.spec.js: -------------------------------------------------------------------------------- 1 | import * as queryProjection from '../src/query-projection' 2 | 3 | describe('queryProjection', () => { 4 | let service 5 | 6 | beforeEach(() => { 7 | service = { params: {}, ...queryProjection } 8 | }) 9 | 10 | test('should set the staged param', () => { 11 | service.staged() 12 | expect(service.params.staged).toBeFalsy() 13 | 14 | service.staged(false) 15 | expect(service.params.staged).toBeFalsy() 16 | 17 | service.staged(true) 18 | expect(service.params.staged).toBeTruthy() 19 | }) 20 | 21 | test('should set the priceCurrency param', () => { 22 | service.priceCurrency('EUR') 23 | expect(service.params.priceCurrency).toBe('EUR') 24 | }) 25 | 26 | test('should set the priceCountry param', () => { 27 | service.priceCountry('DE') 28 | expect(service.params.priceCountry).toBe('DE') 29 | }) 30 | 31 | test('should set the priceCustomerGroup param', () => { 32 | service.priceCustomerGroup('1234567890oiuytrewq') 33 | expect(service.params.priceCustomerGroup).toBe('1234567890oiuytrewq') 34 | }) 35 | 36 | test('should set the priceChannel param', () => { 37 | service.priceChannel('1234567890oiuytrewq') 38 | expect(service.params.priceChannel).toBe('1234567890oiuytrewq') 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/query-suggest.spec.js: -------------------------------------------------------------------------------- 1 | import * as querySuggest from '../src/query-suggest' 2 | 3 | describe('querySuggest', () => { 4 | let service 5 | 6 | beforeEach(() => { 7 | service = { params: { searchKeywords: [] }, ...querySuggest } 8 | }) 9 | 10 | test('should set the searchKeywords param', () => { 11 | service.searchKeywords('Foo Bar', 'en') 12 | service.searchKeywords('Wir laufen', 'de') 13 | expect(service.params.searchKeywords).toEqual([ 14 | { 15 | lang: 'en', 16 | value: encodeURIComponent('Foo Bar'), 17 | }, 18 | { 19 | lang: 'de', 20 | value: encodeURIComponent('Wir laufen'), 21 | }, 22 | ]) 23 | }) 24 | 25 | test('should throw if searchKeywords params are missing', () => { 26 | expect(() => service.searchKeywords()).toThrow( 27 | /Required arguments for `searchKeywords` are missing/ 28 | ) 29 | expect(() => service.searchKeywords('Foo Bar')).toThrow( 30 | /Required arguments for `searchKeywords` are missing/ 31 | ) 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/query.spec.js: -------------------------------------------------------------------------------- 1 | import * as query from '../src/query' 2 | import { getDefaultQueryParams } from '../src/default-params' 3 | 4 | describe('query', () => { 5 | let service 6 | 7 | beforeEach(() => { 8 | service = { params: getDefaultQueryParams(), ...query } 9 | }) 10 | 11 | test('should set the where param', () => { 12 | service.where('name(en = "Foo Bar")') 13 | expect(service.params.query.where).toEqual([ 14 | encodeURIComponent('name(en = "Foo Bar")'), 15 | ]) 16 | }) 17 | 18 | test('should throw if predicate is missing', () => { 19 | expect(() => service.where()).toThrow( 20 | /Required argument for `where` is missing/ 21 | ) 22 | }) 23 | 24 | test('should set the whereOperator param', () => { 25 | service.whereOperator('or') 26 | expect(service.params.query.operator).toBe('or') 27 | 28 | service.whereOperator('and') 29 | expect(service.params.query.operator).toBe('and') 30 | }) 31 | 32 | test('should throw if whereOperator is missing', () => { 33 | expect(() => service.whereOperator()).toThrow( 34 | /Required argument for `whereOperator` is missing/ 35 | ) 36 | }) 37 | 38 | test('should throw if whereOperator is wrong', () => { 39 | expect(() => service.whereOperator('foo')).toThrow( 40 | // eslint-disable-next-line max-len 41 | /Required argument for `whereOperator` is invalid, allowed values are \(`and`, `or`\)/ 42 | ) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/api-request-builder/test/version.spec.js: -------------------------------------------------------------------------------- 1 | import withVersion from '../src/version' 2 | 3 | describe('withVersion', () => { 4 | let service 5 | 6 | beforeEach(() => { 7 | service = { params: {}, withVersion } 8 | }) 9 | 10 | test('should set the version number of an item', () => { 11 | service.withVersion(3) 12 | expect(service.params.version).toBe(3) 13 | }) 14 | 15 | test('should throw if not passed any value', () => { 16 | expect(() => service.withVersion()).toThrow( 17 | /A resource version is missing or invalid/ 18 | ) 19 | }) 20 | 21 | test('should throw if not passed a number', () => { 22 | expect(() => service.withVersion('foo')).toThrow( 23 | /A resource version is missing or invalid/ 24 | ) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /packages/category-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # category-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/csv-parser-discount-code/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-csv-parser-discount-code 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/csv-parser-orders/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-csv-parser-orders 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/csv-parser-price/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-csv-parser-price 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/csv-parser-state/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-csv-parser-state 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/custom-objects-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # custom-objects-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/custom-objects-importer/readme.md: -------------------------------------------------------------------------------- 1 | # custom-objects-importer 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/customer-groups-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # customer-groups-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/discount-code-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # discount-code-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/discount-code-generator/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/discount-code-generator 2 | 3 | ## 4.0.0 4 | 5 | ### Major Changes 6 | 7 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 8 | 9 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 10 | 11 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 12 | 13 | ## 3.0.0 14 | 15 | ### Major Changes 16 | 17 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 18 | 19 | ## 2.0.10 20 | 21 | ### Patch Changes 22 | 23 | - [#1734](https://github.com/commercetools/nodejs/pull/1734) [`1385e5a0`](https://github.com/commercetools/nodejs/commit/1385e5a0b649e088d67f2647b05a06dc02aca76b) Thanks [@jenschude](https://github.com/jenschude)! - Cleanup & update dependencies 24 | -------------------------------------------------------------------------------- /packages/discount-code-generator/readme.md: -------------------------------------------------------------------------------- 1 | # discount-code-generator 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/discount-code-importer/readme.md: -------------------------------------------------------------------------------- 1 | # discount-code-importer 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/get-credentials/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/get-credentials 2 | 3 | ## 5.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 5.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 4.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | 27 | ## 3.0.18 28 | 29 | ### Patch Changes 30 | 31 | - [#1609](https://github.com/commercetools/nodejs/pull/1609) [`34e1bb80`](https://github.com/commercetools/nodejs/commit/34e1bb8010225fcc5ea7459bdd93f330eb7dd37d) Thanks [@renovate](https://github.com/apps/renovate)! - chore(deps): update all dependencies 32 | -------------------------------------------------------------------------------- /packages/get-credentials/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/get-credentials", 9 | "version": "5.0.1", 10 | "description": "Get CT credentials from the system environment.", 11 | "keywords": [ 12 | "commercetools", 13 | "credentials" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/commercetools/nodejs/tree/master/packages/get-credentials" 18 | }, 19 | "homepage": "https://commercetools.github.io/nodejs/sdk/api/getCredentials", 20 | "bugs": "https://github.com/commercetools/nodejs/issues", 21 | "license": "MIT", 22 | "contributors": [ 23 | "Selwyn Versteeg (https://selwyn.cc/)" 24 | ], 25 | "main": "lib/index.js", 26 | "files": [ 27 | "lib" 28 | ], 29 | "scripts": { 30 | "prebuild": "rimraf lib/**", 31 | "build": "babel src --out-dir lib --config-file '../../babel.config.js'" 32 | }, 33 | "devDependencies": { 34 | "sinon": "9.2.4" 35 | }, 36 | "dependencies": { 37 | "dotenv": "^8.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/get-credentials/readme.md: -------------------------------------------------------------------------------- 1 | # get-credentials 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Retrieve commercetools platform credentials from environment variables or file system. 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/getCredentials 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/get-credentials 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/get-credentials/src/get-credentials.js: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv' 2 | import path from 'path' 3 | 4 | import { homepage } from '../package.json' 5 | 6 | export function setCredentialsFromEnvFile() { 7 | const currentDirectoryResult = dotenv.config({ 8 | path: path.resolve('.ct-credentials.env'), 9 | }) 10 | const etcDirectoryResult = dotenv.config({ 11 | path: path.resolve(path.join('/etc', '.ct-credentials.env')), 12 | }) 13 | 14 | return { 15 | ...currentDirectoryResult.parsed, 16 | ...etcDirectoryResult.parsed, 17 | } 18 | } 19 | 20 | export function getCredentialsFromEnvironment(projectKey) { 21 | return new Promise((resolve, reject) => { 22 | const envKey = `CT_${projectKey.toUpperCase().replace(/-/g, '_')}` 23 | const envValue = process.env[envKey] || '' 24 | 25 | if (!envValue) 26 | return reject( 27 | new Error( 28 | `Could not find environment variable ${envKey} 29 | see ${homepage}#usage` 30 | ) 31 | ) 32 | 33 | if (!envValue.match(/\w+:\w+/)) 34 | return reject( 35 | new Error( 36 | `Could not get credentials from value '${envValue}' in ${envKey} 37 | see ${homepage}#usage` 38 | ) 39 | ) 40 | 41 | const [clientId, clientSecret] = envValue.split(':') 42 | 43 | return resolve({ 44 | clientId, 45 | clientSecret, 46 | }) 47 | }) 48 | } 49 | 50 | export default function getCredentials(projectKey) { 51 | if (!projectKey) 52 | return Promise.reject(new Error('Missing "projectKey" argument')) 53 | 54 | return Promise.resolve(setCredentialsFromEnvFile()) 55 | .then(() => getCredentialsFromEnvironment(projectKey)) 56 | .catch((environmentError) => Promise.reject(environmentError)) 57 | } 58 | -------------------------------------------------------------------------------- /packages/get-credentials/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as getCredentials } from './get-credentials' 3 | export { getCredentialsFromEnvironment } from './get-credentials' 4 | export { setCredentialsFromEnvFile } from './get-credentials' 5 | -------------------------------------------------------------------------------- /packages/http-user-agent/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'plugin:import/typescript', 6 | 'plugin:jest/recommended', 7 | 'prettier', 8 | 'prettier/@typescript-eslint', 9 | ], 10 | plugins: ['import', 'jest', 'prettier', '@typescript-eslint/eslint-plugin'], 11 | env: { 12 | es6: true, 13 | browser: true, 14 | jest: true, 15 | node: true, 16 | }, 17 | rules: { 18 | '@typescript-eslint/camelcase': 0, 19 | '@typescript-eslint/consistent-type-definitions': 0, 20 | '@typescript-eslint/explicit-function-return-type': 0, 21 | '@typescript-eslint/no-explicit-any': 2, 22 | '@typescript-eslint/no-use-before-define': ['error', { functions: false }], 23 | '@typescript-eslint/no-var-requires': 0, 24 | '@typescript-eslint/unbound-method': 0, 25 | 'import/no-extraneous-dependencies': 0, 26 | 'import/no-named-as-default': 0, 27 | 'import/no-unresolved': 2, 28 | }, 29 | settings: { 30 | 'import/parsers': { 31 | '@typescript-eslint/parser': ['.ts'], 32 | }, 33 | 'import/resolver': { 34 | 'eslint-import-resolver-typescript': true, 35 | typescript: {}, 36 | node: { 37 | extensions: ['.js', '.ts'], 38 | }, 39 | }, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /packages/http-user-agent/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/http-user-agent 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 4.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 3.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/http-user-agent/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-http-user-agent 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Creates a proper HTTP User-Agent 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/httpUserAgent 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/http-user-agent 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/http-user-agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/http-user-agent", 9 | "version": "4.0.1", 10 | "description": "Creates a proper HTTP User-Agent", 11 | "keywords": [ 12 | "commercetools", 13 | "http", 14 | "user-agent" 15 | ], 16 | "homepage": "https://commercetools.github.io/nodejs/", 17 | "bugs": "https://github.com/commercetools/nodejs/issues", 18 | "license": "MIT", 19 | "author": "Nicola Molinari (https://github.com/emmenko)", 20 | "main": "dist/commercetools-http-user-agent.cjs.js", 21 | "module": "dist/commercetools-http-user-agent.esm.js", 22 | "browser": { 23 | "./dist/commercetools-http-user-agent.cjs.js": "./dist/commercetools-http-user-agent.browser.cjs.js", 24 | "./dist/commercetools-http-user-agent.esm.js": "./dist/commercetools-http-user-agent.browser.esm.js" 25 | }, 26 | "typings": "./dist/commercetools-http-user-agent.cjs.d.ts", 27 | "types": "./dist/commercetools-http-user-agent.cjs.d.ts", 28 | "preconstruct": { 29 | "entrypoints": [ 30 | "./index.ts" 31 | ], 32 | "umdName": "commercetoolsHttpUserAgent" 33 | }, 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/commercetools/nodejs.git" 37 | }, 38 | "files": [ 39 | "dist" 40 | ], 41 | "scripts": { 42 | "prebuild": "rimraf dist/**", 43 | "build": "exit 0;" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/http-user-agent/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './create-user-agent' 2 | -------------------------------------------------------------------------------- /packages/http-user-agent/tsconfig.declarations.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "isolatedModules": false 6 | }, 7 | "exclude": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx" 10 | ] 11 | } -------------------------------------------------------------------------------- /packages/http-user-agent/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "files": ["src/index.ts"] 4 | } -------------------------------------------------------------------------------- /packages/inventories-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # Inventories Exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/personal-data-erasure/bin/personal-data-erasure.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint-disable */ 4 | /* 5 | This file exists because we use Babel to transpile the JS but when testing 6 | the CLI we need to spawn a process that uses normal JS. 7 | */ 8 | 'use strict' 9 | 10 | require('../lib/cli.js') 11 | -------------------------------------------------------------------------------- /packages/personal-data-erasure/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/personal-data-erasure", 9 | "version": "5.0.1", 10 | "description": "Export and delete all data related to a single customer", 11 | "main": "lib/main.js", 12 | "bin": "bin/personal-data-erasure.js", 13 | "scripts": { 14 | "prebuild": "rimraf lib/**", 15 | "build": "babel src --out-dir lib --config-file '../../babel.config.js'" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/commercetools/nodejs/tree/master/packages/personal-data-erasure" 20 | }, 21 | "homepage": "https://commercetools.github.io/nodejs/cli/personal-data-erasure", 22 | "bugs": "https://github.com/commercetools/nodejs/issues", 23 | "keywords": [ 24 | "commercetools", 25 | "customer", 26 | "get", 27 | "delete", 28 | "json", 29 | "personal-data" 30 | ], 31 | "author": { 32 | "name": "Daniel Eriksson", 33 | "email": "daniel.eriksson@commercetools.com" 34 | }, 35 | "license": "MIT", 36 | "dependencies": { 37 | "@commercetools/api-request-builder": "workspace:*", 38 | "@commercetools/get-credentials": "workspace:*", 39 | "@commercetools/sdk-client": "workspace:*", 40 | "@commercetools/sdk-middleware-auth": "workspace:*", 41 | "@commercetools/sdk-middleware-http": "workspace:*", 42 | "@commercetools/sdk-middleware-user-agent": "workspace:*", 43 | "lodash.flatten": "^4.4.0", 44 | "node-fetch": "^2.6.7", 45 | "pino": "^6.0.0", 46 | "pretty-error": "^2.1.1", 47 | "prompt-confirm": "^2.0.4", 48 | "yargs": "^16.0.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/personal-data-erasure/readme.md: -------------------------------------------------------------------------------- 1 | # personal-data-erasure 2 | 3 | Export and delete all customer data from the commercetools platform. 4 | 5 | ## Install 6 | 7 | ```bash 8 | npm install @commercetools/personal-data-erasure --global 9 | ``` 10 | -------------------------------------------------------------------------------- /packages/personal-data-erasure/src/utils/silent-logger.js: -------------------------------------------------------------------------------- 1 | export default { 2 | error: () => {}, 3 | warn: () => {}, 4 | info: () => {}, 5 | debug: () => {}, 6 | } 7 | -------------------------------------------------------------------------------- /packages/price-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # price-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/product-exporter/readme.md: -------------------------------------------------------------------------------- 1 | # product-exporter 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/product-json-to-csv/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-product-json-to-csv 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/product-json-to-xlsx/readme.md: -------------------------------------------------------------------------------- 1 | # commercetools-product-json-to-xlsx 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/resource-deleter/bin/resource-deleter.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint-disable */ 4 | /* 5 | This file exists because we use Babel to transpile the JS but when testing 6 | the CLI we need to spawn a process that uses normal JS. 7 | */ 8 | 'use strict' 9 | 10 | require('../lib/cli.js') 11 | -------------------------------------------------------------------------------- /packages/resource-deleter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/resource-deleter", 9 | "version": "4.0.1", 10 | "description": "Delete resources from the commercetools platform", 11 | "main": "lib/main.js", 12 | "bin": "bin/resource-deleter.js", 13 | "scripts": { 14 | "prebuild": "rimraf lib/**", 15 | "build": "babel src --out-dir lib --config-file '../../babel.config.js'" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/commercetools/nodejs/tree/master/packages/resource-deleter" 20 | }, 21 | "homepage": "https://commercetools.github.io/nodejs/cli/resource-deleter", 22 | "bugs": "https://github.com/commercetools/nodejs/issues", 23 | "keywords": [ 24 | "commercetools", 25 | "resource", 26 | "resources", 27 | "delete" 28 | ], 29 | "author": { 30 | "name": "Babajide Williams", 31 | "email": "babajide.williams@commercetools.com" 32 | }, 33 | "license": "MIT", 34 | "dependencies": { 35 | "@commercetools/api-request-builder": "workspace:*", 36 | "@commercetools/get-credentials": "workspace:*", 37 | "@commercetools/sdk-client": "workspace:*", 38 | "@commercetools/sdk-middleware-auth": "workspace:*", 39 | "@commercetools/sdk-middleware-http": "workspace:*", 40 | "@commercetools/sdk-middleware-queue": "workspace:*", 41 | "@commercetools/sdk-middleware-user-agent": "workspace:*", 42 | "core-js": "^3.22.5", 43 | "node-fetch": "^2.6.7", 44 | "pino": "^6.0.0", 45 | "pretty-error": "^2.1.1", 46 | "prompts": "^2.0.4", 47 | "regenerator-runtime": "^0.14.0", 48 | "yargs": "^16.0.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/resource-deleter/readme.md: -------------------------------------------------------------------------------- 1 | # resource-deleter 2 | 3 | Deletes commercetools resources from the commercetools platform. 4 | 5 | More info here: https://commercetools.github.io/nodejs/cli/resource-deleter 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install @commercetools/resource-deleter --global 11 | ``` 12 | -------------------------------------------------------------------------------- /packages/resource-deleter/src/constants.js: -------------------------------------------------------------------------------- 1 | const CONSTANTS = { 2 | host: { 3 | api: 'https://api.europe-west1.gcp.commercetools.com', 4 | auth: 'https://auth.europe-west1.gcp.commercetools.com', 5 | }, 6 | 7 | standardOption: { 8 | confirm: 'false', 9 | defaultLogFile: 'resources-deleted-report.log', 10 | }, 11 | } 12 | 13 | // Go through object because `freeze` works shallow 14 | Object.keys(CONSTANTS).forEach((key) => { 15 | Object.freeze(CONSTANTS[key]) 16 | }) 17 | 18 | export default CONSTANTS 19 | -------------------------------------------------------------------------------- /packages/resource-deleter/src/utils/silent-logger.js: -------------------------------------------------------------------------------- 1 | export default { 2 | error: () => {}, 3 | warn: () => {}, 4 | info: () => {}, 5 | debug: () => {}, 6 | } 7 | -------------------------------------------------------------------------------- /packages/sdk-auth/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-auth 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Auth module for working with commercetools platform API 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkAuth 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-auth 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-auth", 9 | "version": "5.0.1", 10 | "description": "Auth module for different authentication flows of commercetools platform API", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "auth", 15 | "oauth" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Jan Juna (https://github.com/junajan)", 21 | "main": "dist/commercetools-sdk-auth.cjs.js", 22 | "module": "dist/commercetools-sdk-auth.esm.js", 23 | "umd:min": "dist/commercetools-sdk-auth.umd.js", 24 | "preconstruct": { 25 | "entrypoints": [ 26 | "./index.js" 27 | ], 28 | "umdName": "commercetoolsSdkAuth" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/commercetools/nodejs.git" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | }, 41 | "dependencies": { 42 | "@commercetools/sdk-middleware-http": "workspace:*", 43 | "qss": "2.0.3" 44 | }, 45 | "devDependencies": { 46 | "nock": "12.0.3", 47 | "node-fetch": "^2.6.7" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/sdk-auth/src/constants.js: -------------------------------------------------------------------------------- 1 | export const MANAGE_PROJECT = 'manage_project' 2 | export const DEFAULT_AUTH_TYPE = 'Basic' 3 | export const EXPIRATION_OFFSET = 2 * 60 * 60 * 1000 // 2 hours 4 | -------------------------------------------------------------------------------- /packages/sdk-auth/src/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './auth' 2 | export TokenProvider from './tokenProvider' 3 | -------------------------------------------------------------------------------- /packages/sdk-auth/test/anonymous-flow.spec.js: -------------------------------------------------------------------------------- 1 | import nock from 'nock' 2 | import Auth from '../src/auth' 3 | import config from './resources/sample-config' 4 | import response from './resources/sample-response.json' 5 | 6 | describe('Anonymous flow', () => { 7 | const auth = new Auth(config) 8 | jest.spyOn(Auth, '_calculateExpirationTime').mockImplementation(() => 123) 9 | 10 | beforeEach(() => nock.cleanAll()) 11 | 12 | test('should authenticate without anonymousId', async () => { 13 | const scope = nock(config.host) 14 | .post(`/oauth/${config.projectKey}/anonymous/token`, { 15 | grant_type: 'client_credentials', 16 | scope: `manage_project:${config.projectKey}`, 17 | // no anonymousId 18 | }) 19 | .reply(200, JSON.stringify(response)) 20 | 21 | expect(scope.isDone()).toBe(false) 22 | const res = await auth.anonymousFlow() 23 | 24 | expect(scope.isDone()).toBe(true) 25 | expect(res).toEqual({ 26 | ...response, 27 | expires_at: 123, 28 | }) 29 | }) 30 | 31 | test('should authenticate with anonymousId', async () => { 32 | const scope = nock(config.host) 33 | .post(`/oauth/${config.projectKey}/anonymous/token`, { 34 | grant_type: 'client_credentials', 35 | scope: `manage_project:${config.projectKey}`, 36 | anonymous_id: '123', 37 | }) 38 | .reply(200, JSON.stringify(response)) 39 | 40 | expect(scope.isDone()).toBe(false) 41 | const res = await auth.anonymousFlow(123) 42 | 43 | expect(scope.isDone()).toBe(true) 44 | expect(res).toEqual({ 45 | ...response, 46 | expires_at: 123, 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /packages/sdk-auth/test/client-credentials-flow.spec.js: -------------------------------------------------------------------------------- 1 | import nock from 'nock' 2 | import Auth from '../src/auth' 3 | import config from './resources/sample-config' 4 | import response from './resources/sample-response.json' 5 | 6 | describe('Client Credentials flow', () => { 7 | const auth = new Auth(config) 8 | jest.spyOn(Auth, '_calculateExpirationTime').mockImplementation(() => 123) 9 | 10 | beforeEach(() => nock.cleanAll()) 11 | 12 | test('should authenticate with correct credentials', async () => { 13 | const scope = nock(config.host) 14 | .post(`/oauth/token`, { 15 | grant_type: 'client_credentials', 16 | scope: `manage_project:${config.projectKey}`, 17 | }) 18 | .reply(200, JSON.stringify(response)) 19 | 20 | expect(scope.isDone()).toBe(false) 21 | const res = await auth.clientCredentialsFlow() 22 | expect(scope.isDone()).toBe(true) 23 | expect(res).toEqual({ 24 | ...response, 25 | expires_at: 123, 26 | }) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /packages/sdk-auth/test/refresh-token-flow.spec.js: -------------------------------------------------------------------------------- 1 | import nock from 'nock' 2 | import Auth from '../src/auth' 3 | import config from './resources/sample-config' 4 | import response from './resources/sample-response.json' 5 | 6 | describe('Refresh Token flow', () => { 7 | const auth = new Auth(config) 8 | jest.spyOn(Auth, '_calculateExpirationTime').mockImplementation(() => 123) 9 | 10 | beforeEach(() => nock.cleanAll()) 11 | 12 | test('should send a refresh token request', async () => { 13 | const scope = nock(config.host) 14 | .post(`/oauth/token`, { 15 | grant_type: 'refresh_token', 16 | refresh_token: 'refreshTokenValue', 17 | }) 18 | .reply(200, JSON.stringify(response)) 19 | 20 | expect(scope.isDone()).toBe(false) 21 | const res = await auth.refreshTokenFlow('refreshTokenValue') 22 | expect(scope.isDone()).toBe(true) 23 | expect(res).toEqual({ 24 | ...response, 25 | expires_at: 123, 26 | }) 27 | }) 28 | 29 | test('should throw an error when token is not provided', async () => { 30 | expect(() => auth.refreshTokenFlow()).toThrow( 31 | 'Missing required token value' 32 | ) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /packages/sdk-auth/test/resources/sample-config.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch' 2 | 3 | const config = { 4 | host: 'https://auth.commercetools.com', 5 | projectKey: 'sample-project', 6 | credentials: { 7 | clientId: 'sampleClient', 8 | clientSecret: 'sampleSecret', 9 | }, 10 | fetch, 11 | } 12 | 13 | export default config 14 | -------------------------------------------------------------------------------- /packages/sdk-auth/test/resources/sample-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "access_token": "wohdwohfowpjf-XNe-i784rh9Zij-B", 3 | "expires_in": 172800, 4 | "scope": "manage_project:sample-project", 5 | "refresh_token": "owhdiwdiwuIhnIjW-bLnJkmFzTTUluM6iq-SVfGjkQzI", 6 | "token_type": "Bearer" 7 | } -------------------------------------------------------------------------------- /packages/sdk-auth/test/token-introspection.spec.js: -------------------------------------------------------------------------------- 1 | import nock from 'nock' 2 | import querystring from 'querystring' 3 | import Auth from '../src/auth' 4 | import config from './resources/sample-config' 5 | 6 | describe('Token Introspection', () => { 7 | const response = { 8 | active: true, 9 | scope: `manage_project:${config.projectKey}`, 10 | expires_in: 12345, 11 | } 12 | const auth = new Auth(config) 13 | jest.spyOn(Auth, '_calculateExpirationTime').mockImplementation(() => 123) 14 | 15 | beforeEach(() => nock.cleanAll()) 16 | 17 | test('should introspect token', async () => { 18 | const scope = nock(config.host) 19 | .post( 20 | '/oauth/introspect', 21 | querystring.encode({ 22 | grant_type: 'client_credentials', 23 | scope: 'manage_project:sample-project', 24 | token: 'tokenValue', 25 | }) 26 | ) 27 | .reply(200, JSON.stringify(response)) 28 | 29 | expect(scope.isDone()).toBe(false) 30 | const res = await auth.introspectToken('tokenValue') 31 | expect(scope.isDone()).toBe(true) 32 | expect(res).toEqual({ 33 | ...response, 34 | expires_at: 123, 35 | }) 36 | }) 37 | 38 | test('should throw an error when token is not provided', () => { 39 | expect(() => auth.introspectToken()).toThrow('Missing required token value') 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /packages/sdk-client/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/sdk-client 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 4.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 3.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/sdk-client/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-client 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | SDK Client for usage of commercetools platform API 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkClient 16 | 17 | ## Note: 18 | 19 | This sdk is no longer actively maintained. Follow this [link](https://www.npmjs.com/package/@commercetools/sdk-client-v2) to migrate to the new TypeScript SDK 20 | 21 | ## Install 22 | 23 | ```bash 24 | npm install --save @commercetools/sdk-client 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/sdk-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-client", 9 | "version": "4.0.1", 10 | "description": "SDK Client for usage of commercetools platform API", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "api", 15 | "client" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Nicola Molinari (https://github.com/emmenko)", 21 | "main": "dist/commercetools-sdk-client.cjs.js", 22 | "module": "dist/commercetools-sdk-client.esm.js", 23 | "umd:min": "dist/commercetools-sdk-client.umd.js", 24 | "preconstruct": { 25 | "entrypoints": [ 26 | "./index.js" 27 | ], 28 | "umdName": "commercetoolsSdkClient" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/commercetools/nodejs.git" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-client/src/allowed-methods.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'ACL', 3 | 'BIND', 4 | 'CHECKOUT', 5 | 'CONNECT', 6 | 'COPY', 7 | 'DELETE', 8 | 'GET', 9 | 'HEAD', 10 | 'LINK', 11 | 'LOCK', 12 | 'M-SEARCH', 13 | 'MERGE', 14 | 'MKACTIVITY', 15 | 'MKCALENDAR', 16 | 'MKCOL', 17 | 'MOVE', 18 | 'NOTIFY', 19 | 'OPTIONS', 20 | 'PATCH', 21 | 'POST', 22 | 'PROPFIND', 23 | 'PROPPATCH', 24 | 'PURGE', 25 | 'PUT', 26 | 'REBIND', 27 | 'REPORT', 28 | 'SEARCH', 29 | 'SOURCE', 30 | 'SUBSCRIBE', 31 | 'TRACE', 32 | 'UNBIND', 33 | 'UNLINK', 34 | 'UNLOCK', 35 | 'UNSUBSCRIBE', 36 | ] 37 | -------------------------------------------------------------------------------- /packages/sdk-client/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createClient } from './client' 3 | -------------------------------------------------------------------------------- /packages/sdk-client/src/validate.js: -------------------------------------------------------------------------------- 1 | import METHODS from './allowed-methods' 2 | 3 | export default function validate( 4 | funcName: string, 5 | request: Object, 6 | options: Object = { allowedMethods: METHODS } 7 | ) { 8 | if (!request) 9 | // eslint-disable-next-line max-len 10 | throw new Error( 11 | `The "${funcName}" function requires a "Request" object as an argument. See https://commercetools.github.io/nodejs/sdk/Glossary#clientrequest` 12 | ) 13 | 14 | if (typeof request.uri !== 'string') 15 | // eslint-disable-next-line max-len 16 | throw new Error( 17 | `The "${funcName}" Request object requires a valid uri. See https://commercetools.github.io/nodejs/sdk/Glossary#clientrequest` 18 | ) 19 | 20 | if (!options.allowedMethods.includes(request.method)) 21 | // eslint-disable-next-line max-len 22 | throw new Error( 23 | `The "${funcName}" Request object requires a valid method. See https://commercetools.github.io/nodejs/sdk/Glossary#clientrequest` 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-auth 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Auth middlewares collection for usage with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareAuth 16 | 17 | ### Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-auth 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-auth", 9 | "version": "8.0.1", 10 | "description": "Middleware for different authentication flows of commercetools platform API, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "auth", 16 | "oauth" 17 | ], 18 | "homepage": "https://commercetools.github.io/nodejs/", 19 | "bugs": "https://github.com/commercetools/nodejs/issues", 20 | "license": "MIT", 21 | "author": "Nicola Molinari (https://github.com/emmenko)", 22 | "main": "dist/commercetools-sdk-middleware-auth.cjs.js", 23 | "module": "dist/commercetools-sdk-middleware-auth.esm.js", 24 | "umd:min": "dist/commercetools-sdk-middleware-auth.umd.js", 25 | "preconstruct": { 26 | "entrypoints": [ 27 | "./index.js" 28 | ], 29 | "umdName": "commercetoolsSdkMiddlewareAuth" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/commercetools/nodejs.git" 34 | }, 35 | "files": [ 36 | "dist" 37 | ], 38 | "scripts": { 39 | "prebuild": "rimraf dist/**", 40 | "build": "exit 0;" 41 | }, 42 | "dependencies": { 43 | "@commercetools/sdk-middleware-http": "workspace:*", 44 | "node-fetch": "^2.6.7" 45 | }, 46 | "devDependencies": { 47 | "abort-controller": "3.0.0", 48 | "nock": "12.0.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/anonymous-session-flow.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | AuthMiddlewareOptions, 4 | Middleware, 5 | MiddlewareRequest, 6 | MiddlewareResponse, 7 | Next, 8 | Task, 9 | } from 'types/sdk' 10 | 11 | import { buildRequestForAnonymousSessionFlow } from './build-requests' 12 | import authMiddlewareBase from './base-auth-flow' 13 | import store from './utils' 14 | 15 | export default function createAuthMiddlewareForAnonymousSessionFlow( 16 | options: AuthMiddlewareOptions 17 | ): Middleware { 18 | const tokenCache = store({}) 19 | const pendingTasks: Array = [] 20 | 21 | const requestState = store(false) 22 | return (next: Next): Next => 23 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 24 | // Check if there is already a `Authorization` header in the request. 25 | // If so, then go directly to the next middleware. 26 | if ( 27 | (request.headers && request.headers.authorization) || 28 | (request.headers && request.headers.Authorization) 29 | ) { 30 | next(request, response) 31 | return 32 | } 33 | const params = { 34 | ...options, 35 | request, 36 | response, 37 | ...buildRequestForAnonymousSessionFlow(options), 38 | pendingTasks, 39 | requestState, 40 | tokenCache, 41 | fetch: options.fetch, 42 | } 43 | authMiddlewareBase(params, next, options) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/build-token-cache-key.js: -------------------------------------------------------------------------------- 1 | import type { AuthMiddlewareOptions, TokenCacheOptions } from 'types/sdk' 2 | 3 | export default function buildTokenCacheKey( 4 | options: AuthMiddlewareOptions 5 | ): TokenCacheOptions { 6 | return { 7 | clientId: options.credentials.clientId, 8 | host: options.host, 9 | projectKey: options.projectKey, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/client-credentials-flow.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | AuthMiddlewareOptions, 4 | Middleware, 5 | MiddlewareRequest, 6 | MiddlewareResponse, 7 | Next, 8 | Task, 9 | } from 'types/sdk' 10 | 11 | import { buildRequestForClientCredentialsFlow } from './build-requests' 12 | import buildTokenCacheKey from './build-token-cache-key' 13 | import authMiddlewareBase from './base-auth-flow' 14 | import store from './utils' 15 | 16 | export default function createAuthMiddlewareForClientCredentialsFlow( 17 | options: AuthMiddlewareOptions 18 | ): Middleware { 19 | const tokenCache = 20 | options.tokenCache || 21 | store({ 22 | token: '', 23 | expirationTime: -1, 24 | }) 25 | const requestState = store(false) 26 | const pendingTasks: Array = [] 27 | 28 | return (next: Next): Next => 29 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 30 | // Check if there is already a `Authorization` header in the request. 31 | // If so, then go directly to the next middleware. 32 | if ( 33 | (request.headers && request.headers.authorization) || 34 | (request.headers && request.headers.Authorization) 35 | ) { 36 | next(request, response) 37 | return 38 | } 39 | const params = { 40 | ...options, 41 | request, 42 | response, 43 | ...buildRequestForClientCredentialsFlow(options), 44 | pendingTasks, 45 | requestState, 46 | tokenCache, 47 | tokenCacheKey: buildTokenCacheKey(options), 48 | fetch: options.fetch, 49 | } 50 | authMiddlewareBase(params, next) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/existing-token.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | Middleware, 4 | MiddlewareRequest, 5 | MiddlewareResponse, 6 | ExistingTokenMiddlewareOptions, 7 | Next, 8 | } from 'types/sdk' 9 | 10 | export default function createAuthMiddlewareWithExistingToken( 11 | authorization: string = '', 12 | options: ExistingTokenMiddlewareOptions = {} 13 | ): Middleware { 14 | return (next: Next): Next => 15 | (request: MiddlewareRequest, response: MiddlewareResponse): mixed => { 16 | if (typeof authorization !== 'string') 17 | throw new Error('authorization must be a string') 18 | const force = options.force === undefined ? true : options.force 19 | 20 | /** The request will not be modified if: 21 | * 1. no argument is passed 22 | * 2. force is false and authorization header exists 23 | */ 24 | if ( 25 | !authorization || 26 | (((request.headers && request.headers.authorization) || 27 | (request.headers && request.headers.Authorization)) && 28 | force === false) 29 | ) { 30 | return next(request, response) 31 | } 32 | const requestWithAuth = { 33 | ...request, 34 | headers: { 35 | ...request.headers, 36 | Authorization: authorization, 37 | }, 38 | } 39 | return next(requestWithAuth, response) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-len */ 2 | export { default as createAuthMiddlewareForClientCredentialsFlow } from './client-credentials-flow' 3 | export { default as createAuthMiddlewareForPasswordFlow } from './password-flow' 4 | export { default as createAuthMiddlewareForRefreshTokenFlow } from './refresh-token-flow' 5 | export { default as createAuthMiddlewareForAnonymousSessionFlow } from './anonymous-session-flow' 6 | export { default as createAuthMiddlewareWithExistingToken } from './existing-token' 7 | export * as scopes from './scopes' 8 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/password-flow.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | PasswordAuthMiddlewareOptions, 4 | Middleware, 5 | MiddlewareRequest, 6 | MiddlewareResponse, 7 | Next, 8 | Task, 9 | } from 'types/sdk' 10 | 11 | import { buildRequestForPasswordFlow } from './build-requests' 12 | import authMiddlewareBase from './base-auth-flow' 13 | import store from './utils' 14 | 15 | export default function createAuthMiddlewareForPasswordFlow( 16 | options: PasswordAuthMiddlewareOptions 17 | ): Middleware { 18 | const tokenCache = store({}) 19 | const pendingTasks: Array = [] 20 | const requestState = store(false) 21 | 22 | return (next: Next): Next => 23 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 24 | // Check if there is already a `Authorization` header in the request. 25 | // If so, then go directly to the next middleware. 26 | if ( 27 | (request.headers && request.headers.authorization) || 28 | (request.headers && request.headers.Authorization) 29 | ) { 30 | next(request, response) 31 | return 32 | } 33 | const params = { 34 | ...options, 35 | request, 36 | response, 37 | ...buildRequestForPasswordFlow(options), 38 | pendingTasks, 39 | requestState, 40 | tokenCache, 41 | fetch: options.fetch, 42 | } 43 | authMiddlewareBase(params, next, options) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/refresh-token-flow.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | RefreshAuthMiddlewareOptions, 4 | Middleware, 5 | MiddlewareRequest, 6 | MiddlewareResponse, 7 | Next, 8 | Task, 9 | } from 'types/sdk' 10 | 11 | import { buildRequestForRefreshTokenFlow } from './build-requests' 12 | import authMiddlewareBase from './base-auth-flow' 13 | import store from './utils' 14 | 15 | export default function createAuthMiddlewareForRefreshTokenFlow( 16 | options: RefreshAuthMiddlewareOptions 17 | ): Middleware { 18 | const tokenCache = store({}) 19 | const pendingTasks: Array = [] 20 | 21 | const requestState = store(false) 22 | return (next: Next): Next => 23 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 24 | // Check if there is already a `Authorization` header in the request. 25 | // If so, then go directly to the next middleware. 26 | if ( 27 | (request.headers && request.headers.authorization) || 28 | (request.headers && request.headers.Authorization) 29 | ) { 30 | next(request, response) 31 | return 32 | } 33 | const params = { 34 | ...options, 35 | request, 36 | response, 37 | ...buildRequestForRefreshTokenFlow(options), 38 | pendingTasks, 39 | requestState, 40 | tokenCache, 41 | fetch: options.fetch, 42 | } 43 | authMiddlewareBase(params, next) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/scopes.js: -------------------------------------------------------------------------------- 1 | export const MANAGE_PROJECT = 'manage_project' 2 | export const MANAGE_PRODUCTS = 'manage_products' 3 | export const VIEW_PRODUCTS = 'view_products' 4 | export const MANAGE_ORDERS = 'manage_orders' 5 | export const VIEW_ORDERS = 'view_orders' 6 | export const MANAGE_MY_ORDERS = 'manage_my_orders' 7 | export const MANAGE_CUSTOMERS = 'manage_customers' 8 | export const VIEW_CUSTOMERS = 'view_customers' 9 | export const MANAGE_MY_PROFILE = 'manage_my_profile' 10 | export const MANAGE_TYPES = 'manage_types' 11 | export const VIEW_TYPES = 'view_types' 12 | export const MANAGE_PAYMENTS = 'manage_payments' 13 | export const VIEW_PAYMENTS = 'view_payments' 14 | export const CREATE_ANONYMOUS_TOKEN = 'create_anonymous_token' 15 | export const MANAGE_SUBSCRIPTIONS = 'manage_subscriptions' 16 | -------------------------------------------------------------------------------- /packages/sdk-middleware-auth/src/utils.js: -------------------------------------------------------------------------------- 1 | export default function store(initVal) { 2 | let value = initVal 3 | return { 4 | get: () => value, 5 | set: (val) => { 6 | value = val 7 | return value 8 | }, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/sdk-middleware-correlation-id 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 4.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 3.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-correlation-id 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Middleware for adding a correlation id to requests with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareCorrelationId 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-correlation-id 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-correlation-id", 9 | "version": "4.0.1", 10 | "description": "Middleware for adding a correlation id to requests being executed, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "correlation-id", 16 | "request tracing" 17 | ], 18 | "homepage": "https://commercetools.github.io/nodejs/", 19 | "bugs": "https://github.com/commercetools/nodejs/issues", 20 | "license": "MIT", 21 | "author": "Tobias Deekens (https://github.com/tdeekens)", 22 | "main": "dist/commercetools-sdk-middleware-correlation-id.cjs.js", 23 | "module": "dist/commercetools-sdk-middleware-correlation-id.esm.js", 24 | "umd:min": "dist/commercetools-sdk-middleware-correlation-id.umd.js", 25 | "preconstruct": { 26 | "entrypoints": [ 27 | "./index.js" 28 | ], 29 | "umdName": "commercetoolsSdkMiddlewareCorrelationId" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/commercetools/nodejs.git" 34 | }, 35 | "files": [ 36 | "dist" 37 | ], 38 | "scripts": { 39 | "prebuild": "rimraf dist/**", 40 | "build": "exit 0;" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/src/correlation-id.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | Middleware, 4 | MiddlewareRequest, 5 | MiddlewareResponse, 6 | CorrelationIdMiddlewareOptions, 7 | Next, 8 | } from '../../../types/sdk' 9 | 10 | export default function createCorrelationIdMiddleware( 11 | options: CorrelationIdMiddlewareOptions 12 | ): Middleware { 13 | return (next: Next): Next => 14 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 15 | const nextRequest = { 16 | ...request, 17 | headers: { 18 | ...request.headers, 19 | 'X-Correlation-ID': options.generate(), 20 | }, 21 | } 22 | next(nextRequest, response) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createCorrelationIdMiddleware } from './correlation-id' 3 | -------------------------------------------------------------------------------- /packages/sdk-middleware-correlation-id/test/correlation-id.spec.js: -------------------------------------------------------------------------------- 1 | import { createCorrelationIdMiddleware } from '../src' 2 | 3 | function createTestRequest(options) { 4 | return { 5 | uri: '', 6 | method: 'GET', 7 | body: null, 8 | headers: {}, 9 | ...options, 10 | } 11 | } 12 | 13 | function createTestResponse(options) { 14 | return { 15 | ...options, 16 | } 17 | } 18 | 19 | describe('CorrelationId', () => { 20 | const correlationId = 'abc-def-123' 21 | const middlewareOptions = { 22 | generate: jest.fn(() => correlationId), 23 | } 24 | const request = createTestRequest({ 25 | headers: { 26 | Authorization: '123', 27 | }, 28 | }) 29 | const response = createTestResponse() 30 | const correlationIdMiddleware = 31 | createCorrelationIdMiddleware(middlewareOptions) 32 | 33 | const next = (req) => { 34 | test('retains existing headers', () => { 35 | expect(req.headers.Authorization).toBe('123') 36 | }) 37 | 38 | test('adds an `X-Correlation-ID` header', () => { 39 | expect(req.headers['X-Correlation-ID']).toBe(correlationId) 40 | }) 41 | 42 | test('invokes `generate` on the middleware options', () => { 43 | expect(middlewareOptions.generate).toHaveBeenCalled() 44 | }) 45 | } 46 | 47 | correlationIdMiddleware(next)(request, response) 48 | }) 49 | -------------------------------------------------------------------------------- /packages/sdk-middleware-http/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-http 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Middleware for making http requests for usage with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareHttp 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-http 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-http/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-http", 9 | "version": "8.0.1", 10 | "description": "Middleware for http requests, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "http" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Nicola Molinari (https://github.com/emmenko)", 21 | "main": "dist/commercetools-sdk-middleware-http.cjs.js", 22 | "module": "dist/commercetools-sdk-middleware-http.esm.js", 23 | "umd:min": "dist/commercetools-sdk-middleware-http.umd.js", 24 | "preconstruct": { 25 | "entrypoints": [ 26 | "./index.js" 27 | ], 28 | "umdName": "commercetoolsSdkMiddlewareHttp" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/commercetools/nodejs.git" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | }, 41 | "devDependencies": { 42 | "abort-controller": "3.0.0", 43 | "nock": "12.0.3", 44 | "node-fetch": "^2.6.7" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/sdk-middleware-http/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createHttpMiddleware } from './http' 3 | export { default as getErrorByCode } from './errors' 4 | export * as errors from './errors' 5 | -------------------------------------------------------------------------------- /packages/sdk-middleware-http/src/parse-headers.js: -------------------------------------------------------------------------------- 1 | export default function parseHeaders(headers) { 2 | if (headers.raw) 3 | // node-fetch 4 | return headers.raw() 5 | 6 | // Tmp fix for Firefox until it supports iterables 7 | if (!headers.forEach) return {} 8 | 9 | // whatwg-fetch 10 | const map = {} 11 | headers.forEach((value, name) => { 12 | map[name] = value 13 | }) 14 | return map 15 | } 16 | -------------------------------------------------------------------------------- /packages/sdk-middleware-http/test/parse-headers.spec.js: -------------------------------------------------------------------------------- 1 | import parseHeaders from '../src/parse-headers' 2 | 3 | describe('Parse headers', () => { 4 | test('return headers for polyfill (node-fetch)', () => { 5 | const spy = jest.fn() 6 | parseHeaders({ raw: spy }) 7 | expect(spy).toHaveBeenCalledTimes(1) 8 | }) 9 | 10 | test('return headers for polyfill (whatwg-fetch)', () => { 11 | const spy = jest 12 | .fn() 13 | .mockImplementation((cb) => cb(['application/json'], 'content-type')) 14 | expect(parseHeaders({ forEach: spy })).toEqual({ 15 | 'content-type': ['application/json'], 16 | }) 17 | }) 18 | 19 | test('patch fix for firefox', () => { 20 | expect(parseHeaders({})).toEqual({}) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/sdk-middleware-logger 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 4.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 3.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-logger 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Middleware for queueing requests for usage with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareLogger 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-logger 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-logger", 9 | "version": "4.0.1", 10 | "description": "Middleware for logging request and response being executed, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "logger" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Nicola Molinari (https://github.com/emmenko)", 21 | "main": "dist/commercetools-sdk-middleware-logger.cjs.js", 22 | "module": "dist/commercetools-sdk-middleware-logger.esm.js", 23 | "umd:min": "dist/commercetools-sdk-middleware-logger.umd.js", 24 | "preconstruct": { 25 | "entrypoints": [ 26 | "./index.js" 27 | ], 28 | "umdName": "commercetoolsSdkMiddlewareLogger" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/commercetools/nodejs.git" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createLoggerMiddleware } from './logger' 3 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/src/logger.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | Middleware, 4 | MiddlewareRequest, 5 | MiddlewareResponse, 6 | Next, 7 | } from 'types/sdk' 8 | 9 | export default function createLoggerMiddleware(): Middleware { 10 | return (next: Next): Next => 11 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 12 | const { error, body, statusCode } = response 13 | /* eslint-disable */ 14 | console.log('Request: ', request) 15 | console.log('Response: ', { error, body, statusCode }) 16 | /* eslint-enable */ 17 | next(request, response) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/sdk-middleware-logger/test/logger.spec.js: -------------------------------------------------------------------------------- 1 | import { createLoggerMiddleware } from '../src' 2 | 3 | function createTestRequest(options) { 4 | return { 5 | uri: '', 6 | method: 'GET', 7 | body: null, 8 | headers: {}, 9 | ...options, 10 | } 11 | } 12 | 13 | function createTestResponse(options) { 14 | return { 15 | ...options, 16 | } 17 | } 18 | // eslint-disable-next-line 19 | const originalConsoleLog = console.log 20 | 21 | describe('Logger', () => { 22 | beforeEach(() => { 23 | // Mock `console.log` 24 | // eslint-disable-next-line 25 | console.log = jest.fn() 26 | }) 27 | 28 | afterEach(() => { 29 | // Reset original `console.log` 30 | // eslint-disable-next-line 31 | console.log = originalConsoleLog 32 | }) 33 | 34 | test('log request / response', () => { 35 | const request = createTestRequest({ 36 | uri: '/foo/bar', 37 | headers: { 38 | 'Content-Type': 'application/json', 39 | }, 40 | }) 41 | const response = createTestResponse({ 42 | resolve: jest.fn(), 43 | reject: jest.fn(), 44 | statusCode: 200, 45 | body: { foo: 'bar' }, 46 | error: new Error('Oops'), 47 | }) 48 | const loggerMiddleware = createLoggerMiddleware() 49 | 50 | const next = () => { 51 | /* eslint-disable */ 52 | expect(console.log).toHaveBeenCalledTimes(2) 53 | expect(console.log).toHaveBeenCalledWith('Request: ', request) 54 | expect(console.log).toHaveBeenCalledWith('Response: ', { 55 | statusCode: response.statusCode, 56 | body: response.body, 57 | error: response.error, 58 | }) /* eslint-enable */ 59 | } 60 | loggerMiddleware(next)(request, response) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /packages/sdk-middleware-queue/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/sdk-middleware-queue 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | - [#1949](https://github.com/commercetools/nodejs/pull/1949) [`6fe114e`](https://github.com/commercetools/nodejs/commit/6fe114e9a15edd319819cf98c33a4de22a6de301) Thanks [@industrian](https://github.com/industrian)! - Update links to documentation. 10 | 11 | ## 4.0.0 12 | 13 | ### Major Changes 14 | 15 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 16 | 17 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 18 | 19 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 20 | 21 | ## 3.0.0 22 | 23 | ### Major Changes 24 | 25 | - [#1775](https://github.com/commercetools/nodejs/pull/1775) [`35669f30`](https://github.com/commercetools/nodejs/commit/35669f30dbc4b24d59ec3df3f38417b1f2a77837) Thanks [@ajimae](https://github.com/ajimae)! - Drop support for Node `v10` and `v12`. Supported versions now are `v14`, `v16` and `v18`. 26 | -------------------------------------------------------------------------------- /packages/sdk-middleware-queue/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-queue 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Middleware for queueing requests for usage with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareQueue 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-queue 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-queue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-queue", 9 | "version": "4.0.1", 10 | "description": "Middleware for queueing requests, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "queue" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Nicola Molinari (https://github.com/emmenko)", 21 | "main": "dist/commercetools-sdk-middleware-queue.cjs.js", 22 | "module": "dist/commercetools-sdk-middleware-queue.esm.js", 23 | "umd:min": "dist/commercetools-sdk-middleware-queue.umd.js", 24 | "preconstruct": { 25 | "entrypoints": [ 26 | "./index.js" 27 | ], 28 | "umdName": "commercetoolsSdkMiddlewareQueue" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/commercetools/nodejs.git" 33 | }, 34 | "files": [ 35 | "dist" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-middleware-queue/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createQueueMiddleware } from './queue' 3 | -------------------------------------------------------------------------------- /packages/sdk-middleware-queue/src/queue.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | QueueMiddlewareOptions, 4 | Dispatch, 5 | Middleware, 6 | MiddlewareRequest, 7 | MiddlewareResponse, 8 | Next, 9 | } from 'types/sdk' 10 | 11 | type Task = { 12 | request: MiddlewareRequest, 13 | response: MiddlewareResponse, 14 | } 15 | 16 | export default function createQueueMiddleware({ 17 | concurrency = 20, 18 | }: QueueMiddlewareOptions = {}): Middleware { 19 | const queue: Array = [] 20 | let runningCount = 0 21 | 22 | const dequeue = (next: Dispatch) => { 23 | // We assume here that this task has been completed 24 | runningCount -= 1 25 | 26 | // Check if there are any other pending tasks and execute them 27 | if (queue.length && runningCount <= concurrency) { 28 | const nextTask = queue.shift() 29 | runningCount += 1 30 | next(nextTask.request, nextTask.response) 31 | } 32 | } 33 | 34 | return (next: Next): Next => 35 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 36 | // Override response `resolve` and `reject` to know when the request has 37 | // been completed and therefore trigger a pending task in the queue. 38 | const patchedResponse = { 39 | ...response, 40 | resolve(data: any) { 41 | // Resolve original promise 42 | response.resolve(data) 43 | dequeue(next) 44 | }, 45 | reject(error: any) { 46 | // Reject original promise 47 | response.reject(error) 48 | dequeue(next) 49 | }, 50 | } 51 | 52 | // Add task to the queue 53 | queue.push({ request, response: patchedResponse }) 54 | 55 | // If possible, run the task straight away 56 | if (runningCount < concurrency) { 57 | const nextTask = queue.shift() 58 | runningCount += 1 59 | 60 | next(nextTask.request, nextTask.response) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'plugin:import/typescript', 6 | 'plugin:jest/recommended', 7 | 'prettier', 8 | 'prettier/@typescript-eslint', 9 | ], 10 | plugins: ['import', 'jest', 'prettier', '@typescript-eslint/eslint-plugin'], 11 | env: { 12 | es6: true, 13 | browser: true, 14 | jest: true, 15 | node: true, 16 | }, 17 | rules: { 18 | '@typescript-eslint/camelcase': 0, 19 | '@typescript-eslint/consistent-type-definitions': 0, 20 | '@typescript-eslint/explicit-function-return-type': 0, 21 | '@typescript-eslint/no-explicit-any': 2, 22 | '@typescript-eslint/no-use-before-define': ['error', { functions: false }], 23 | '@typescript-eslint/no-var-requires': 0, 24 | '@typescript-eslint/unbound-method': 0, 25 | 'import/no-extraneous-dependencies': 0, 26 | 'import/no-named-as-default': 0, 27 | 'import/no-unresolved': 2, 28 | }, 29 | settings: { 30 | 'import/parsers': { 31 | '@typescript-eslint/parser': ['.ts'], 32 | }, 33 | 'import/resolver': { 34 | 'eslint-import-resolver-typescript': true, 35 | typescript: {}, 36 | node: { 37 | extensions: ['.js', '.ts'], 38 | }, 39 | }, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-middlware-user-agent 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | Middleware for setting the User-Agent on the HTTP request for usage with `@commercetools/sdk-client` 14 | 15 | https://commercetools.github.io/nodejs/sdk/api/sdkMiddlewareUserAgent 16 | 17 | ## Install 18 | 19 | ```bash 20 | npm install --save @commercetools/sdk-middleware-user-agent 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-middleware-user-agent", 9 | "version": "4.0.1", 10 | "description": "Middleware for setting the User-Agent on the HTTP request, to use with @commercetools/sdk-client", 11 | "keywords": [ 12 | "commercetools", 13 | "sdk", 14 | "middleware", 15 | "user-agent" 16 | ], 17 | "homepage": "https://commercetools.github.io/nodejs/", 18 | "bugs": "https://github.com/commercetools/nodejs/issues", 19 | "license": "MIT", 20 | "author": "Nicola Molinari (https://github.com/emmenko)", 21 | "main": "dist/commercetools-sdk-middleware-user-agent.cjs.js", 22 | "module": "dist/commercetools-sdk-middleware-user-agent.esm.js", 23 | "browser": { 24 | "./dist/commercetools-sdk-middleware-user-agent.cjs.js": "./dist/commercetools-sdk-middleware-user-agent.browser.cjs.js", 25 | "./dist/commercetools-sdk-middleware-user-agent.esm.js": "./dist/commercetools-sdk-middleware-user-agent.browser.esm.js" 26 | }, 27 | "typings": "./dist/typings/commercetools-sdk-middleware-user-agent.browser.cjs.d.ts", 28 | "types": "./dist/typings/commercetools-sdk-middleware-user-agent.browser.cjs.d.ts", 29 | "preconstruct": { 30 | "entrypoints": [ 31 | "./index.ts" 32 | ], 33 | "umdName": "commercetoolsSdkMiddlewareUserAgent" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/commercetools/nodejs.git" 38 | }, 39 | "files": [ 40 | "dist" 41 | ], 42 | "scripts": { 43 | "prebuild": "rimraf dist/**", 44 | "build": "exit 0;" 45 | }, 46 | "dependencies": { 47 | "@commercetools/http-user-agent": "workspace:*", 48 | "@commercetools/sdk-types": "workspace:*" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@commercetools/http-user-agent': 12 | specifier: ^3.0.0 13 | version: 3.0.0 14 | '@commercetools/sdk-types': 15 | specifier: ^0.1.2 16 | version: 0.1.2 17 | 18 | packages: 19 | 20 | '@commercetools/http-user-agent@3.0.0': 21 | resolution: {integrity: sha512-kHlVST/Ax8GFpG9vpcUR5wKBGBoY2tZDA87kSC3nxhgk2+szZfv7MMMaAt0EIz2thpyO7oJv9NyPY/3XrrNIXQ==} 22 | engines: {node: '>=14'} 23 | 24 | '@commercetools/sdk-types@0.1.2': 25 | resolution: {integrity: sha512-j9yFGbdOxc4RRaYXzQbGLdm9tpLFOLkFmqKjaj+rOrkpNstsbiBNE8BgHt0D+rXlTGaNa4PjoK7PImCj69Jpuw==} 26 | 27 | snapshots: 28 | 29 | '@commercetools/http-user-agent@3.0.0': {} 30 | 31 | '@commercetools/sdk-types@0.1.2': {} 32 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/src/index.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/prefer-default-export 2 | export { default as createUserAgentMiddleware } from './user-agent' 3 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/src/user-agent.ts: -------------------------------------------------------------------------------- 1 | import createHttpUserAgent from '@commercetools/http-user-agent' 2 | import { 3 | Dispatch, 4 | Middleware, 5 | MiddlewareRequest, 6 | MiddlewareResponse, 7 | } from '@commercetools/sdk-types' 8 | 9 | type UserAgentMiddlewareOptions = { 10 | libraryName?: string; 11 | libraryVersion?: string; 12 | contactUrl?: string; 13 | contactEmail?: string; 14 | } 15 | 16 | export default function createUserAgentMiddleware( 17 | options: UserAgentMiddlewareOptions 18 | ): Middleware { 19 | const userAgent = createHttpUserAgent({ 20 | name: 'commercetools-js-sdk', 21 | ...options, 22 | }) 23 | 24 | return (next: Dispatch): Dispatch => 25 | (request: MiddlewareRequest, response: MiddlewareResponse) => { 26 | const requestWithUserAgent = { 27 | ...request, 28 | headers: { 29 | ...request.headers, 30 | 'User-Agent': userAgent, 31 | }, 32 | } 33 | next(requestWithUserAgent, response) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/tsconfig.declarations.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "isolatedModules": false 6 | }, 7 | "exclude": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx" 10 | ] 11 | } -------------------------------------------------------------------------------- /packages/sdk-middleware-user-agent/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "files": ["src/index.ts"] 4 | } -------------------------------------------------------------------------------- /packages/sdk-types/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'plugin:import/typescript', 6 | 'plugin:jest/recommended', 7 | 'prettier', 8 | 'prettier/@typescript-eslint', 9 | ], 10 | plugins: ['import', 'jest', 'prettier', '@typescript-eslint/eslint-plugin'], 11 | env: { 12 | es6: true, 13 | browser: true, 14 | jest: true, 15 | node: true, 16 | }, 17 | rules: { 18 | '@typescript-eslint/camelcase': 0, 19 | '@typescript-eslint/consistent-type-definitions': 0, 20 | '@typescript-eslint/explicit-function-return-type': 0, 21 | '@typescript-eslint/no-explicit-any': 2, 22 | '@typescript-eslint/no-use-before-define': ['error', { functions: false }], 23 | '@typescript-eslint/no-var-requires': 0, 24 | '@typescript-eslint/unbound-method': 0, 25 | 'import/no-extraneous-dependencies': 0, 26 | 'import/no-named-as-default': 0, 27 | 'import/no-unresolved': 2, 28 | }, 29 | settings: { 30 | 'import/parsers': { 31 | '@typescript-eslint/parser': ['.ts'], 32 | }, 33 | 'import/resolver': { 34 | 'eslint-import-resolver-typescript': true, 35 | typescript: {}, 36 | node: { 37 | extensions: ['.js', '.ts'], 38 | }, 39 | }, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /packages/sdk-types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @commercetools/sdk-types 2 | 3 | ## 1.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1741](https://github.com/commercetools/nodejs/pull/1741) [`dd64902`](https://github.com/commercetools/nodejs/commit/dd6490249727ee462c238b35b1e38ec89464a1d0) Thanks [@renovate](https://github.com/apps/renovate)! - Remove resolutions from dependencies. 8 | 9 | ## 1.0.0 10 | 11 | ### Major Changes 12 | 13 | - [#1930](https://github.com/commercetools/nodejs/pull/1930) [`5a56792`](https://github.com/commercetools/nodejs/commit/5a5679256a4a7e4b90bc47b945b12acb4f70b411) Thanks [@tdeekens](https://github.com/tdeekens)! - # Requires Node.js v18 or later 14 | 15 | This releases migrates packages to require Node.js v18 or later. Ideally you should be already using Node.js v20 or later. According to [Node.js Releases](https://nodejs.org/en/about/previous-releases) Node.js v18 will be in maintenance and reach End of Life by the end of April. 16 | 17 | Other than requiring Node.js v18 packages with this releases do not contain any internal breaking changes. 18 | -------------------------------------------------------------------------------- /packages/sdk-types/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sdk-types 2 | 3 |
4 |

⚠️ In Maintenance Mode ⚠️

5 |

6 | This package has been replaced by the TypeScript SDK is in maintenance mode as such this tool will no longer receive new features or bug fixes. 7 |

8 |

9 | We recommend to use the TypeScript SDK for any new implementation and plan migrating to it. 10 |

11 |
12 | 13 | TypeScript declarations for SDK packages 14 | 15 | ## Install 16 | 17 | ```bash 18 | npm install --save @commercetools/sdk-types 19 | ``` 20 | -------------------------------------------------------------------------------- /packages/sdk-types/index.ts: -------------------------------------------------------------------------------- 1 | export type JsonObject = { [key: string]: T } 2 | 3 | export type MethodType = 4 | | 'GET' 5 | | 'POST' 6 | | 'DELETE' 7 | | 'HEAD' 8 | | 'OPTIONS' 9 | | 'PUT' 10 | | 'PATCH' 11 | | 'TRACE' 12 | 13 | export type ClientRequest = { 14 | uri: string 15 | method: MethodType 16 | body?: string | JsonObject 17 | headers?: JsonObject 18 | } 19 | export type HttpErrorType = { 20 | name: string 21 | message: string 22 | code: number 23 | status: number 24 | statusCode: number 25 | originalRequest: ClientRequest 26 | body?: JsonObject 27 | headers?: JsonObject 28 | } 29 | 30 | /* Middlewares */ 31 | export type MiddlewareRequest = ClientRequest 32 | export type MiddlewareResponse = { 33 | resolve(response: JsonObject): void 34 | reject(error: JsonObject): void 35 | body?: JsonObject 36 | error?: HttpErrorType 37 | statusCode: number 38 | headers?: JsonObject 39 | request?: JsonObject 40 | } 41 | export type Dispatch = ( 42 | request: MiddlewareRequest, 43 | response: MiddlewareResponse 44 | ) => unknown 45 | export type Middleware = (next: Dispatch) => Dispatch 46 | -------------------------------------------------------------------------------- /packages/sdk-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sdk-types", 9 | "version": "1.0.1", 10 | "description": "TypeScript declarations for SDK packages", 11 | "keywords": [ 12 | "commercetools", 13 | "typescript", 14 | "sdk" 15 | ], 16 | "homepage": "https://commercetools.github.io/nodejs/", 17 | "bugs": "https://github.com/commercetools/nodejs/issues", 18 | "license": "MIT", 19 | "author": "Nicola Molinari (https://github.com/emmenko)", 20 | "typings": "./index.d.ts", 21 | "types": "./index.d.ts", 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/commercetools/nodejs.git" 25 | }, 26 | "files": [ 27 | "index.ts" 28 | ], 29 | "scripts": { 30 | "build": "exit 0", 31 | "typecheck:ts": "tsc --noEmit" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/sdk-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "files": ["index.ts"] 4 | } -------------------------------------------------------------------------------- /packages/state-importer/readme.md: -------------------------------------------------------------------------------- 1 | # state-importer 2 | 3 |
4 |

🚨 Notice of End of Life - Unmaintained 🚨

5 |

6 | Starting March 31st, 2025, we will no longer provide maintenance or updates for this CLI. After this date, this tool will no longer receive bug fixes, security patches, or new features. 7 |

8 |

9 | The last published version of this CLI will remain available through NPM. The last state of its source can be viewed at [this commit](https://github.com/commercetools/nodejs/tree/ea6e4bd89c286565d5726ffa7603ee1121a381bb). 10 |

11 |
12 | -------------------------------------------------------------------------------- /packages/sync-actions/README.md: -------------------------------------------------------------------------------- 1 | # commercetools-sync-actions 2 | 3 | Construct API update actions, for usage with `@commercetools/sdk-client`. 4 | 5 | https://commercetools.github.io/nodejs/sdk/api/syncActions 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install --save @commercetools/sync-actions 11 | ``` 12 | -------------------------------------------------------------------------------- /packages/sync-actions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publishConfig": { 3 | "access": "public" 4 | }, 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "name": "@commercetools/sync-actions", 9 | "version": "7.1.3", 10 | "description": "Build API update actions for the commercetools platform.", 11 | "keywords": [ 12 | "commercetools", 13 | "sync", 14 | "actions" 15 | ], 16 | "homepage": "https://commercetools.github.io/nodejs/", 17 | "bugs": "https://github.com/commercetools/nodejs/issues", 18 | "license": "MIT", 19 | "author": "Nicola Molinari (https://github.com/emmenko)", 20 | "main": "dist/commercetools-sync-actions.cjs.js", 21 | "module": "dist/commercetools-sync-actions.esm.js", 22 | "umd:min": "dist/commercetools-sync-actions.umd.js", 23 | "preconstruct": { 24 | "entrypoints": [ 25 | "./index.js" 26 | ], 27 | "umdName": "commercetoolsSyncActions" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/commercetools/nodejs.git" 32 | }, 33 | "files": [ 34 | "dist", 35 | "lib" 36 | ], 37 | "scripts": { 38 | "prebuild": "rimraf dist/**", 39 | "build": "exit 0;" 40 | }, 41 | "dependencies": { 42 | "fast-equals": "^2.0.0", 43 | "jsondiffpatch": "0.5.0", 44 | "lodash.flatten": "^4.4.0", 45 | "lodash.foreach": "^4.5.0", 46 | "lodash.intersection": "^4.4.0", 47 | "lodash.isequal": "^4.5.0", 48 | "lodash.isnil": "^4.0.0", 49 | "lodash.shuffle": "^4.2.0", 50 | "lodash.sortby": "^4.7.0", 51 | "lodash.uniqwith": "^4.5.0", 52 | "lodash.without": "^4.4.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/sync-actions/src/assets-actions.js: -------------------------------------------------------------------------------- 1 | import createBuildArrayActions, { 2 | ADD_ACTIONS, 3 | REMOVE_ACTIONS, 4 | CHANGE_ACTIONS, 5 | } from './utils/create-build-array-actions' 6 | 7 | function toAssetIdentifier(asset) { 8 | const assetIdentifier = asset.id 9 | ? { assetId: asset.id } 10 | : { assetKey: asset.key } 11 | return assetIdentifier 12 | } 13 | 14 | export default function actionsMapAssets(diff, oldObj, newObj) { 15 | const handler = createBuildArrayActions('assets', { 16 | [ADD_ACTIONS]: (newAsset) => ({ 17 | action: 'addAsset', 18 | asset: newAsset, 19 | }), 20 | [REMOVE_ACTIONS]: (oldAsset) => ({ 21 | action: 'removeAsset', 22 | ...toAssetIdentifier(oldAsset), 23 | }), 24 | [CHANGE_ACTIONS]: (oldAsset, newAsset) => 25 | // here we could use more atomic update actions (e.g. changeAssetName) 26 | // but for now we use the simpler approach to first remove and then 27 | // re-add the asset - which reduces the code complexity 28 | [ 29 | { 30 | action: 'removeAsset', 31 | ...toAssetIdentifier(oldAsset), 32 | }, 33 | { 34 | action: 'addAsset', 35 | asset: newAsset, 36 | }, 37 | ], 38 | }) 39 | 40 | return handler(diff, oldObj, newObj) 41 | } 42 | -------------------------------------------------------------------------------- /packages/sync-actions/src/attribute-groups.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | ActionGroup, 6 | UpdateAction, 7 | SyncActionConfig, 8 | } from 'types/sdk' 9 | import * as attributeGroupsActions from './attribute-groups-actions' 10 | import createBuildActions from './utils/create-build-actions' 11 | import createMapActionGroup from './utils/create-map-action-group' 12 | import * as diffpatcher from './utils/diffpatcher' 13 | 14 | function createAttributeGroupsMapActions( 15 | mapActionGroup: ( 16 | type: string, 17 | fn: () => Array 18 | ) => Array, 19 | syncActionConfig: SyncActionConfig 20 | ): (diff: Object, newObj: Object, oldObj: Object) => Array { 21 | return function doMapActions( 22 | diff: Object, 23 | newObj: Object, 24 | oldObj: Object 25 | ): Array { 26 | const allActions = [] 27 | allActions.push( 28 | mapActionGroup('base', (): Array => 29 | attributeGroupsActions.actionsMapBase( 30 | diff, 31 | oldObj, 32 | newObj, 33 | syncActionConfig 34 | ) 35 | ) 36 | ) 37 | allActions.push( 38 | flatten( 39 | mapActionGroup('attributes', (): Array => 40 | attributeGroupsActions.actionsMapAttributes(diff, oldObj, newObj) 41 | ) 42 | ) 43 | ) 44 | return flatten(allActions) 45 | } 46 | } 47 | 48 | export default ( 49 | actionGroupList: Array, 50 | syncActionConfig: SyncActionConfig 51 | ): SyncAction => { 52 | const mapActionGroup = createMapActionGroup(actionGroupList) 53 | const doMapActions = createAttributeGroupsMapActions( 54 | mapActionGroup, 55 | syncActionConfig 56 | ) 57 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 58 | return { buildActions } 59 | } 60 | -------------------------------------------------------------------------------- /packages/sync-actions/src/cart-discounts-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeIsActive', key: 'isActive' }, 5 | { action: 'changeName', key: 'name' }, 6 | { action: 'changeCartPredicate', key: 'cartPredicate' }, 7 | { action: 'changeSortOrder', key: 'sortOrder' }, 8 | { action: 'changeValue', key: 'value' }, 9 | { action: 'changeRequiresDiscountCode', key: 'requiresDiscountCode' }, 10 | { action: 'changeTarget', key: 'target' }, 11 | { action: 'setDescription', key: 'description' }, 12 | { action: 'setValidFrom', key: 'validFrom' }, 13 | { action: 'setValidUntil', key: 'validUntil' }, 14 | { action: 'changeStackingMode', key: 'stackingMode' }, 15 | { action: 'setKey', key: 'key' }, 16 | ] 17 | 18 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 19 | return buildBaseAttributesActions({ 20 | actions: baseActionsList, 21 | diff, 22 | oldObj, 23 | newObj, 24 | shouldOmitEmptyString: config.shouldOmitEmptyString, 25 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 26 | shouldPreventUnsettingRequiredFields: 27 | config.shouldPreventUnsettingRequiredFields, 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /packages/sync-actions/src/cart-discounts.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import actionsMapCustom from './utils/action-map-custom' 5 | import { actionsMapBase } from './cart-discounts-actions' 6 | import combineValidityActions from './utils/combine-validity-actions' 7 | import * as diffpatcher from './utils/diffpatcher' 8 | 9 | export const actionGroups = ['base', 'custom'] 10 | 11 | function createCartDiscountsMapActions(mapActionGroup, syncActionConfig) { 12 | return function doMapActions(diff, newObj, oldObj) { 13 | const allActions = [] 14 | 15 | allActions.push( 16 | mapActionGroup('base', () => 17 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 18 | ) 19 | ) 20 | 21 | allActions.push( 22 | mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) 23 | ) 24 | 25 | return combineValidityActions(flatten(allActions)) 26 | } 27 | } 28 | 29 | export default (actionGroupList, syncActionConfig = {}) => { 30 | const mapActionGroup = createMapActionGroup(actionGroupList) 31 | const doMapActions = createCartDiscountsMapActions( 32 | mapActionGroup, 33 | syncActionConfig 34 | ) 35 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 36 | return { buildActions } 37 | } 38 | -------------------------------------------------------------------------------- /packages/sync-actions/src/category-actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | buildBaseAttributesActions, 3 | buildReferenceActions, 4 | } from './utils/common-actions' 5 | 6 | export const baseActionsList = [ 7 | { action: 'changeName', key: 'name' }, 8 | { action: 'changeSlug', key: 'slug' }, 9 | { action: 'setDescription', key: 'description' }, 10 | { action: 'changeOrderHint', key: 'orderHint' }, 11 | { action: 'setExternalId', key: 'externalId' }, 12 | { action: 'setKey', key: 'key' }, 13 | ] 14 | 15 | export const metaActionsList = [ 16 | { action: 'setMetaTitle', key: 'metaTitle' }, 17 | { action: 'setMetaKeywords', key: 'metaKeywords' }, 18 | { action: 'setMetaDescription', key: 'metaDescription' }, 19 | ] 20 | 21 | export const referenceActionsList = [{ action: 'changeParent', key: 'parent' }] 22 | 23 | /** 24 | * SYNC FUNCTIONS 25 | */ 26 | 27 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 28 | return buildBaseAttributesActions({ 29 | actions: baseActionsList, 30 | diff, 31 | oldObj, 32 | newObj, 33 | shouldOmitEmptyString: config.shouldOmitEmptyString, 34 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 35 | shouldPreventUnsettingRequiredFields: 36 | config.shouldPreventUnsettingRequiredFields, 37 | }) 38 | } 39 | 40 | export function actionsMapReferences(diff, oldObj, newObj) { 41 | return buildReferenceActions({ 42 | actions: referenceActionsList, 43 | diff, 44 | oldObj, 45 | newObj, 46 | }) 47 | } 48 | 49 | export function actionsMapMeta(diff, oldObj, newObj) { 50 | return buildBaseAttributesActions({ 51 | actions: metaActionsList, 52 | diff, 53 | oldObj, 54 | newObj, 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /packages/sync-actions/src/channels-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeKey', key: 'key' }, 5 | { action: 'changeName', key: 'name' }, 6 | { action: 'changeDescription', key: 'description' }, 7 | { action: 'setAddress', key: 'address' }, 8 | { action: 'setGeoLocation', key: 'geoLocation' }, 9 | { action: 'setRoles', key: 'roles' }, 10 | ] 11 | 12 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 13 | return buildBaseAttributesActions({ 14 | actions: baseActionsList, 15 | diff, 16 | oldObj, 17 | newObj, 18 | shouldOmitEmptyString: config.shouldOmitEmptyString, 19 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 20 | shouldPreventUnsettingRequiredFields: 21 | config.shouldPreventUnsettingRequiredFields, 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /packages/sync-actions/src/channels.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import actionsMapCustom from './utils/action-map-custom' 5 | import { actionsMapBase } from './channels-actions' 6 | import * as diffpatcher from './utils/diffpatcher' 7 | 8 | export const actionGroups = ['base', 'custom'] 9 | 10 | function createChannelsMapActions(mapActionGroup, syncActionConfig) { 11 | return function doMapActions(diff, newObj, oldObj) { 12 | const allActions = [] 13 | 14 | allActions.push( 15 | mapActionGroup('base', () => 16 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 17 | ) 18 | ) 19 | 20 | allActions.push( 21 | mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) 22 | ) 23 | 24 | return flatten(allActions) 25 | } 26 | } 27 | 28 | export default (actionGroupList, syncActionConfig = {}) => { 29 | const mapActionGroup = createMapActionGroup(actionGroupList) 30 | const doMapActions = createChannelsMapActions( 31 | mapActionGroup, 32 | syncActionConfig 33 | ) 34 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 35 | return { buildActions } 36 | } 37 | -------------------------------------------------------------------------------- /packages/sync-actions/src/customer-group-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeName', key: 'name' }, 5 | { action: 'setKey', key: 'key' }, 6 | ] 7 | 8 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 9 | return buildBaseAttributesActions({ 10 | actions: baseActionsList, 11 | diff, 12 | oldObj, 13 | newObj, 14 | shouldOmitEmptyString: config.shouldOmitEmptyString, 15 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 16 | shouldPreventUnsettingRequiredFields: 17 | config.shouldPreventUnsettingRequiredFields, 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/sync-actions/src/customer-group.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import actionsMapCustom from './utils/action-map-custom' 5 | import { actionsMapBase } from './customer-group-actions' 6 | import * as diffpatcher from './utils/diffpatcher' 7 | 8 | export const actionGroups = ['base', 'custom'] 9 | 10 | function createCustomerGroupMapActions(mapActionGroup, syncActionConfig) { 11 | return function doMapActions(diff, newObj, oldObj) { 12 | const allActions = [] 13 | 14 | allActions.push( 15 | mapActionGroup('base', () => 16 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 17 | ) 18 | ) 19 | 20 | allActions.push( 21 | mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) 22 | ) 23 | 24 | return flatten(allActions) 25 | } 26 | } 27 | 28 | export default (actionGroupList, syncActionConfig = {}) => { 29 | const mapActionGroup = createMapActionGroup(actionGroupList) 30 | const doMapActions = createCustomerGroupMapActions( 31 | mapActionGroup, 32 | syncActionConfig 33 | ) 34 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 35 | return { buildActions } 36 | } 37 | -------------------------------------------------------------------------------- /packages/sync-actions/src/discount-codes-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeIsActive', key: 'isActive' }, 5 | { action: 'setName', key: 'name' }, 6 | { action: 'setDescription', key: 'description' }, 7 | { action: 'setKey', key: 'key' }, 8 | { action: 'setCartPredicate', key: 'cartPredicate' }, 9 | { action: 'setMaxApplications', key: 'maxApplications' }, 10 | { 11 | action: 'setMaxApplicationsPerCustomer', 12 | key: 'maxApplicationsPerCustomer', 13 | }, 14 | { action: 'changeCartDiscounts', key: 'cartDiscounts' }, 15 | { action: 'setValidFrom', key: 'validFrom' }, 16 | { action: 'setValidUntil', key: 'validUntil' }, 17 | { action: 'changeGroups', key: 'groups' }, 18 | ] 19 | 20 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 21 | return buildBaseAttributesActions({ 22 | actions: baseActionsList, 23 | diff, 24 | oldObj, 25 | newObj, 26 | shouldOmitEmptyString: config.shouldOmitEmptyString, 27 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 28 | shouldPreventUnsettingRequiredFields: 29 | config.shouldPreventUnsettingRequiredFields, 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /packages/sync-actions/src/discount-codes.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import actionsMapCustom from './utils/action-map-custom' 5 | import { actionsMapBase } from './discount-codes-actions' 6 | import combineValidityActions from './utils/combine-validity-actions' 7 | import * as diffpatcher from './utils/diffpatcher' 8 | 9 | export const actionGroups = ['base', 'custom'] 10 | 11 | function createDiscountCodesMapActions(mapActionGroup, syncActionConfig) { 12 | return function doMapActions(diff, newObj, oldObj) { 13 | const allActions = [] 14 | allActions.push( 15 | mapActionGroup('base', () => 16 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 17 | ) 18 | ) 19 | allActions.push( 20 | mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) 21 | ) 22 | return combineValidityActions(flatten(allActions)) 23 | } 24 | } 25 | 26 | export default (actionGroupList, syncActionConfig = {}) => { 27 | // actionGroupList contains information about which action groups 28 | // are allowed or ignored 29 | 30 | // createMapActionGroup returns function 'mapActionGroup' that takes params: 31 | // - action group name 32 | // - callback function that should return a list of actions that correspond 33 | // to the for the action group 34 | 35 | // this resulting function mapActionGroup will call the callback function 36 | // for allowed action groups and return the return value of the callback 37 | // It will return an empty array for ignored action groups 38 | const mapActionGroup = createMapActionGroup(actionGroupList) 39 | const doMapActions = createDiscountCodesMapActions( 40 | mapActionGroup, 41 | syncActionConfig 42 | ) 43 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 44 | return { buildActions } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sync-actions/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as createSyncCategories } from './categories' 2 | export { default as createSyncCustomers } from './customers' 3 | export { default as createSyncInventories } from './inventories' 4 | export { default as createSyncProducts } from './products' 5 | export { default as createSyncOrders } from './orders' 6 | export { default as createSyncRecurringOrders } from './recurring-orders' 7 | export { default as createSyncProductDiscounts } from './product-discounts' 8 | export { default as createSyncDiscountCodes } from './discount-codes' 9 | export { default as createSyncCustomerGroup } from './customer-group' 10 | export { default as createSyncCartDiscounts } from './cart-discounts' 11 | export { default as createSyncTaxCategories } from './tax-categories' 12 | export { default as createSyncZones } from './zones' 13 | export { default as createSyncShippingMethods } from './shipping-methods' 14 | export { default as createSyncProductTypes } from './product-types' 15 | export { default as createSyncStates } from './states' 16 | export { default as createSyncChannels } from './channels' 17 | export { default as createSyncTypes } from './types' 18 | export { default as createSyncProjects } from './projects' 19 | export { default as createSyncStores } from './stores' 20 | export { default as createSyncProductSelections } from './product-selections' 21 | export { default as createSyncStandalonePrices } from './prices' 22 | export { default as createSyncAttributeGroups } from './attribute-groups' 23 | -------------------------------------------------------------------------------- /packages/sync-actions/src/inventory-actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | buildBaseAttributesActions, 3 | buildReferenceActions, 4 | } from './utils/common-actions' 5 | 6 | export const baseActionsList = [ 7 | { action: 'changeQuantity', key: 'quantityOnStock', actionKey: 'quantity' }, 8 | { action: 'setRestockableInDays', key: 'restockableInDays' }, 9 | { action: 'setExpectedDelivery', key: 'expectedDelivery' }, 10 | ] 11 | 12 | export const referenceActionsList = [ 13 | { action: 'setSupplyChannel', key: 'supplyChannel' }, 14 | ] 15 | 16 | /** 17 | * SYNC FUNCTIONS 18 | */ 19 | 20 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 21 | return buildBaseAttributesActions({ 22 | actions: baseActionsList, 23 | diff, 24 | oldObj, 25 | newObj, 26 | shouldOmitEmptyString: config.shouldOmitEmptyString, 27 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 28 | shouldPreventUnsettingRequiredFields: 29 | config.shouldPreventUnsettingRequiredFields, 30 | }) 31 | } 32 | 33 | export function actionsMapReferences(diff, oldObj, newObj) { 34 | return buildReferenceActions({ 35 | actions: referenceActionsList, 36 | diff, 37 | oldObj, 38 | newObj, 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /packages/sync-actions/src/prices-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeValue', key: 'value' }, 5 | { action: 'setDiscountedPrice', key: 'discounted' }, 6 | // TODO: Later add more accurate actions `addPriceTier`, `removePriceTier` 7 | { action: 'setPriceTiers', key: 'tiers' }, 8 | { action: 'setKey', key: 'key' }, 9 | { action: 'setValidFrom', key: 'validFrom' }, 10 | { action: 'setValidUntil', key: 'validUntil' }, 11 | { action: 'changeActive', key: 'active' }, 12 | ] 13 | 14 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 15 | return buildBaseAttributesActions({ 16 | actions: baseActionsList, 17 | diff, 18 | oldObj, 19 | newObj, 20 | shouldOmitEmptyString: config.shouldOmitEmptyString, 21 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 22 | shouldPreventUnsettingRequiredFields: 23 | config.shouldPreventUnsettingRequiredFields, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /packages/sync-actions/src/prices.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { 3 | SyncAction, 4 | SyncActionConfig, 5 | ActionGroup, 6 | UpdateAction, 7 | } from 'types/sdk' 8 | import createBuildActions from './utils/create-build-actions' 9 | import createMapActionGroup from './utils/create-map-action-group' 10 | import actionsMapCustom from './utils/action-map-custom' 11 | import * as pricesActions from './prices-actions' 12 | import * as diffpatcher from './utils/diffpatcher' 13 | import combineValidityActions from './utils/combine-validity-actions' 14 | 15 | const actionGroups = ['base', 'custom'] 16 | 17 | function createPriceMapActions( 18 | mapActionGroup: Function, 19 | syncActionConfig: SyncActionConfig 20 | ): ( 21 | diff: Object, 22 | newObj: Object, 23 | oldObj: Object, 24 | options: Object 25 | ) => Array { 26 | return function doMapActions( 27 | diff: Object, 28 | newObj: Object, 29 | oldObj: Object 30 | ): Array { 31 | const baseActions = mapActionGroup('base', (): Array => 32 | pricesActions.actionsMapBase(diff, oldObj, newObj, syncActionConfig) 33 | ) 34 | 35 | const customActions = mapActionGroup('custom', (): Array => 36 | actionsMapCustom(diff, newObj, oldObj) 37 | ) 38 | 39 | return combineValidityActions([...baseActions, ...customActions]) 40 | } 41 | } 42 | 43 | export default ( 44 | actionGroupList: Array, 45 | syncActionConfig: SyncActionConfig 46 | ): SyncAction => { 47 | const mapActionGroup = createMapActionGroup(actionGroupList) 48 | const doMapActions = createPriceMapActions(mapActionGroup, syncActionConfig) 49 | 50 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 51 | 52 | return { buildActions } 53 | } 54 | 55 | export { actionGroups } 56 | -------------------------------------------------------------------------------- /packages/sync-actions/src/product-discounts-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeIsActive', key: 'isActive' }, 5 | { action: 'changeName', key: 'name' }, 6 | { action: 'changePredicate', key: 'predicate' }, 7 | { action: 'changeSortOrder', key: 'sortOrder' }, 8 | { action: 'changeValue', key: 'value' }, 9 | { action: 'setDescription', key: 'description' }, 10 | { action: 'setValidFrom', key: 'validFrom' }, 11 | { action: 'setValidUntil', key: 'validUntil' }, 12 | { action: 'setKey', key: 'key' }, 13 | ] 14 | 15 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 16 | return buildBaseAttributesActions({ 17 | actions: baseActionsList, 18 | diff, 19 | oldObj, 20 | newObj, 21 | shouldOmitEmptyString: config.shouldOmitEmptyString, 22 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 23 | shouldPreventUnsettingRequiredFields: 24 | config.shouldPreventUnsettingRequiredFields, 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /packages/sync-actions/src/product-discounts.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import { actionsMapBase } from './product-discounts-actions' 5 | import combineValidityActions from './utils/combine-validity-actions' 6 | import * as diffpatcher from './utils/diffpatcher' 7 | 8 | export const actionGroups = ['base'] 9 | 10 | function createProductDiscountsMapActions(mapActionGroup, syncActionConfig) { 11 | return function doMapActions(diff, newObj, oldObj) { 12 | const allActions = [] 13 | 14 | allActions.push( 15 | mapActionGroup('base', () => 16 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 17 | ) 18 | ) 19 | return combineValidityActions(flatten(allActions)) 20 | } 21 | } 22 | 23 | export default (actionGroupList, syncActionConfig = {}) => { 24 | const mapActionGroup = createMapActionGroup(actionGroupList) 25 | const doMapActions = createProductDiscountsMapActions( 26 | mapActionGroup, 27 | syncActionConfig 28 | ) 29 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 30 | return { buildActions } 31 | } 32 | -------------------------------------------------------------------------------- /packages/sync-actions/src/product-selections-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeName', key: 'name' }, 5 | { action: 'setKey', key: 'key' }, 6 | ] 7 | 8 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 9 | return buildBaseAttributesActions({ 10 | actions: baseActionsList, 11 | diff, 12 | oldObj, 13 | newObj, 14 | shouldOmitEmptyString: config.shouldOmitEmptyString, 15 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 16 | shouldPreventUnsettingRequiredFields: 17 | config.shouldPreventUnsettingRequiredFields, 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/sync-actions/src/product-selections.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { SyncAction, UpdateAction, ActionGroup } from 'types/sdk' 4 | import createBuildActions from './utils/create-build-actions' 5 | import createMapActionGroup from './utils/create-map-action-group' 6 | import actionsMapCustom from './utils/action-map-custom' 7 | import * as productSelectionsActions from './product-selections-actions' 8 | import * as diffpatcher from './utils/diffpatcher' 9 | 10 | export const actionGroups = ['base'] 11 | 12 | function createProductSelectionsMapActions( 13 | mapActionGroup: ( 14 | type: string, 15 | fn: () => Array 16 | ) => Array 17 | ): ( 18 | diff: Object, 19 | next: Object, 20 | previous: Object, 21 | options: Object 22 | ) => Array { 23 | return function doMapActions( 24 | diff: Object, 25 | next: Object, 26 | previous: Object 27 | ): Array { 28 | const allActions = [] 29 | allActions.push( 30 | mapActionGroup('base', (): Array => 31 | productSelectionsActions.actionsMapBase(diff, previous, next) 32 | ) 33 | ) 34 | allActions.push( 35 | mapActionGroup('custom', (): Array => 36 | actionsMapCustom(diff, next, previous) 37 | ) 38 | ) 39 | 40 | return flatten(allActions) 41 | } 42 | } 43 | 44 | export default (actionGroupList: Array): SyncAction => { 45 | const mapActionGroup = createMapActionGroup(actionGroupList) 46 | const doMapActions = createProductSelectionsMapActions(mapActionGroup) 47 | const onBeforeApplyingDiff = null 48 | const buildActions = createBuildActions( 49 | diffpatcher.diff, 50 | doMapActions, 51 | onBeforeApplyingDiff 52 | ) 53 | 54 | return { buildActions } 55 | } 56 | -------------------------------------------------------------------------------- /packages/sync-actions/src/projects.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | import createBuildActions from './utils/create-build-actions' 3 | import createMapActionGroup from './utils/create-map-action-group' 4 | import { 5 | actionsMapBase, 6 | actionsMapBusinessUnit, 7 | actionsMapSearchIndexingConfiguration, 8 | } from './projects-actions' 9 | import * as diffpatcher from './utils/diffpatcher' 10 | 11 | export const actionGroups = [ 12 | 'base', 13 | 'businessUnit', 14 | 'searchIndexingConfiguration', 15 | ] 16 | 17 | function createChannelsMapActions(mapActionGroup, syncActionConfig) { 18 | return function doMapActions(diff, newObj, oldObj) { 19 | const allActions = [] 20 | 21 | allActions.push( 22 | mapActionGroup('base', () => 23 | actionsMapBase(diff, oldObj, newObj, syncActionConfig) 24 | ) 25 | ) 26 | 27 | allActions.push( 28 | mapActionGroup('businessUnit', () => 29 | actionsMapBusinessUnit(diff, oldObj, newObj) 30 | ) 31 | ) 32 | 33 | allActions.push( 34 | mapActionGroup('searchIndexingConfiguration', () => 35 | actionsMapSearchIndexingConfiguration(diff, oldObj, newObj) 36 | ) 37 | ) 38 | 39 | return flatten(allActions) 40 | } 41 | } 42 | 43 | export default (actionGroupList, syncActionConfig = {}) => { 44 | const mapActionGroup = createMapActionGroup(actionGroupList) 45 | const doMapActions = createChannelsMapActions( 46 | mapActionGroup, 47 | syncActionConfig 48 | ) 49 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 50 | return { buildActions } 51 | } 52 | -------------------------------------------------------------------------------- /packages/sync-actions/src/quote-requests-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeQuoteRequestState', key: 'quoteRequestState' }, 5 | { action: 'transitionState', key: 'state' }, 6 | ] 7 | 8 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 9 | return buildBaseAttributesActions({ 10 | actions: baseActionsList, 11 | diff, 12 | oldObj, 13 | newObj, 14 | shouldOmitEmptyString: config.shouldOmitEmptyString, 15 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 16 | shouldPreventUnsettingRequiredFields: 17 | config.shouldPreventUnsettingRequiredFields, 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /packages/sync-actions/src/quote-requests.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | SyncActionConfig, 6 | ActionGroup, 7 | UpdateAction, 8 | } from 'types/sdk' 9 | import createBuildActions from './utils/create-build-actions' 10 | import createMapActionGroup from './utils/create-map-action-group' 11 | import actionsMapCustom from './utils/action-map-custom' 12 | import * as QuoteRequestsActions from './quote-requests-actions' 13 | import * as diffpatcher from './utils/diffpatcher' 14 | 15 | const actionGroups = ['base', 'custom'] 16 | 17 | function createQuoteRequestsMapActions( 18 | mapActionGroup: Function, 19 | syncActionConfig: SyncActionConfig 20 | ): ( 21 | diff: Object, 22 | newObj: Object, 23 | oldObj: Object, 24 | options: Object 25 | ) => Array { 26 | return function doMapActions( 27 | diff: Object, 28 | newObj: Object, 29 | oldObj: Object 30 | ): Array { 31 | const allActions = [] 32 | 33 | allActions.push( 34 | mapActionGroup('base', (): Array => 35 | QuoteRequestsActions.actionsMapBase( 36 | diff, 37 | oldObj, 38 | newObj, 39 | syncActionConfig 40 | ) 41 | ) 42 | ) 43 | 44 | allActions.push( 45 | mapActionGroup('custom', (): Array => 46 | actionsMapCustom(diff, newObj, oldObj) 47 | ) 48 | ) 49 | 50 | return flatten(allActions) 51 | } 52 | } 53 | 54 | export default ( 55 | actionGroupList: Array, 56 | syncActionConfig: SyncActionConfig 57 | ): SyncAction => { 58 | const mapActionGroup = createMapActionGroup(actionGroupList) 59 | const doMapActions = createQuoteRequestsMapActions( 60 | mapActionGroup, 61 | syncActionConfig 62 | ) 63 | 64 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 65 | 66 | return { buildActions } 67 | } 68 | 69 | export { actionGroups } 70 | -------------------------------------------------------------------------------- /packages/sync-actions/src/quotes-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeQuoteState', key: 'quoteState' }, 5 | { action: 'requestQuoteRenegotiation', key: 'buyerComment' }, 6 | { action: 'transitionState', key: 'state' }, 7 | ] 8 | 9 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 10 | return buildBaseAttributesActions({ 11 | actions: baseActionsList, 12 | diff, 13 | oldObj, 14 | newObj, 15 | shouldOmitEmptyString: config.shouldOmitEmptyString, 16 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 17 | shouldPreventUnsettingRequiredFields: 18 | config.shouldPreventUnsettingRequiredFields, 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /packages/sync-actions/src/quotes.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | SyncActionConfig, 6 | ActionGroup, 7 | UpdateAction, 8 | } from 'types/sdk' 9 | import createBuildActions from './utils/create-build-actions' 10 | import createMapActionGroup from './utils/create-map-action-group' 11 | import actionsMapCustom from './utils/action-map-custom' 12 | import * as QuotesActions from './quotes-actions' 13 | import * as diffpatcher from './utils/diffpatcher' 14 | 15 | const actionGroups = ['base', 'custom'] 16 | 17 | function createQuotesMapActions( 18 | mapActionGroup: Function, 19 | syncActionConfig: SyncActionConfig 20 | ): ( 21 | diff: Object, 22 | newObj: Object, 23 | oldObj: Object, 24 | options: Object 25 | ) => Array { 26 | return function doMapActions( 27 | diff: Object, 28 | newObj: Object, 29 | oldObj: Object 30 | ): Array { 31 | const allActions = [] 32 | 33 | allActions.push( 34 | mapActionGroup('base', (): Array => 35 | QuotesActions.actionsMapBase(diff, oldObj, newObj, syncActionConfig) 36 | ) 37 | ) 38 | 39 | allActions.push( 40 | mapActionGroup('custom', (): Array => 41 | actionsMapCustom(diff, newObj, oldObj) 42 | ) 43 | ) 44 | 45 | return flatten(allActions) 46 | } 47 | } 48 | 49 | export default ( 50 | actionGroupList: Array, 51 | syncActionConfig: SyncActionConfig 52 | ): SyncAction => { 53 | const mapActionGroup = createMapActionGroup(actionGroupList) 54 | const doMapActions = createQuotesMapActions(mapActionGroup, syncActionConfig) 55 | 56 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 57 | 58 | return { buildActions } 59 | } 60 | 61 | export { actionGroups } 62 | -------------------------------------------------------------------------------- /packages/sync-actions/src/recurring-orders-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'setKey', key: 'key' }, 5 | { action: 'setRecurringOrderState', key: 'recurringOrderState' }, 6 | { action: 'transitionState', key: 'state' }, 7 | ] 8 | 9 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 10 | return buildBaseAttributesActions({ 11 | actions: baseActionsList, 12 | diff, 13 | oldObj, 14 | newObj, 15 | shouldOmitEmptyString: config.shouldOmitEmptyString, 16 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 17 | shouldPreventUnsettingRequiredFields: 18 | config.shouldPreventUnsettingRequiredFields, 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /packages/sync-actions/src/recurring-orders.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | SyncActionConfig, 6 | ActionGroup, 7 | UpdateAction, 8 | } from 'types/sdk' 9 | import createBuildActions from './utils/create-build-actions' 10 | import createMapActionGroup from './utils/create-map-action-group' 11 | import actionsMapCustom from './utils/action-map-custom' 12 | import * as RecurringOrdersActions from './recurring-orders-actions' 13 | import * as diffpatcher from './utils/diffpatcher' 14 | 15 | const actionGroups = ['base', 'custom'] 16 | 17 | function createRecurringOrdersMapActions( 18 | mapActionGroup: Function, 19 | syncActionConfig: SyncActionConfig 20 | ): ( 21 | diff: Object, 22 | newObj: Object, 23 | oldObj: Object, 24 | options: Object 25 | ) => Array { 26 | return function doMapActions( 27 | diff: Object, 28 | newObj: Object, 29 | oldObj: Object 30 | ): Array { 31 | const allActions = [] 32 | 33 | allActions.push( 34 | mapActionGroup('base', (): Array => 35 | RecurringOrdersActions.actionsMapBase( 36 | diff, 37 | oldObj, 38 | newObj, 39 | syncActionConfig 40 | ) 41 | ) 42 | ) 43 | 44 | allActions.push( 45 | mapActionGroup('custom', (): Array => 46 | actionsMapCustom(diff, newObj, oldObj) 47 | ) 48 | ) 49 | 50 | return flatten(allActions) 51 | } 52 | } 53 | 54 | export default ( 55 | actionGroupList: Array, 56 | syncActionConfig: SyncActionConfig 57 | ): SyncAction => { 58 | const mapActionGroup = createMapActionGroup(actionGroupList) 59 | const doMapActions = createRecurringOrdersMapActions( 60 | mapActionGroup, 61 | syncActionConfig 62 | ) 63 | 64 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 65 | 66 | return { buildActions } 67 | } 68 | 69 | export { actionGroups } 70 | -------------------------------------------------------------------------------- /packages/sync-actions/src/staged-quotes-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'changeStagedQuoteState', key: 'stagedQuoteState' }, 5 | { action: 'setSellerComment', key: 'sellerComment' }, 6 | { action: 'setValidTo', key: 'validTo' }, 7 | { action: 'transitionState', key: 'state' }, 8 | ] 9 | 10 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 11 | return buildBaseAttributesActions({ 12 | actions: baseActionsList, 13 | diff, 14 | oldObj, 15 | newObj, 16 | shouldOmitEmptyString: config.shouldOmitEmptyString, 17 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 18 | shouldPreventUnsettingRequiredFields: 19 | config.shouldPreventUnsettingRequiredFields, 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /packages/sync-actions/src/staged-quotes.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | SyncActionConfig, 6 | ActionGroup, 7 | UpdateAction, 8 | } from 'types/sdk' 9 | import createBuildActions from './utils/create-build-actions' 10 | import createMapActionGroup from './utils/create-map-action-group' 11 | import actionsMapCustom from './utils/action-map-custom' 12 | import * as StagedQuotesActions from './staged-quotes-actions' 13 | import * as diffpatcher from './utils/diffpatcher' 14 | 15 | const actionGroups = ['base', 'custom'] 16 | 17 | function createStagedQuotesMapActions( 18 | mapActionGroup: Function, 19 | syncActionConfig: SyncActionConfig 20 | ): ( 21 | diff: Object, 22 | newObj: Object, 23 | oldObj: Object, 24 | options: Object 25 | ) => Array { 26 | return function doMapActions( 27 | diff: Object, 28 | newObj: Object, 29 | oldObj: Object 30 | ): Array { 31 | const allActions = [] 32 | 33 | allActions.push( 34 | mapActionGroup('base', (): Array => 35 | StagedQuotesActions.actionsMapBase( 36 | diff, 37 | oldObj, 38 | newObj, 39 | syncActionConfig 40 | ) 41 | ) 42 | ) 43 | 44 | allActions.push( 45 | mapActionGroup('custom', (): Array => 46 | actionsMapCustom(diff, newObj, oldObj) 47 | ) 48 | ) 49 | 50 | return flatten(allActions) 51 | } 52 | } 53 | 54 | export default ( 55 | actionGroupList: Array, 56 | syncActionConfig: SyncActionConfig 57 | ): SyncAction => { 58 | const mapActionGroup = createMapActionGroup(actionGroupList) 59 | const doMapActions = createStagedQuotesMapActions( 60 | mapActionGroup, 61 | syncActionConfig 62 | ) 63 | 64 | const buildActions = createBuildActions(diffpatcher.diff, doMapActions) 65 | 66 | return { buildActions } 67 | } 68 | 69 | export { actionGroups } 70 | -------------------------------------------------------------------------------- /packages/sync-actions/src/state-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | import createBuildArrayActions, { 3 | ADD_ACTIONS, 4 | REMOVE_ACTIONS, 5 | } from './utils/create-build-array-actions' 6 | 7 | export const baseActionsList = [ 8 | { action: 'changeKey', key: 'key' }, 9 | { action: 'setName', key: 'name' }, 10 | { action: 'setDescription', key: 'description' }, 11 | { action: 'changeType', key: 'type' }, 12 | { action: 'changeInitial', key: 'initial' }, 13 | { action: 'setTransitions', key: 'transitions' }, 14 | ] 15 | 16 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 17 | return buildBaseAttributesActions({ 18 | actions: baseActionsList, 19 | diff, 20 | oldObj, 21 | newObj, 22 | shouldOmitEmptyString: config.shouldOmitEmptyString, 23 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 24 | shouldPreventUnsettingRequiredFields: 25 | config.shouldPreventUnsettingRequiredFields, 26 | }) 27 | } 28 | 29 | export function actionsMapRoles(diff, oldObj, newObj) { 30 | const buildArrayActions = createBuildArrayActions('roles', { 31 | [ADD_ACTIONS]: (newRole) => ({ 32 | action: 'addRoles', 33 | roles: newRole, 34 | }), 35 | [REMOVE_ACTIONS]: (oldRole) => ({ 36 | action: 'removeRoles', 37 | roles: oldRole, 38 | }), 39 | }) 40 | 41 | return buildArrayActions(diff, oldObj, newObj) 42 | } 43 | -------------------------------------------------------------------------------- /packages/sync-actions/src/stores-actions.js: -------------------------------------------------------------------------------- 1 | import { buildBaseAttributesActions } from './utils/common-actions' 2 | 3 | export const baseActionsList = [ 4 | { action: 'setName', key: 'name' }, 5 | { action: 'setLanguages', key: 'languages' }, 6 | { action: 'setDistributionChannels', key: 'distributionChannels' }, 7 | { action: 'setSupplyChannels', key: 'supplyChannels' }, 8 | ] 9 | 10 | export function actionsMapBase(diff, oldObj, newObj, config = {}) { 11 | return buildBaseAttributesActions({ 12 | actions: baseActionsList, 13 | diff, 14 | oldObj, 15 | newObj, 16 | shouldOmitEmptyString: config.shouldOmitEmptyString, 17 | shouldUnsetOmittedProperties: config.shouldUnsetOmittedProperties, 18 | shouldPreventUnsettingRequiredFields: 19 | config.shouldPreventUnsettingRequiredFields, 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /packages/sync-actions/src/stores.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import flatten from 'lodash.flatten' 3 | import type { 4 | SyncAction, 5 | UpdateAction, 6 | ActionGroup, 7 | SyncActionConfig, 8 | } from 'types/sdk' 9 | import createBuildActions from './utils/create-build-actions' 10 | import createMapActionGroup from './utils/create-map-action-group' 11 | import actionsMapCustom from './utils/action-map-custom' 12 | import * as storesActions from './stores-actions' 13 | import * as diffpatcher from './utils/diffpatcher' 14 | 15 | export const actionGroups = ['base'] 16 | 17 | function createStoresMapActions( 18 | mapActionGroup: ( 19 | type: string, 20 | fn: () => Array 21 | ) => Array 22 | ): ( 23 | diff: Object, 24 | next: Object, 25 | previous: Object, 26 | options: Object 27 | ) => Array { 28 | return function doMapActions( 29 | diff: Object, 30 | next: Object, 31 | previous: Object 32 | ): Array { 33 | const allActions = [] 34 | allActions.push( 35 | mapActionGroup('base', (): Array => 36 | storesActions.actionsMapBase(diff, previous, next) 37 | ) 38 | ) 39 | allActions.push( 40 | mapActionGroup('custom', (): Array => 41 | actionsMapCustom(diff, next, previous) 42 | ) 43 | ) 44 | 45 | return flatten(allActions) 46 | } 47 | } 48 | 49 | export default ( 50 | actionGroupList: Array, 51 | options: SyncActionConfig = {} 52 | ): SyncAction => { 53 | const mapActionGroup = createMapActionGroup(actionGroupList) 54 | const doMapActions = createStoresMapActions(mapActionGroup) 55 | const onBeforeApplyingDiff = null 56 | const buildActions = createBuildActions( 57 | diffpatcher.diff, 58 | doMapActions, 59 | onBeforeApplyingDiff, 60 | options 61 | ) 62 | 63 | return { buildActions } 64 | } 65 | -------------------------------------------------------------------------------- /packages/sync-actions/src/types.js: -------------------------------------------------------------------------------- 1 | import flatten from 'lodash.flatten' 2 | 3 | import createBuildActions from './utils/create-build-actions' 4 | import createMapActionGroup from './utils/create-map-action-group' 5 | import * as typeActions from './types-actions' 6 | import * as diffPatcher from './utils/diffpatcher' 7 | import findMatchingPairs from './utils/find-matching-pairs' 8 | 9 | const actionGroups = ['base', 'fieldDefinitions'] 10 | 11 | function createTypeMapActions(mapActionGroup, syncActionConfig) { 12 | return function doMapActions(diff, next, previous) { 13 | const allActions = [] 14 | allActions.push( 15 | mapActionGroup('base', () => 16 | typeActions.actionsMapBase(diff, previous, next, syncActionConfig) 17 | ), 18 | mapActionGroup('fieldDefinitions', () => 19 | typeActions.actionsMapFieldDefinitions( 20 | diff.fieldDefinitions, 21 | previous.fieldDefinitions, 22 | next.fieldDefinitions, 23 | findMatchingPairs( 24 | diff.fieldDefinitions, 25 | previous.fieldDefinitions, 26 | next.fieldDefinitions, 27 | 'name' 28 | ) 29 | ) 30 | ) 31 | ) 32 | return flatten(allActions) 33 | } 34 | } 35 | 36 | export default (actionGroupList, syncActionConfig) => { 37 | const mapActionGroup = createMapActionGroup(actionGroupList) 38 | const doMapActions = createTypeMapActions(mapActionGroup, syncActionConfig) 39 | const buildActions = createBuildActions(diffPatcher.diff, doMapActions) 40 | return { buildActions } 41 | } 42 | 43 | export { actionGroups } 44 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/clone.js: -------------------------------------------------------------------------------- 1 | export default function clone(obj) { 2 | return JSON.parse(JSON.stringify(obj)) 3 | } 4 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/combine-validity-actions.js: -------------------------------------------------------------------------------- 1 | const validityActions = ['setValidFrom', 'setValidUntil'] 2 | 3 | const isValidityActions = (actionName) => validityActions.includes(actionName) 4 | 5 | export default function combineValidityActions(actions = []) { 6 | const [setValidFromAction, setValidUntilAction] = actions.filter((item) => 7 | isValidityActions(item.action) 8 | ) 9 | if (setValidFromAction && setValidUntilAction) { 10 | return [ 11 | ...actions.filter((item) => !isValidityActions(item.action)), 12 | { 13 | action: 'setValidFromAndUntil', 14 | validFrom: setValidFromAction.validFrom, 15 | validUntil: setValidUntilAction.validUntil, 16 | }, 17 | ] 18 | } 19 | return actions 20 | } 21 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/create-map-action-group.js: -------------------------------------------------------------------------------- 1 | // Array of action groups which need to be allowed or ignored. 2 | // Example: 3 | // [ 4 | // { type: 'base', group: 'ignore' }, 5 | // { type: 'prices', group: 'allow' }, 6 | // { type: 'variants', group: 'ignore' }, 7 | // ] 8 | export default function createMapActionGroup(actionGroups = []) { 9 | return function mapActionGroup(type, fn) { 10 | if (!Object.keys(actionGroups).length) return fn() 11 | 12 | const found = actionGroups.find((c) => c.type === type) 13 | if (!found) return [] 14 | 15 | // Keep `black` for backwards compatibility. 16 | if (found.group === 'ignore' || found.group === 'black') return [] 17 | // Keep `white` for backwards compatibility. 18 | if (found.group === 'allow' || found.group === 'white') return fn() 19 | 20 | throw new Error( 21 | `Action group '${found.group}' not supported. Use either "allow" or "ignore".` 22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/extract-matching-pairs.js: -------------------------------------------------------------------------------- 1 | export default function extractMatchingPairs(hashMap, key, before, now) { 2 | let oldObjPos 3 | let newObjPos 4 | let oldObj 5 | let newObj 6 | 7 | if (hashMap[key]) { 8 | oldObjPos = hashMap[key][0] 9 | newObjPos = hashMap[key][1] 10 | if (before && before[oldObjPos]) oldObj = before[oldObjPos] 11 | 12 | if (now && now[newObjPos]) newObj = now[newObjPos] 13 | } 14 | 15 | return { oldObj, newObj } 16 | } 17 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/find-matching-pairs.js: -------------------------------------------------------------------------------- 1 | import forEach from 'lodash.foreach' 2 | 3 | const REGEX_NUMBER = new RegExp(/^\d+$/) 4 | const REGEX_UNDERSCORE_NUMBER = new RegExp(/^_\d+$/) 5 | 6 | function preProcessCollection(collection = [], identifier = 'id') { 7 | return collection.reduce( 8 | (acc, currentValue, currentIndex) => { 9 | acc.refByIndex[String(currentIndex)] = currentValue[identifier] 10 | acc.refByIdentifier[currentValue[identifier]] = String(currentIndex) 11 | return acc 12 | }, 13 | { 14 | refByIndex: {}, 15 | refByIdentifier: {}, 16 | } 17 | ) 18 | } 19 | 20 | // creates a hash of a location of an item in collection1 and collection2 21 | export default function findMatchingPairs( 22 | diff, 23 | before = [], 24 | now = [], 25 | identifier = 'id' 26 | ) { 27 | const result = {} 28 | const { 29 | refByIdentifier: beforeObjRefByIdentifier, 30 | refByIndex: beforeObjRefByIndex, 31 | } = preProcessCollection(before, identifier) 32 | const { 33 | refByIdentifier: nowObjRefByIdentifier, 34 | refByIndex: nowObjRefByIndex, 35 | } = preProcessCollection(now, identifier) 36 | forEach(diff, (item, key) => { 37 | if (REGEX_NUMBER.test(key)) { 38 | const matchingIdentifier = nowObjRefByIndex[key] 39 | result[key] = [beforeObjRefByIdentifier[matchingIdentifier], key] 40 | } else if (REGEX_UNDERSCORE_NUMBER.test(key)) { 41 | const index = key.substring(1) 42 | const matchingIdentifier = beforeObjRefByIndex[index] 43 | result[key] = [index, nowObjRefByIdentifier[matchingIdentifier]] 44 | } 45 | }) 46 | return result 47 | } 48 | -------------------------------------------------------------------------------- /packages/sync-actions/src/utils/remove-typename.js: -------------------------------------------------------------------------------- 1 | export default function removeTypename(obj) { 2 | const { __typename, ...objWithoutTypename } = obj 3 | return objWithoutTypename 4 | } 5 | -------------------------------------------------------------------------------- /packages/sync-actions/test/utils/extract-matching-pairs.spec.js: -------------------------------------------------------------------------------- 1 | import extractMatchingPairs from '../../src/utils/extract-matching-pairs' 2 | 3 | describe('extractMatchingPairs', () => { 4 | let key 5 | let path 6 | let oldObj 7 | let newObj 8 | let pairs 9 | describe('with found path', () => { 10 | beforeEach(() => { 11 | key = '0' 12 | path = { 13 | [key]: ['0', '0'], 14 | } 15 | oldObj = [ 16 | { 17 | name: 'foo', 18 | }, 19 | ] 20 | newObj = [ 21 | { 22 | name: 'bar', 23 | }, 24 | ] 25 | pairs = extractMatchingPairs(path, key, oldObj, newObj) 26 | }) 27 | test('should return `newObj` and `oldObj`', () => { 28 | expect(pairs).toEqual({ 29 | oldObj: { name: 'foo' }, 30 | newObj: { name: 'bar' }, 31 | }) 32 | }) 33 | }) 34 | describe('without found pairs', () => { 35 | beforeEach(() => { 36 | key = '0' 37 | path = { 38 | [key]: ['0', '0'], 39 | } 40 | oldObj = [ 41 | { 42 | name: 'foo', 43 | }, 44 | ] 45 | newObj = [] 46 | pairs = extractMatchingPairs(path, key, oldObj, newObj) 47 | }) 48 | test('should return `oldObj` and empty `newObj`', () => { 49 | expect(pairs).toEqual({ 50 | oldObj: { name: 'foo' }, 51 | newObj: undefined, 52 | }) 53 | }) 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /packages/sync-actions/test/utils/find-matching-pairs.spec.js: -------------------------------------------------------------------------------- 1 | import findMatchingPairs from '../../src/utils/find-matching-pairs' 2 | 3 | describe('findMatchingPairs', () => { 4 | let diff 5 | let newVariants 6 | let oldVariants 7 | beforeEach(() => { 8 | diff = { 9 | _t: 'a', 10 | _3: ['', 0, 3], 11 | _4: [{ id: 10 }, 0, 0], 12 | _5: ['', 1, 3], 13 | } 14 | oldVariants = [ 15 | { id: 3 }, 16 | { id: 4 }, 17 | { id: 5 }, 18 | { id: 1 }, 19 | { id: 10 }, 20 | { id: 2 }, 21 | ] 22 | newVariants = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }] 23 | }) 24 | 25 | test('should find matching pairs', () => { 26 | const actualResult = findMatchingPairs(diff, oldVariants, newVariants) 27 | const expectedResult = { 28 | _3: ['3', '0'], 29 | _4: ['4', undefined], 30 | _5: ['5', '1'], 31 | } 32 | expect(actualResult).toEqual(expectedResult) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'integration-tests' 4 | -------------------------------------------------------------------------------- /scripts/install-npm-packages-for-integration-tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | tars=() 4 | 5 | echo "--> Pack all packages:" 6 | for dir in packages/resource-deleter packages/personal-data-erasure; do 7 | echo "$dir" 8 | pushd "$dir" > /dev/null 9 | tarName=$(npm pack) 10 | tars=("${tars[@]}" "$(pwd)/${tarName}") 11 | popd > /dev/null 12 | done 13 | 14 | echo "--> Install dependencies and packages for integration-tests:" 15 | pushd "./integration-tests" > /dev/null 16 | pnpm add "${tars[@]}" -w 17 | popd > /dev/null 18 | 19 | echo "--> Cleanup tarballs" 20 | for tar in "${tars[@]}"; do 21 | rm "${tar}" 22 | done 23 | -------------------------------------------------------------------------------- /scripts/npm-owners-grant: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | read -p "Username: " username 4 | 5 | for f in packages/*; do 6 | package=`basename $f` 7 | npm_package="@commercetools/$package" 8 | 9 | if [ -d "$f" ]; then 10 | npm owner add $username $npm_package 11 | fi 12 | done 13 | -------------------------------------------------------------------------------- /scripts/npm-owners-list: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | for f in packages/*; do 4 | package=`basename $f` 5 | npm_package="@commercetools/$package" 6 | 7 | if [ -d "$f" ]; then 8 | echo "(${npm_package})" 9 | npm owner ls $npm_package 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /scripts/npm-owners-revoke: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | read -p "Username: " username 4 | 5 | for f in packages/*; do 6 | package=`basename $f` 7 | npm_package="@commercetools/$package" 8 | 9 | if [ -d "$f" ]; then 10 | npm owner rm $username $npm_package 11 | fi 12 | done 13 | -------------------------------------------------------------------------------- /scripts/package-readme-entry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | read -p "Package name: " name 4 | 5 | nameCell="[\`$name\`](/packages/$name)" 6 | versionCell="[![$name Version][$name-icon]][$name-version]" 7 | dependenciesCell="[![$name Dependencies Status][$name-dependencies-icon]][$name-dependencies]" 8 | 9 | echo "| $nameCell | $versionCell | $dependenciesCell |" 10 | 11 | versionUrl="[$name-version]: https://www.npmjs.com/package/@commercetools/$name" 12 | versionIcon="[$name-icon]: https://img.shields.io/npm/v/@commercetools/$name.svg?style=flat-square" 13 | dependenciesUrl="[$name-dependencies]: https://david-dm.org/commercetools/nodejs?path=packages/$name" 14 | dependenciesIcon="[$name-dependencies-icon]: https://img.shields.io/david/commercetools/nodejs.svg?path=packages/$name&style=flat-square" 15 | 16 | echo " 17 | $versionUrl 18 | $versionIcon 19 | $dependenciesUrl 20 | $dependenciesIcon 21 | " 22 | -------------------------------------------------------------------------------- /scripts/postinstall.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -n "$SKIP_POSTINSTALL" ]; then 6 | echo "Skipping postinstall steps." 7 | 8 | else 9 | if [ -n "$SKIP_POSTINSTALL_DEV_SETUP" ]; then 10 | echo "Skipping development setup." 11 | 12 | else 13 | echo "Preparing development setup." 14 | 15 | pnpm husky install 16 | pnpm preconstruct dev 17 | pnpm check-node-version --package --print 18 | pnpm manypkg check 19 | fi 20 | fi 21 | -------------------------------------------------------------------------------- /scripts/test-package: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # An optional flag to pass to the test runner (see validation below) 4 | flag="${1}" 5 | 6 | if [ -n "$flag" ]; then 7 | if [[ "$flag" != "--watch" && "$flag" != "--coverage" ]]; then 8 | echo "Only --watch or --coverage mode are supported as flag" 9 | exit 1 10 | fi 11 | fi 12 | 13 | packages=() 14 | for dir in packages/*; do 15 | packages=(${packages[@]} "${dir/packages\//@commercetools/}") 16 | done 17 | 18 | echo "Select a package to run the tests for:" 19 | select package in "${packages[@]}"; do 20 | selected_package=$package 21 | echo "Selected package $selected_package" 22 | break 23 | done 24 | 25 | if [ -z "$flag" ]; then 26 | pnpm --filter $selected_package exec -- $(pwd)/node_modules/.bin/jest --config $(pwd)/jest.test.config.js 27 | else 28 | pnpm --fitler $selected_package exec -- $(pwd)/node_modules/.bin/jest --config $(pwd)/jest.test.config.js $flag 29 | fi 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "emitDecoratorMetadata": false, 5 | "experimentalDecorators": false, 6 | "esModuleInterop": true, 7 | "importHelpers": true, 8 | "isolatedModules": true, 9 | "lib": [ 10 | "esnext", 11 | "dom" 12 | ], 13 | "module": "esnext", 14 | "moduleResolution": "node", 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitAny": true, 17 | "noImplicitReturns": true, 18 | "resolveJsonModule": true, 19 | "noImplicitThis": true, 20 | "noUnusedLocals": false, 21 | "noUnusedParameters": true, 22 | "preserveSymlinks": true, 23 | "pretty": true, 24 | "removeComments": true, 25 | "sourceMap": true, 26 | "strict": true, 27 | "strictNullChecks": true, 28 | "stripInternal": true, 29 | "target": "esnext", 30 | "allowJs": false, 31 | "baseUrl": ".", 32 | "skipLibCheck": true, 33 | "typeRoots": [ 34 | "node_modules/@types" 35 | ] 36 | }, 37 | "exclude": [ 38 | "**/node_modules", 39 | "**/dist/**/*", 40 | "**/src/**/*.js" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /types/categoryExporter.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /* Logger */ 4 | export type LoggerOptions = { 5 | error: Function, 6 | info: Function, 7 | warn: Function, 8 | debug: Function, 9 | } 10 | 11 | /* Config */ 12 | export type ApiConfigOptions = { 13 | host: string, 14 | projectKey: string, 15 | credentials: { 16 | clientId: string, 17 | clientSecret: string, 18 | }, 19 | scopes: Array, 20 | apiUrl?: string, 21 | } 22 | 23 | export type CategoryExporterOptions = { 24 | apiConfig: ApiConfigOptions, 25 | accessToken?: string, 26 | predicate?: string, 27 | logger?: LoggerOptions, 28 | } 29 | -------------------------------------------------------------------------------- /types/customObjects.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /* Custom Objects */ 4 | 5 | type Values = number | string | boolean | Array | Object 6 | 7 | export type CustomObjectDraft = { 8 | container: string, 9 | key: string, 10 | value: number | string | boolean | Array | Object, 11 | version?: number, 12 | } 13 | 14 | export type CustomObject = { 15 | id: String, 16 | createdAt: number, 17 | lastModifiedAt: number, 18 | container: string, 19 | key: string, 20 | value: number | string | boolean | Array | Object, 21 | version: number, 22 | } 23 | 24 | export type ExecutionResult = Promise 25 | 26 | /* Summary */ 27 | 28 | export type Summary = { 29 | createdCount: number, 30 | updatedCount: number, 31 | unchangedCount: number, 32 | createErrorCount: number, 33 | updateErrorCount: number, 34 | errors: Array, 35 | } 36 | 37 | export type SummaryReport = { 38 | reportMessage: string, 39 | detailedSummary: Summary, 40 | } 41 | 42 | /* Logger */ 43 | export type LoggerOptions = { 44 | error: Function, 45 | info: Function, 46 | warn: Function, 47 | debug: Function, 48 | } 49 | 50 | /* Config */ 51 | export type ApiConfigOptions = { 52 | host: string, 53 | projectKey: string, 54 | credentials: { 55 | clientId: string, 56 | clientSecret: string, 57 | }, 58 | scopes: Array, 59 | apiUrl?: string, 60 | } 61 | 62 | export type ExporterOptions = { 63 | apiConfig: ApiConfigOptions, 64 | accessToken?: string, 65 | predicate?: string, 66 | logger?: LoggerOptions, 67 | batchSize?: number, 68 | continueOnProblems?: boolean, 69 | } 70 | -------------------------------------------------------------------------------- /types/customerGroups.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /* Logger */ 4 | export type LoggerOptions = { 5 | error: Function, 6 | info: Function, 7 | warn: Function, 8 | debug: Function, 9 | } 10 | 11 | /* Config */ 12 | export type ApiConfigOptions = { 13 | host: string, 14 | projectKey: string, 15 | credentials: { 16 | clientId: string, 17 | clientSecret: string, 18 | }, 19 | scopes: Array, 20 | apiUrl?: string, 21 | } 22 | 23 | export type ExporterOptions = { 24 | apiConfig: ApiConfigOptions, 25 | accessToken?: string, 26 | predicate?: string, 27 | logger?: LoggerOptions, 28 | batchSize?: number, 29 | continueOnProblems?: boolean, 30 | } 31 | -------------------------------------------------------------------------------- /types/highland.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /* Highland stream */ 4 | export type highlandStream = { 5 | map: Function, 6 | through: Function, 7 | flatMap: Function, 8 | doto: Function, 9 | flatten: Function, 10 | stopOnError: Function, 11 | each: Function, 12 | done: Function, 13 | } 14 | -------------------------------------------------------------------------------- /types/inventory.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export type Inventory = { 4 | id: string, 5 | version: number, 6 | createdAt: string, 7 | lastModifiedAt: string, 8 | sku: string, 9 | supplyChannel: Object, 10 | quantityOnStock: number, 11 | availableQuantity: number, 12 | restockableInDays: number, 13 | expectedDelivery: string, 14 | custom: { 15 | type: Object, 16 | fields: Object, 17 | }, 18 | } 19 | 20 | export type ExportConfig = { 21 | headerFields: Array | null, 22 | format: string, 23 | delimiter: string, 24 | channelKey?: string, 25 | queryString?: string, 26 | } 27 | 28 | export type CsvInventoryMapping = { 29 | sku: string, 30 | supplyChannel?: Object, 31 | quantityOnStock: number, 32 | availableQuantity?: number, 33 | restockableInDays?: number, 34 | expectedDelivery?: string, 35 | customType?: string, 36 | custom?: { 37 | type: Object, 38 | fields: Object, 39 | }, 40 | createdAt?: string, 41 | lastModifiedAt?: string, 42 | } 43 | -------------------------------------------------------------------------------- /types/price.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /* Config */ 4 | export type ApiConfigOptions = { 5 | host: string, 6 | projectKey: string, 7 | credentials: { 8 | clientId: string, 9 | clientSecret: string, 10 | }, 11 | scopes: Array, 12 | apiUrl?: string, 13 | } 14 | 15 | export type Configuration = { 16 | accessToken?: string, 17 | delimiter: string, 18 | exportFormat: string, 19 | predicate: string, 20 | staged: boolean, 21 | csvHeaders?: Array, 22 | } 23 | 24 | export type ExporterOptions = { 25 | apiConfig: ApiConfigOptions, 26 | accessToken?: string, 27 | delimiter: string, 28 | exportFormat: string, 29 | predicate: string, 30 | staged: boolean, 31 | csvHeaders?: Array, 32 | } 33 | 34 | /* Logger */ 35 | export type LoggerOptions = { 36 | error: Function, 37 | info: Function, 38 | warn: Function, 39 | verbose: Function, 40 | } 41 | 42 | /* Price */ 43 | export type currencyValue = { 44 | currencyCode: string, 45 | centAmount: number, 46 | } 47 | 48 | export type customerGroup = { 49 | groupName?: string, 50 | id?: string, 51 | } 52 | 53 | export type channel = { 54 | key?: string, 55 | id?: string, 56 | } 57 | 58 | export type reference = { 59 | id: string, 60 | typeId?: string, 61 | } 62 | 63 | export type customReference = { 64 | type: reference, 65 | fields: Object, 66 | } 67 | 68 | export type UnprocessedPriceObject = { 69 | value: currencyValue, 70 | country?: string, 71 | id?: string, 72 | customerGroup?: reference, 73 | channel?: reference, 74 | custom?: customReference, 75 | 'variant-sku'?: string, 76 | } 77 | 78 | export type ProcessedPriceObject = { 79 | value: currencyValue, 80 | country?: string, 81 | id?: string, 82 | customerGroup?: customerGroup, 83 | 'variant-sku'?: string, 84 | customType?: string, 85 | channel?: channel, 86 | custom?: customReference, 87 | customField?: Object, 88 | } 89 | -------------------------------------------------------------------------------- /types/resourceDeleter.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import type { ClientResult } from 'types/sdk' 3 | 4 | /* Logger */ 5 | export type LoggerOptions = { 6 | error: (...args: Array) => void, 7 | info: (...args: Array) => void, 8 | warn: (...args: Array) => void, 9 | debug: (...args: Array) => void, 10 | } 11 | 12 | /* Config */ 13 | export type ApiConfigOptions = { 14 | host: string, 15 | projectKey: string, 16 | credentials: { 17 | clientId: string, 18 | clientSecret: string, 19 | }, 20 | scopes: Array, 21 | apiUrl?: string, 22 | } 23 | 24 | /* Client */ 25 | export type CustomClientResult = ClientResult & { 26 | id: string, 27 | version?: number, 28 | } 29 | 30 | /* ResourceDeleter Objects */ 31 | export type resourceDeleterOptions = { 32 | apiConfig: ApiConfigOptions, 33 | accessToken?: string, 34 | predicate?: string, 35 | logger?: LoggerOptions, 36 | resource: string, 37 | fetchedResource: CustomClientResult, 38 | } 39 | --------------------------------------------------------------------------------