├── .babelrc ├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ ├── netlicensing-js-ci.yml │ ├── netlicensing-js-codeql-analysis.yml │ └── netlicensing-js-release.yml ├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── _release.sh ├── build ├── build.cjs ├── webpack.base.conf.cjs ├── webpack.dev.conf.cjs ├── webpack.node.conf.cjs ├── webpack.prod.conf.cjs ├── webpack.test.conf.cjs └── webpack.web.conf.cjs ├── dist ├── netlicensing-client.js ├── netlicensing-client.min.js ├── netlicensing-client.min.js.LICENSE.txt ├── netlicensing-client.node.js ├── netlicensing-client.node.min.js └── netlicensing-client.node.min.js.LICENSE.txt ├── docs ├── client-demo.html └── client-demo.js ├── package-lock.json ├── package.json ├── src ├── Constants.js ├── converters │ ├── itemToBundle.js │ ├── itemToCountry.js │ ├── itemToLicense.js │ ├── itemToLicenseTemplate.js │ ├── itemToLicensee.js │ ├── itemToNotification.js │ ├── itemToObject.js │ ├── itemToPaymentMethod.js │ ├── itemToProduct.js │ ├── itemToProductModule.js │ ├── itemToToken.js │ └── itemToTransaction.js ├── entities │ ├── BaseEntity.js │ ├── Bundle.js │ ├── Country.js │ ├── License.js │ ├── LicenseTemplate.js │ ├── LicenseTransactionJoin.js │ ├── Licensee.js │ ├── Notification.js │ ├── PaymentMethod.js │ ├── Product.js │ ├── ProductDiscount.js │ ├── ProductModule.js │ ├── Token.js │ └── Transaction.js ├── errors │ └── NlicError.js ├── index.js ├── services │ ├── BundleService.js │ ├── LicenseService.js │ ├── LicenseTemplateService.js │ ├── LicenseeService.js │ ├── NotificationService.js │ ├── PaymentMethodService.js │ ├── ProductModuleService.js │ ├── ProductService.js │ ├── Service.js │ ├── TokenService.js │ ├── TransactionService.js │ └── UtilityService.js ├── util │ ├── CastsUtils.js │ ├── CheckUtils.js │ └── FilterUtils.js └── vo │ ├── Context.js │ ├── Page.js │ ├── ValidationParameters.js │ └── ValidationResults.js └── test ├── factories ├── bundle.js ├── factory.js ├── license.js ├── licenseTemplate.js ├── licensee.js ├── notification.js ├── paymentMethod.js ├── product.js ├── productDiscount.js ├── productModule.js ├── token.js ├── transaction.js ├── utility.js └── validate.js ├── index.js ├── karma.conf.js ├── response ├── Info.js ├── Item.js └── index.js └── specs ├── .eslintrc ├── entities ├── Country.spec.js ├── License.spec.js ├── LicenseTemplate.spec.js ├── Licensee.spec.js ├── Notification.spec.js ├── PaymentMethod.spec.js ├── Product.spec.js ├── ProductDiscount.spec.js ├── ProductModule.spec.js ├── Token.spec.js └── Transaction.spec.js └── services ├── BundleService.spec.js ├── LicenseService.spec.js ├── LicenseTemplateService.spec.js ├── LicenseeService.spec.js ├── NotificationService.spec.js ├── PaymentMethodService.spec.js ├── ProductModuleService.spec.js ├── ProductService.spec.js ├── TokenService.spec.js ├── TransactionService.spec.js └── UtilityService.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "modules": false, 7 | "targets": { 8 | "browsers": [ 9 | "> 1%", 10 | "last 2 versions", 11 | "not ie <= 8" 12 | ] 13 | } 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | "@babel/plugin-transform-runtime", 19 | [ 20 | "@babel/plugin-proposal-decorators", 21 | { 22 | "legacy": true 23 | } 24 | ], 25 | [ 26 | "@babel/plugin-transform-modules-commonjs", 27 | { 28 | "allowTopLevelThis": true 29 | } 30 | ], 31 | "@babel/plugin-proposal-function-sent", 32 | "@babel/plugin-proposal-export-namespace-from", 33 | "@babel/plugin-proposal-numeric-separator", 34 | "@babel/plugin-proposal-throw-expressions", 35 | "@babel/plugin-syntax-dynamic-import", 36 | "@babel/plugin-syntax-import-meta", 37 | [ 38 | "@babel/plugin-proposal-class-properties", 39 | { 40 | "loose": false 41 | } 42 | ], 43 | "@babel/plugin-proposal-json-strings" 44 | ], 45 | "env": { 46 | "test": { 47 | "presets": [ 48 | "@babel/preset-env" 49 | ], 50 | "plugins": [ 51 | "istanbul", 52 | [ 53 | "@babel/plugin-proposal-decorators", 54 | { 55 | "legacy": true 56 | } 57 | ], 58 | "@babel/plugin-proposal-function-sent", 59 | "@babel/plugin-proposal-export-namespace-from", 60 | "@babel/plugin-proposal-numeric-separator", 61 | "@babel/plugin-proposal-throw-expressions", 62 | "@babel/plugin-syntax-dynamic-import", 63 | "@babel/plugin-syntax-import-meta", 64 | [ 65 | "@babel/plugin-proposal-class-properties", 66 | { 67 | "loose": false 68 | } 69 | ], 70 | "@babel/plugin-proposal-json-strings" 71 | ] 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /build 2 | /dist 3 | /node_modules 4 | /docs -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // https://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parserOptions: { 6 | parser: 'babel-eslint', 7 | }, 8 | env: { 9 | browser: true, 10 | }, 11 | extends: ['airbnb-base'], 12 | // check if imports actually resolve 13 | settings: { 14 | 'import/resolver': { 15 | webpack: { 16 | config: 'build/webpack.base.conf.cjs', 17 | }, 18 | }, 19 | }, 20 | // add your custom rules here 21 | rules: { 22 | // allow optionalDependencies 23 | 'import/no-extraneous-dependencies': ['error', { 24 | optionalDependencies: ['test/index.js'], 25 | }], 26 | // allow debugger during development 27 | 'no-debugger': 'error', 28 | // custom spaces rules 29 | indent: 'off', 30 | 'indent-legacy': ['error', 4, { SwitchCase: 1 }], 31 | 'linebreak-style': 0, 32 | 'max-len': ['error', 120, { ignoreComments: true }], 33 | 'vue/no-template-key': 'off', 34 | 'object-curly-newline': ['error', { consistent: true }], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /.github/workflows/netlicensing-js-ci.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript Client - CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [18.x, 20.x, 22.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: npm install, build, and test 21 | run: | 22 | npm ci 23 | npm run build --if-present 24 | npm test 25 | ls -la dist/ 26 | env: 27 | CI: true 28 | -------------------------------------------------------------------------------- /.github/workflows/netlicensing-js-codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "JavaScript Client - CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '0 0 */7 * *' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v2 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v2 71 | -------------------------------------------------------------------------------- /.github/workflows/netlicensing-js-release.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript Client - Release 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 18 15 | - run: npm ci 16 | - run: npm test 17 | 18 | publish-npm: 19 | needs: build 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v3 23 | - uses: actions/setup-node@v3 24 | with: 25 | node-version: 18 26 | registry-url: https://registry.npmjs.org/ 27 | - run: npm ci 28 | - run: npm publish 29 | env: 30 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | .build* 5 | .idea 6 | index.html 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - node 4 | - '12' 5 | - '13' 6 | services: 7 | - xvfb 8 | script: 9 | - npm run test-for-travis 10 | after_success: 11 | - env 12 | - test "${TRAVIS_NODE_VERSION}" == "12" && test "${TRAVIS_TEST_RESULT}" == "0" && npm run build 13 | - ls -la dist/ 14 | jobs: 15 | include: 16 | - stage: npm release 17 | node_js: 12 18 | script: 19 | - if [ -n "$TRAVIS_TAG" ]; then echo "Deploying version ${TRAVIS_TAG} to npm..."; 20 | fi 21 | deploy: 22 | provider: npm 23 | email: info@labs64.com 24 | api_key: 25 | secure: Ap+YAsL47M+RQOI0XIKeeOIvnCkBBFG7w6MdyEIibQjURbI8D9SAhZGEjE2s+ahdmtlwJkcKhPj4hpKNKgPFFSJgrLdtAnfvqoMUuj2LEBc+m7/6eZfUTchV1d7ckKe0PvhvRlQssg04N5ODt65xTPnivRMLiXcPiJDt4AceiR0EwVZQx7YZTSCLx5K48X8HI3VuVwShiWPwxm6zjKGOdoaa6GFO0taUBdUD0wZXHb8bfkHmvgiBz5g/uPoLxs4R6t36mUoXpnte5L9vCwV42Swt1Xmztd1drBUDEjuxmJuLLgNWBZ+Yywn8Z62Zthi+sQ/w99LdFP+CsTExmo+t9CmhakV2OOugonQJmCQdcmh+xWBZNCVCXadjS0yvo/DSm7L+sREiaqn+Y1lCjKAfgcHTi15+fHfDyUOddiW0Yozn2Nje4Oy8zkPjr80X+SoDyoaXa51qM0BV7J7e/e1XBi4sKIqeOOLlRTvJgf2e6/Dqrn/ouMRvqEKafYLynFdPcxszmtoYLuwYt6D8C0blf+Sz6Ofs52oxGZimmMr67am06PiQgMLtUF1Dz5tOlXA1B+aMe6S4Tn+uH4d5pSAPA6vdAXdCYZ62f31Qxd8/M9CsTnLjk87SaOzLd2rF9UV1k1hYlTQl/nKjsbOtKNDQlWzUVCXpvEVXmnRi4HpaYIQ= 26 | on: 27 | tags: true 28 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | MAINTAINER Labs64 GmbH info@labs64.com 4 | 5 | # Install some must-haves 6 | RUN apt-get update 7 | RUN apt-get -y install vim git 8 | 9 | # Install Google Chrome 10 | RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - 11 | RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' 12 | RUN apt-get update && apt-get install -y google-chrome-stable 13 | 14 | # Check installed software versions 15 | RUN git --version 16 | RUN node -v 17 | 18 | # Define work directory and volumes 19 | WORKDIR /opt/NetLicensingClient-javascript 20 | VOLUME ["/opt/NetLicensingClient-javascript"] 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Innovative License Management Solution 2 | 3 | # [Labs64 NetLicensing](https://netlicensing.io) Client (JavaScript) 4 | 5 | [![Build Status](https://github.com/Labs64/NetLicensingClient-javascript/workflows/NetLicensing%20Client%20CI/badge.svg)](https://github.com/Labs64/NetLicensingClient-javascript/actions?query=workflow%3A%22JavaScript+Client+-+CI%22) 6 | [![npm version](https://img.shields.io/npm/v/netlicensing-client)](https://www.npmjs.com/package/netlicensing-client) 7 | [![npm downloads](https://img.shields.io/npm/dt/netlicensing-client)](https://www.npmjs.com/package/netlicensing-client) 8 | [![jsDelivr](https://data.jsdelivr.com/v1/package/npm/netlicensing-client/badge)](https://www.jsdelivr.com/package/npm/netlicensing-client) 9 |
10 | [![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/Labs64/NetLicensingClient-javascript/blob/master/LICENSE) 11 | [![📖 Documentation](https://img.shields.io/badge/📖%20Documentation-Wiki-AB6543.svg)](https://netlicensing.io/wiki/restful-api) 12 | [![NetLicensing @ LinkedIn](https://img.shields.io/badge/NetLicensing-0077B5.svg?logo=LinkedIn)](https://www.linkedin.com/showcase/netlicensing) 13 | 14 | JavaScript wrapper for Labs64 NetLicensing [RESTful API](https://netlicensing.io/wiki/restful-api) 15 | 16 | Visit Labs64 NetLicensing at https://netlicensing.io 17 | 18 | ## How to Use 19 | 20 | NetLicensing JavaScript Client was designed to work both in the browser and in Node.js. 21 | 22 | In order to use NetLicensing JavaScript Client, you must include the compiled and minified JavaScript file in your project. There are multiple options for including these pre-compiled files, also known as a distribution, in your website or application. 23 | 24 | ### Using from a CDN 25 | 26 | A CDN (Content Delivery Network) is the fastest way to get up and running with NetLicensing JavaScript Client. 27 | Simply include the following lines of code in the `` section of your page using latest [released version](https://github.com/Labs64/NetLicensingClient-javascript/releases): 28 | ```html 29 | 30 | ``` 31 | 32 | ### Installing with Node.js / npm 33 | 34 | NetLicensing JavaScript Client is available on [npmjs](https://www.npmjs.com/package/netlicensing-client). Add the following to your `package.json` file and then run `npm install`: 35 | ```json 36 | "dependencies": { 37 | "netlicensing-client": "x.y.z" 38 | } 39 | ``` 40 | 41 | or execute following command in your Node.js environment: 42 | 43 | ```bash 44 | $ npm install netlicensing-client 45 | ``` 46 | 47 | ### Manual installation 48 | 49 | We strongly recommend that you use either a CDN or a package manager like npm. This will make it easier for you to deploy your project in different environments, and easily update NetLicensing JavaScript Client when new versions are released. Nonetheless, if you prefer to integrate NetLicensing into your project manually, you can [download the release of your choice](https://github.com/Labs64/NetLicensingClient-javascript/releases) from GitHub and copy the files from the `dist` directory into your project. 50 | 51 | Include the compiled files in your page: 52 | ```html 53 | 54 | ``` 55 | 56 | Check [NetLicensing Wiki](https://netlicensing.io/wiki/) or [NetLicensing Community Support](https://github.com/Labs64/NetLicensing-Community/issues?q=is%3Aissue+javascript) for detailed usage instructions. 57 | 58 | ## Online Demo 59 | 60 | Demo web application for this library can be found [here](http://io.labs64.com/NetLicensingClient-javascript/client-demo.html) as well as [source code](https://github.com/Labs64/NetLicensingClient-javascript/tree/master/docs). 61 | 62 | ## Development 63 | 64 | Useful commands: 65 | - ```npm run dev``` - build and track all changes to your resources 66 | - ```npm run test```- run unit tests 67 | - ```npm run lint``` - syntax check 68 | 69 | Here is a Docker-based local development environment prepared, which provides a very flexible and extensible way of developing Node.js applications. 70 | 71 | ### System Requirements 72 | To be able to build this library you have to meet the following requirements: 73 | * [docker](https://www.docker.com) 74 | To be able to build this NetLicensing Client you have to meet the following requirements: 75 | * Node.js >= 8.x 76 | * npm >= 6.x 77 | 78 | ### Develop with Docker 79 | 80 | 1. Clone repository 81 | ```bash 82 | $ git clone https://github.com/Labs64/NetLicensingClient-javascript.git 83 | ``` 84 | 85 | 2. Prepare docker image 86 | ```bash 87 | $ docker build -t labs64/nodejs . 88 | ``` 89 | 90 | 3. Start local development environment 91 | ```bash 92 | $ docker run -v $(pwd):/opt/NetLicensingClient-javascript -i -t labs64/nodejs /bin/bash 93 | ``` 94 | 95 | 4. Configure git using your eMail and Username 96 | ```bash 97 | $ git config --global user.email "eMail" 98 | $ git config --global user.name "User Name" 99 | ``` 100 | 101 | ## How to Contribute 102 | 103 | Everyone is welcome to contribute to this project! 104 | Once you're done with your changes send a pull request and check [CI Status](https://github.com/Labs64/NetLicensingClient-javascript/actions?query=workflow%3A%22JavaScript+Client+-+CI%22). 105 | Thanks! 106 | 107 | ## Bugs and Feedback 108 | 109 | For bugs, questions and discussions please use the [GitHub Issues](https://github.com/Labs64/NetLicensingClient-javascript/issues). 110 | 111 | ## License 112 | 113 | This boilerplate is open-sourced software licensed under the [Apache License Version 2.0](LICENSE). 114 | 115 | --- 116 | 117 | Visit Labs64 NetLicensing at https://netlicensing.io 118 | -------------------------------------------------------------------------------- /_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # install dependencies 4 | npm install 5 | 6 | # check outdated dependencies 7 | npm outdated 8 | 9 | # execute tests 10 | npm run test 11 | 12 | # prepare distribution 13 | npm run build 14 | 15 | # version prompt 16 | echo Enter release version: 17 | read version 18 | if [ "$version" = "" ]; then 19 | echo "Error! Version cannot be empty." 20 | exit 1 21 | fi 22 | 23 | # start release 24 | git commit -a -m "Prepare for release $version" 25 | npm config set tag-version-prefix '' 26 | npm version $version -m "Prepare for Release $version" 27 | git push origin master $version 28 | -------------------------------------------------------------------------------- /build/build.cjs: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const ora = require('ora'); 4 | 5 | const rm = require('rimraf'); 6 | const chalk = require('chalk'); 7 | const webpack = require('webpack'); 8 | const webpackConfig = require('./webpack.prod.conf.cjs'); 9 | 10 | const spinner = ora('building for production... '); 11 | spinner.start(); 12 | 13 | rm(path.resolve(__dirname, '../dist'), (e) => { 14 | if (e) throw e; 15 | webpack(webpackConfig, (err, stats) => { 16 | spinner.stop(); 17 | if (err) throw err; 18 | process.stdout.write(`${stats.toString({ 19 | colors: true, 20 | modules: false, 21 | children: false, 22 | chunks: false, 23 | chunkModules: false, 24 | })}\n\n`); 25 | 26 | if (stats.hasErrors()) { 27 | spinner.fail(chalk.red('Build failed with errors.\n')) 28 | process.exit(1); 29 | } 30 | 31 | spinner.succeed(chalk.cyan('Build complete.\n')) 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /build/webpack.base.conf.cjs: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const eslintFriendlyFormatter = require('eslint-friendly-formatter'); 3 | const ESLintPlugin = require('eslint-webpack-plugin'); 4 | const pkg = require('../package.json'); 5 | 6 | const namespace = 'NetLicensing'; 7 | 8 | function resolve(dir) { 9 | return path.join(__dirname, '..', dir); 10 | } 11 | 12 | module.exports = { 13 | context: path.resolve(__dirname, '../'), 14 | output: { 15 | path: path.resolve(__dirname, '../dist'), 16 | filename: '[name].js', 17 | library: namespace, 18 | libraryTarget: 'umd', 19 | umdNamedDefine: true, 20 | globalObject: 'this', 21 | }, 22 | resolve: { 23 | extensions: ['.js', '.json'], 24 | alias: { 25 | '@': resolve('src'), 26 | 'test@': resolve('test'), 27 | }, 28 | }, 29 | module: { 30 | rules: [ 31 | { 32 | test: /\.js$/, 33 | loader: 'babel-loader', 34 | exclude: /node_modules/, 35 | include: [resolve('src'), resolve('test')], 36 | }, 37 | // { 38 | // test: /(\.jsx|\.js)$/, 39 | // loader: 'eslint-loader', 40 | // include: [resolve('src'), resolve('test')], 41 | // options: { 42 | // formatter: eslintFriendlyFormatter, 43 | // emitWarning: true, 44 | // }, 45 | // }, 46 | ], 47 | }, 48 | plugins: [new ESLintPlugin()], 49 | }; 50 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.cjs: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const webWebpackConfig = require('./webpack.web.conf.cjs'); 3 | 4 | const webpackConfig = merge(webWebpackConfig, { 5 | mode: 'development', 6 | devtool: 'source-map', 7 | }); 8 | 9 | module.exports = webpackConfig; 10 | -------------------------------------------------------------------------------- /build/webpack.node.conf.cjs: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const pkg = require('../package.json'); 3 | const baseWebpackConfig = require('./webpack.base.conf.cjs'); 4 | 5 | const { name } = pkg; 6 | 7 | module.exports = merge( 8 | baseWebpackConfig, 9 | { 10 | target: 'node', 11 | entry: { 12 | [`${name}.node`]: './src', 13 | [`${name}.node.min`]: './src', 14 | }, 15 | }, 16 | ); 17 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.cjs: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const TerserPlugin = require("terser-webpack-plugin"); 3 | const webWebpackConfig = require('./webpack.web.conf.cjs'); 4 | const nodeWebpackConfig = require('./webpack.node.conf.cjs'); 5 | 6 | const webpackConfig = { 7 | mode: 'production', 8 | devtool: false, 9 | performance: { hints: false }, 10 | optimization: { 11 | minimizer: [ 12 | new TerserPlugin({ 13 | parallel: true, 14 | test: /\.min\.js$/, 15 | }), 16 | ], 17 | }, 18 | }; 19 | 20 | module.exports = [merge(webWebpackConfig, webpackConfig), merge(nodeWebpackConfig, webpackConfig)]; 21 | -------------------------------------------------------------------------------- /build/webpack.test.conf.cjs: -------------------------------------------------------------------------------- 1 | // This is the webpack config used for unit tests. 2 | const { merge } = require('webpack-merge'); 3 | const baseWebpackConfig = require('./webpack.base.conf.cjs'); 4 | 5 | const webpackConfig = merge(baseWebpackConfig, { 6 | mode: 'development', 7 | devtool: 'inline-source-map', 8 | }); 9 | 10 | module.exports = webpackConfig; 11 | -------------------------------------------------------------------------------- /build/webpack.web.conf.cjs: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const pkg = require('../package.json'); 3 | const baseWebpackConfig = require('./webpack.base.conf.cjs'); 4 | 5 | const { name } = pkg; 6 | 7 | module.exports = merge( 8 | baseWebpackConfig, 9 | { 10 | target: 'web', 11 | entry: { 12 | [name]: './src', 13 | [`${name}.min`]: './src', 14 | }, 15 | }, 16 | ); 17 | -------------------------------------------------------------------------------- /dist/netlicensing-client.min.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! Axios v1.8.2 Copyright (c) 2025 Matt Zabriskie and contributors */ 2 | 3 | /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ 4 | 5 | /** 6 | * @author Labs64 7 | * @license Apache-2.0 8 | * @link https://netlicensing.io 9 | * @copyright 2017 Labs64 NetLicensing 10 | */ 11 | -------------------------------------------------------------------------------- /dist/netlicensing-client.node.min.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * mime-db 3 | * Copyright(c) 2014 Jonathan Ong 4 | * Copyright(c) 2015-2022 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | /*! 9 | * mime-types 10 | * Copyright(c) 2014 Jonathan Ong 11 | * Copyright(c) 2015 Douglas Christopher Wilson 12 | * MIT Licensed 13 | */ 14 | 15 | /*! Axios v1.8.2 Copyright (c) 2025 Matt Zabriskie and contributors */ 16 | 17 | /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ 18 | 19 | /** 20 | * @author Labs64 21 | * @license Apache-2.0 22 | * @link https://netlicensing.io 23 | * @copyright 2017 Labs64 NetLicensing 24 | */ 25 | -------------------------------------------------------------------------------- /docs/client-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Labs64 NetLicensing JavaScript Client Demo 6 | 7 | 8 | 17 | 18 | 19 | 20 |

Labs64 NetLicensing
JavaScript Client 21 | Demo

22 |

This demo showcases RESTful API access 23 | to NetLicensing’s core features.

24 |

25 | 26 | 27 |

28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "netlicensing-client", 3 | "version": "1.2.39", 4 | "description": "JavaScript Wrapper for Labs64 NetLicensing RESTful API", 5 | "keywords": [ 6 | "labs64", 7 | "netlicensing", 8 | "licensing", 9 | "licensing-as-a-service", 10 | "license", 11 | "license-management", 12 | "software-license", 13 | "client", 14 | "restful", 15 | "restful-api", 16 | "javascript", 17 | "wrapper", 18 | "api", 19 | "client" 20 | ], 21 | "license": "Apache-2.0", 22 | "author": "Labs64 GmbH", 23 | "homepage": "https://netlicensing.io", 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/Labs64/NetLicensingClient-javascript" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/Labs64/NetLicensingClient-javascript/issues" 30 | }, 31 | "contributors": [ 32 | { 33 | "name": "Ready Brown", 34 | "email": "ready.brown@hotmail.de", 35 | "url": "https://github.com/r-brown" 36 | }, 37 | { 38 | "name": "Viacheslav Rudkovskiy", 39 | "email": "viachaslau.rudkovski@labs64.de", 40 | "url": "https://github.com/v-rudkovskiy" 41 | }, 42 | { 43 | "name": "Andrei Yushkevich", 44 | "email": "yushkevich@me.com", 45 | "url": "https://github.com/yushkevich" 46 | } 47 | ], 48 | "main": "dist/netlicensing-client.js", 49 | "files": [ 50 | "dist" 51 | ], 52 | "scripts": { 53 | "build": "node build/build.cjs", 54 | "release": "npm run build && npm run test", 55 | "dev": "webpack --progress --watch --config build/webpack.dev.conf.cjs", 56 | "test": "karma start test/karma.conf.js --single-run", 57 | "test-mocha": "webpack --config build/webpack.test.conf.cjs", 58 | "test-for-travis": "karma start test/karma.conf.js --single-run --browsers Firefox", 59 | "lint": "eslint --ext .js,.vue src test" 60 | }, 61 | "dependencies": { 62 | "axios": "^1.8.2", 63 | "btoa": "^1.2.1", 64 | "es6-promise": "^4.2.8" 65 | }, 66 | "devDependencies": { 67 | "@babel/core": "^7.26.9", 68 | "@babel/plugin-proposal-class-properties": "^7.16.7", 69 | "@babel/plugin-proposal-decorators": "^7.25.9", 70 | "@babel/plugin-proposal-export-namespace-from": "^7.16.7", 71 | "@babel/plugin-proposal-function-sent": "^7.25.9", 72 | "@babel/plugin-proposal-json-strings": "^7.16.7", 73 | "@babel/plugin-proposal-numeric-separator": "^7.16.7", 74 | "@babel/plugin-proposal-throw-expressions": "^7.25.9", 75 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 76 | "@babel/plugin-syntax-import-meta": "^7.10.4", 77 | "@babel/plugin-transform-modules-commonjs": "^7.26.3", 78 | "@babel/plugin-transform-runtime": "^7.26.9", 79 | "@babel/preset-env": "^7.26.9", 80 | "@babel/runtime": "^7.26.9", 81 | "axios-mock-adapter": "^2.1.0", 82 | "babel-eslint": "^10.1.0", 83 | "babel-loader": "^9.2.1", 84 | "chalk": "^4.1.2", 85 | "eslint": "^8.2.0", 86 | "eslint-config-airbnb-base": "^15.0.0", 87 | "eslint-friendly-formatter": "^4.0.1", 88 | "eslint-import-resolver-webpack": "^0.13.10", 89 | "eslint-plugin-import": "^2.31.0", 90 | "eslint-plugin-jasmine": "^4.2.2", 91 | "eslint-webpack-plugin": "^4.2.0", 92 | "faker": "^5.5.3", 93 | "is-docker": "^2.2.1", 94 | "jasmine": "^4.0.2", 95 | "jasmine-core": "^4.0.1", 96 | "karma": "^6.3.17", 97 | "karma-chrome-launcher": "^3.1.0", 98 | "karma-firefox-launcher": "^2.1.2", 99 | "karma-jasmine": "^4.0.2", 100 | "karma-sourcemap-loader": "^0.3.7", 101 | "karma-spec-reporter": "0.0.33", 102 | "karma-webpack": "^5.0.0", 103 | "lodash": "^4.17.21", 104 | "ora": "^5.4.1", 105 | "rimraf": "^3.0.2", 106 | "terser-webpack-plugin": "^5.3.1", 107 | "webpack": "^5.76.0", 108 | "webpack-cli": "^5.1.1", 109 | "webpack-merge": "^5.8.0" 110 | }, 111 | "engines": { 112 | "node": ">= 14.0.0", 113 | "npm": ">= 8.0.0" 114 | }, 115 | "browserslist": [ 116 | "> 1%", 117 | "last 2 versions", 118 | "not ie <= 10" 119 | ] 120 | } 121 | -------------------------------------------------------------------------------- /src/Constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | export default { 9 | BASIC_AUTHENTICATION: 'BASIC_AUTH', 10 | APIKEY_IDENTIFICATION: 'APIKEY', 11 | ANONYMOUS_IDENTIFICATION: 'ANONYMOUS', 12 | 13 | ACTIVE: 'active', 14 | NUMBER: 'number', 15 | NAME: 'name', 16 | VERSION: 'version', 17 | DELETED: 'deleted', 18 | CASCADE: 'forceCascade', 19 | PRICE: 'price', 20 | DISCOUNT: 'discount', 21 | CURRENCY: 'currency', 22 | IN_USE: 'inUse', 23 | FILTER: 'filter', 24 | BASE_URL: 'baseUrl', 25 | USERNAME: 'username', 26 | PASSWORD: 'password', 27 | SECURITY_MODE: 'securityMode', 28 | 29 | LicensingModel: { 30 | VALID: 'valid', 31 | TryAndBuy: { 32 | NAME: 'TryAndBuy', 33 | }, 34 | Rental: { 35 | NAME: 'Rental', 36 | RED_THRESHOLD: 'redThreshold', 37 | YELLOW_THRESHOLD: 'yellowThreshold', 38 | }, 39 | Subscription: { 40 | NAME: 'Subscription', 41 | }, 42 | Floating: { 43 | NAME: 'Floating', 44 | }, 45 | MultiFeature: { 46 | NAME: 'MultiFeature', 47 | }, 48 | PayPerUse: { 49 | NAME: 'PayPerUse', 50 | }, 51 | PricingTable: { 52 | NAME: 'PricingTable', 53 | }, 54 | Quota: { 55 | NAME: 'Quota', 56 | }, 57 | NodeLocked: { 58 | NAME: 'NodeLocked', 59 | }, 60 | }, 61 | 62 | Vendor: { 63 | VENDOR_NUMBER: 'vendorNumber', 64 | VENDOR_TYPE: 'Vendor', 65 | }, 66 | 67 | Product: { 68 | ENDPOINT_PATH: 'product', 69 | PRODUCT_NUMBER: 'productNumber', 70 | LICENSEE_AUTO_CREATE: 'licenseeAutoCreate', 71 | DESCRIPTION: 'description', 72 | LICENSING_INFO: 'licensingInfo', 73 | DISCOUNTS: 'discounts', 74 | /** 75 | * @deprecated use ProductModule.PROP_LICENSEE_SECRET_MODE instead 76 | */ 77 | PROP_LICENSEE_SECRET_MODE: 'licenseeSecretMode', 78 | PROP_VAT_MODE: 'vatMode', 79 | 80 | Discount: { 81 | TOTAL_PRICE: 'totalPrice', 82 | AMOUNT_FIX: 'amountFix', 83 | AMOUNT_PERCENT: 'amountPercent', 84 | }, 85 | 86 | LicenseeSecretMode: { 87 | /** 88 | * @deprecated DISABLED mode is deprecated 89 | */ 90 | DISABLED: 'DISABLED', 91 | PREDEFINED: 'PREDEFINED', 92 | CLIENT: 'CLIENT', 93 | }, 94 | }, 95 | 96 | ProductModule: { 97 | ENDPOINT_PATH: 'productmodule', 98 | PRODUCT_MODULE_NUMBER: 'productModuleNumber', 99 | PRODUCT_MODULE_NAME: 'productModuleName', 100 | LICENSING_MODEL: 'licensingModel', 101 | PROP_LICENSEE_SECRET_MODE: 'licenseeSecretMode', 102 | }, 103 | 104 | LicenseTemplate: { 105 | ENDPOINT_PATH: 'licensetemplate', 106 | LICENSE_TEMPLATE_NUMBER: 'licenseTemplateNumber', 107 | LICENSE_TYPE: 'licenseType', 108 | AUTOMATIC: 'automatic', 109 | HIDDEN: 'hidden', 110 | HIDE_LICENSES: 'hideLicenses', 111 | PROP_LICENSEE_SECRET: 'licenseeSecret', 112 | LicenseType: { 113 | FEATURE: 'FEATURE', 114 | TIMEVOLUME: 'TIMEVOLUME', 115 | FLOATING: 'FLOATING', 116 | QUANTITY: 'QUANTITY', 117 | }, 118 | }, 119 | 120 | Token: { 121 | ENDPOINT_PATH: 'token', 122 | EXPIRATION_TIME: 'expirationTime', 123 | TOKEN_TYPE: 'tokenType', 124 | API_KEY: 'apiKey', 125 | TOKEN_PROP_EMAIL: 'email', 126 | TOKEN_PROP_VENDORNUMBER: 'vendorNumber', 127 | TOKEN_PROP_SHOP_URL: 'shopURL', 128 | Type: { 129 | DEFAULT: 'DEFAULT', 130 | SHOP: 'SHOP', 131 | APIKEY: 'APIKEY', 132 | }, 133 | }, 134 | 135 | Transaction: { 136 | ENDPOINT_PATH: 'transaction', 137 | TRANSACTION_NUMBER: 'transactionNumber', 138 | GRAND_TOTAL: 'grandTotal', 139 | STATUS: 'status', 140 | SOURCE: 'source', 141 | DATE_CREATED: 'datecreated', 142 | DATE_CLOSED: 'dateclosed', 143 | VAT: 'vat', 144 | VAT_MODE: 'vatMode', 145 | LICENSE_TRANSACTION_JOIN: 'licenseTransactionJoin', 146 | SOURCE_SHOP_ONLY: 'shopOnly', 147 | /** 148 | * @deprecated 149 | */ 150 | Status: { 151 | CANCELLED: 'CANCELLED', 152 | CLOSED: 'CLOSED', 153 | PENDING: 'PENDING', 154 | }, 155 | }, 156 | 157 | Licensee: { 158 | ENDPOINT_PATH: 'licensee', 159 | ENDPOINT_PATH_VALIDATE: 'validate', 160 | ENDPOINT_PATH_TRANSFER: 'transfer', 161 | LICENSEE_NUMBER: 'licenseeNumber', 162 | SOURCE_LICENSEE_NUMBER: 'sourceLicenseeNumber', 163 | PROP_LICENSEE_NAME: 'licenseeName', 164 | /** 165 | * @deprecated use License.PROP_LICENSEE_SECRET 166 | */ 167 | PROP_LICENSEE_SECRET: 'licenseeSecret', 168 | PROP_MARKED_FOR_TRANSFER: 'markedForTransfer', 169 | }, 170 | 171 | License: { 172 | ENDPOINT_PATH: 'license', 173 | LICENSE_NUMBER: 'licenseNumber', 174 | HIDDEN: 'hidden', 175 | PROP_LICENSEE_SECRET: 'licenseeSecret', 176 | }, 177 | 178 | PaymentMethod: { 179 | ENDPOINT_PATH: 'paymentmethod', 180 | }, 181 | 182 | Utility: { 183 | ENDPOINT_PATH: 'utility', 184 | ENDPOINT_PATH_LICENSE_TYPES: 'licenseTypes', 185 | ENDPOINT_PATH_LICENSING_MODELS: 'licensingModels', 186 | ENDPOINT_PATH_COUNTRIES: 'countries', 187 | LICENSING_MODEL_PROPERTIES: 'LicensingModelProperties', 188 | LICENSE_TYPE: 'LicenseType', 189 | }, 190 | 191 | APIKEY: { 192 | ROLE_APIKEY_LICENSEE: 'ROLE_APIKEY_LICENSEE', 193 | ROLE_APIKEY_ANALYTICS: 'ROLE_APIKEY_ANALYTICS', 194 | ROLE_APIKEY_OPERATION: 'ROLE_APIKEY_OPERATION', 195 | ROLE_APIKEY_MAINTENANCE: 'ROLE_APIKEY_MAINTENANCE', 196 | ROLE_APIKEY_ADMIN: 'ROLE_APIKEY_ADMIN', 197 | }, 198 | 199 | Validation: { 200 | FOR_OFFLINE_USE: 'forOfflineUse', 201 | }, 202 | 203 | WarningLevel: { 204 | GREEN: 'GREEN', 205 | YELLOW: 'YELLOW', 206 | RED: 'RED', 207 | }, 208 | 209 | Bundle: { 210 | ENDPOINT_PATH: 'bundle', 211 | ENDPOINT_OBTAIN_PATH: 'obtain', 212 | }, 213 | 214 | Notification: { 215 | ENDPOINT_PATH: 'notification', 216 | Protocol: { 217 | WEBHOOK: 'WEBHOOK', 218 | }, 219 | Event: { 220 | LICENSEE_CREATED: 'LICENSEE_CREATED', 221 | LICENSE_CREATED: 'LICENSE_CREATED', 222 | WARNING_LEVEL_CHANGED: 'WARNING_LEVEL_CHANGED', 223 | PAYMENT_TRANSACTION_PROCESSED: 'PAYMENT_TRANSACTION_PROCESSED', 224 | }, 225 | }, 226 | }; 227 | -------------------------------------------------------------------------------- /src/converters/itemToBundle.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Bundle from '../entities/Bundle'; 3 | 4 | export default (item) => new Bundle(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToCountry.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Country from '../entities/Country'; 3 | 4 | export default (item) => new Country(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToLicense.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import License from '../entities/License'; 3 | 4 | export default (item) => new License(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToLicenseTemplate.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import LicenseTemplate from '../entities/LicenseTemplate'; 3 | 4 | export default (item) => new LicenseTemplate(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToLicensee.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Licensee from '../entities/Licensee'; 3 | 4 | export default (item) => new Licensee(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToNotification.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Notification from '../entities/Notification'; 3 | 4 | export default (item) => new Notification(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToObject.js: -------------------------------------------------------------------------------- 1 | const itemToObject = (item) => { 2 | const object = {}; 3 | const { property, list } = item; 4 | 5 | if (property && Array.isArray(property)) { 6 | property.forEach((p) => { 7 | const { name, value } = p; 8 | if (name) object[name] = value; 9 | }); 10 | } 11 | 12 | if (list && Array.isArray(list)) { 13 | list.forEach((l) => { 14 | const { name } = l; 15 | if (name) { 16 | object[name] = object[name] || []; 17 | object[name].push(itemToObject(l)); 18 | } 19 | }); 20 | } 21 | 22 | return object; 23 | }; 24 | 25 | export default itemToObject; 26 | -------------------------------------------------------------------------------- /src/converters/itemToPaymentMethod.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import PaymentMethod from '../entities/PaymentMethod'; 3 | 4 | export default (item) => new PaymentMethod(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToProduct.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Product from '../entities/Product'; 3 | 4 | export default (item) => { 5 | const object = itemToObject(item); 6 | 7 | const discounts = object.discount; 8 | 9 | delete object.discount; 10 | 11 | const product = new Product(object); 12 | product.setProductDiscounts(discounts); 13 | 14 | return product; 15 | }; 16 | -------------------------------------------------------------------------------- /src/converters/itemToProductModule.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import ProductModule from '../entities/ProductModule'; 3 | 4 | export default (item) => new ProductModule(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToToken.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Token from '../entities/Token'; 3 | 4 | export default (item) => new Token(itemToObject(item)); 5 | -------------------------------------------------------------------------------- /src/converters/itemToTransaction.js: -------------------------------------------------------------------------------- 1 | import itemToObject from './itemToObject'; 2 | import Transaction from '../entities/Transaction'; 3 | import License from '../entities/License'; 4 | import LicenseTransactionJoin from '../entities/LicenseTransactionJoin'; 5 | import Constants from '../Constants'; 6 | 7 | export default (item) => { 8 | const object = itemToObject(item); 9 | 10 | const { licenseTransactionJoin } = object; 11 | 12 | delete object.licenseTransactionJoin; 13 | 14 | const transaction = new Transaction(object); 15 | 16 | if (licenseTransactionJoin) { 17 | const joins = []; 18 | 19 | licenseTransactionJoin.forEach((v) => { 20 | const join = new LicenseTransactionJoin(); 21 | join.setLicense(new License({ number: v[Constants.License.LICENSE_NUMBER] })); 22 | join.setTransaction(new Transaction({ number: v[Constants.Transaction.TRANSACTION_NUMBER] })); 23 | 24 | joins.push(join); 25 | }); 26 | 27 | transaction.setLicenseTransactionJoins(joins); 28 | } 29 | 30 | return transaction; 31 | }; 32 | -------------------------------------------------------------------------------- /src/entities/BaseEntity.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import CheckUtils from '../util/CheckUtils'; 9 | import CastsUtils from '../util/CastsUtils'; 10 | 11 | /** 12 | * The entity properties. 13 | * @type {{}} 14 | * @private 15 | */ 16 | const propertiesMap = new WeakMap(); 17 | 18 | /** 19 | * List of properties that was defined 20 | * @type {{}} 21 | * @private 22 | */ 23 | 24 | const definedMap = new WeakMap(); 25 | 26 | /** 27 | * List of properties that need be casts 28 | * @type {{}} 29 | * @private 30 | */ 31 | const castsMap = new WeakMap(); 32 | 33 | export default class BaseEntity { 34 | constructor({ properties, casts }) { 35 | propertiesMap.set(this, {}); 36 | definedMap.set(this, {}); 37 | castsMap.set(this, casts || []); 38 | 39 | if (properties) { 40 | this.setProperties(properties); 41 | } 42 | } 43 | 44 | /** 45 | * Set a given property on the entity. 46 | * @param property 47 | * @param value 48 | * @returns {BaseEntity} 49 | */ 50 | setProperty(property, value) { 51 | // if property name has bad native type 52 | if (!CheckUtils.isValid(property) || typeof property === 'object') { 53 | throw new TypeError(`Bad property name:${property}`); 54 | } 55 | 56 | const castedValue = this.cast(property, value); 57 | 58 | // define to property 59 | this.define(property); 60 | 61 | // save property to propertiesMap 62 | const properties = propertiesMap.get(this); 63 | properties[property] = castedValue; 64 | 65 | return this; 66 | } 67 | 68 | /** 69 | * Alias for setProperty 70 | * @param property 71 | * @param value 72 | * @returns {BaseEntity} 73 | */ 74 | addProperty(property, value) { 75 | return this.setProperty(property, value); 76 | } 77 | 78 | /** 79 | * Set the entity properties. 80 | * @param properties 81 | * @returns {BaseEntity} 82 | */ 83 | setProperties(properties) { 84 | this.removeProperties(); 85 | 86 | const has = Object.prototype.hasOwnProperty; 87 | 88 | Object.keys(properties).forEach((key) => { 89 | if (has.call(properties, key)) { 90 | this.setProperty(key, properties[key]); 91 | } 92 | }); 93 | 94 | return this; 95 | } 96 | 97 | /** 98 | * Check if we has property 99 | * @param property 100 | * @protected 101 | */ 102 | hasProperty(property) { 103 | return Object.prototype.hasOwnProperty.call(propertiesMap.get(this), property); 104 | } 105 | 106 | /** 107 | * Get an property from the entity. 108 | * @param property 109 | * @param def 110 | * @returns {*} 111 | */ 112 | getProperty(property, def) { 113 | return Object.prototype.hasOwnProperty.call(propertiesMap.get(this), property) 114 | ? propertiesMap.get(this)[property] 115 | : def; 116 | } 117 | 118 | /** 119 | * Get all of the current properties on the entity. 120 | */ 121 | getProperties() { 122 | return { ...propertiesMap.get(this) }; 123 | } 124 | 125 | /** 126 | * Remove property 127 | * @param property 128 | * @returns {BaseEntity} 129 | */ 130 | removeProperty(property) { 131 | const properties = propertiesMap.get(this); 132 | delete properties[property]; 133 | this.removeDefine(property); 134 | return this; 135 | } 136 | 137 | /** 138 | * Remove properties 139 | * @param properties 140 | */ 141 | removeProperties(properties) { 142 | const propertiesForRemove = properties || Object.keys(propertiesMap.get(this)); 143 | 144 | propertiesForRemove.forEach((property) => { 145 | this.removeProperty(property); 146 | }); 147 | } 148 | 149 | cast(property, value) { 150 | if (!castsMap.get(this)[property]) return value; 151 | 152 | return CastsUtils(castsMap.get(this)[property], value); 153 | } 154 | 155 | /** 156 | * Check if property has defined 157 | * @param property 158 | * @protected 159 | */ 160 | hasDefine(property) { 161 | return Boolean(definedMap.get(this)[property]); 162 | } 163 | 164 | /** 165 | * Define property getter and setter 166 | * @param property 167 | * @protected 168 | */ 169 | define(property) { 170 | if (this.hasDefine(property)) return; 171 | 172 | if (!CheckUtils.isValid(property) || typeof property === 'object') { 173 | throw new TypeError(`Bad property name:${property}`); 174 | } 175 | 176 | const self = this; 177 | 178 | // delete property 179 | delete this[property]; 180 | 181 | const descriptors = { 182 | enumerable: true, 183 | configurable: true, 184 | get() { 185 | return self.getProperty(property); 186 | }, 187 | 188 | set(value) { 189 | self.setProperty(property, value); 190 | }, 191 | }; 192 | 193 | const defined = definedMap.get(this); 194 | defined[property] = true; 195 | 196 | Object.defineProperty(this, property, descriptors); 197 | } 198 | 199 | /** 200 | * Remove property getter and setter 201 | * @param property 202 | * @protected 203 | */ 204 | removeDefine(property) { 205 | if (!this.hasDefine(property)) return; 206 | 207 | const defined = definedMap.get(this); 208 | delete defined[property]; 209 | 210 | delete this[property]; 211 | } 212 | 213 | /** 214 | * Get properties map 215 | */ 216 | asPropertiesMap() { 217 | const properties = this.getProperties(); 218 | const customProperties = {}; 219 | 220 | const has = Object.prototype.hasOwnProperty; 221 | 222 | Object.keys(this).forEach((key) => { 223 | if (!has.call(this, key)) return; 224 | 225 | customProperties[key] = this[key]; 226 | }); 227 | 228 | return { ...customProperties, ...properties }; 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/entities/Bundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * NetLicensing Bundle entity. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number that identifies the bundle. Vendor can assign this number when creating a bundle or 16 | * let NetLicensing generate one. 17 | * @property string number 18 | * 19 | * If set to false, the bundle is disabled. 20 | * @property boolean active 21 | * 22 | * Bundle name. 23 | * @property string name 24 | * 25 | * Price for the bundle. If >0, it must always be accompanied by the currency specification. 26 | * @property double price 27 | * 28 | * Specifies currency for the bundle price. Check data types to discover which currencies are 29 | * supported. 30 | * @property string currency 31 | * 32 | * Arbitrary additional user properties of string type may be associated with each bundle. The name of user property 33 | * must not be equal to any of the fixed property names listed above and must be none of id, deleted. 34 | * 35 | * @constructor 36 | */ 37 | export default class Bundle extends BaseEntity { 38 | constructor(properties) { 39 | super({ 40 | properties, 41 | // The attributes that should be cast to native types. 42 | casts: { 43 | number: 'string', 44 | active: 'boolean', 45 | name: 'string', 46 | price: 'double', 47 | currency: 'string', 48 | }, 49 | }); 50 | } 51 | 52 | setNumber(number) { 53 | return this.setProperty('number', number); 54 | } 55 | 56 | getNumber(def) { 57 | return this.getProperty('number', def); 58 | } 59 | 60 | setActive(active) { 61 | return this.setProperty('active', active); 62 | } 63 | 64 | getActive(def) { 65 | return this.getProperty('active', def); 66 | } 67 | 68 | setName(name) { 69 | return this.setProperty('name', name); 70 | } 71 | 72 | getName(def) { 73 | return this.getProperty('name', def); 74 | } 75 | 76 | setDescription(description) { 77 | return this.setProperty('description', description); 78 | } 79 | 80 | getDescription(def) { 81 | return this.getProperty('description', def); 82 | } 83 | 84 | setPrice(price) { 85 | return this.setProperty('price', price); 86 | } 87 | 88 | getPrice(def) { 89 | return this.getProperty('price', def); 90 | } 91 | 92 | setCurrency(currency) { 93 | return this.setProperty('currency', currency); 94 | } 95 | 96 | getCurrency(def) { 97 | return this.getProperty('currency', def); 98 | } 99 | 100 | setLicenseTemplateNumbers(licenseTemplateNumbers) { 101 | const numbers = (Array.isArray(licenseTemplateNumbers)) 102 | ? licenseTemplateNumbers.join(',') 103 | : licenseTemplateNumbers; 104 | 105 | return this.setProperty('licenseTemplateNumbers', numbers); 106 | } 107 | 108 | getLicenseTemplateNumbers(def) { 109 | const numbers = this.getProperty('licenseTemplateNumbers', def); 110 | return (numbers) ? numbers.split(',') : numbers; 111 | } 112 | 113 | addLicenseTemplateNumber(licenseTemplateNumber) { 114 | const numbers = this.getLicenseTemplateNumbers([]); 115 | numbers.push(licenseTemplateNumber); 116 | 117 | return this.setLicenseTemplateNumbers(numbers); 118 | } 119 | 120 | removeLicenseTemplateNumber(licenseTemplateNumber) { 121 | const numbers = this.getLicenseTemplateNumbers([]); 122 | numbers.splice(numbers.indexOf(licenseTemplateNumber), 1); 123 | 124 | return this.setLicenseTemplateNumbers(numbers); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/entities/Country.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * Country entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * @property code - Unique code of country. 16 | * 17 | * @property name - Unique name of country 18 | * 19 | * @property vatPercent - Country vat. 20 | * 21 | * @property isEu - is country in EU. 22 | */ 23 | export default class Country extends BaseEntity { 24 | constructor(properties) { 25 | super({ 26 | properties, 27 | // The attributes that should be cast to native types. 28 | casts: { 29 | code: 'string', 30 | name: 'string', 31 | vatPercent: 'int', 32 | isEu: 'boolean', 33 | }, 34 | }); 35 | } 36 | 37 | setCode(code) { 38 | return this.setProperty('code', code); 39 | } 40 | 41 | getCode(def) { 42 | return this.getProperty('code', def); 43 | } 44 | 45 | setName(name) { 46 | return this.setProperty('name', name); 47 | } 48 | 49 | getName(def) { 50 | return this.getProperty('name', def); 51 | } 52 | 53 | setVatPercent(vat) { 54 | return this.setProperty('vatPercent', vat); 55 | } 56 | 57 | getVatPercent(def) { 58 | return this.getProperty('vatPercent', def); 59 | } 60 | 61 | setIsEu(isEu) { 62 | return this.setProperty('isEu', isEu); 63 | } 64 | 65 | getIsEu(def) { 66 | return this.getProperty('isEu', def); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/entities/License.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * License entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number (across all products/licensees of a vendor) that identifies the license. Vendor can 16 | * assign this number when creating a license or let NetLicensing generate one. Read-only after corresponding creation 17 | * transaction status is set to closed. 18 | * @property string number 19 | * 20 | * Name for the licensed item. Set from license template on creation, if not specified explicitly. 21 | * @property string name 22 | * 23 | * If set to false, the license is disabled. License can be re-enabled, but as long as it is disabled, 24 | * the license is excluded from the validation process. 25 | * @property boolean active 26 | * 27 | * price for the license. If >0, it must always be accompanied by the currency specification. Read-only, 28 | * set from license template on creation. 29 | * @property float price 30 | * 31 | * specifies currency for the license price. Check data types to discover which currencies are 32 | * supported. Read-only, set from license template on creation. 33 | * @property string currency 34 | * 35 | * If set to true, this license is not shown in NetLicensing Shop as purchased license. Set from license 36 | * template on creation, if not specified explicitly. 37 | * @property boolean hidden 38 | * 39 | * @property string startDate 40 | * 41 | * Arbitrary additional user properties of string type may be associated with each license. The name of user property 42 | * must not be equal to any of the fixed property names listed above and must be none of id, deleted, licenseeNumber, 43 | * licenseTemplateNumber. 44 | */ 45 | export default class License extends BaseEntity { 46 | constructor(properties) { 47 | super({ 48 | properties, 49 | // The attributes that should be cast to native types. 50 | casts: { 51 | number: 'string', 52 | active: 'boolean', 53 | name: 'string', 54 | price: 'float', 55 | hidden: 'boolean', 56 | parentfeature: 'string', 57 | timeVolume: 'int', 58 | startDate: 'date', 59 | inUse: 'boolean', 60 | }, 61 | }); 62 | } 63 | 64 | setNumber(number) { 65 | return this.setProperty('number', number); 66 | } 67 | 68 | getNumber(def) { 69 | return this.getProperty('number', def); 70 | } 71 | 72 | setActive(active) { 73 | return this.setProperty('active', active); 74 | } 75 | 76 | getActive(def) { 77 | return this.getProperty('active', def); 78 | } 79 | 80 | setName(name) { 81 | return this.setProperty('name', name); 82 | } 83 | 84 | getName(def) { 85 | return this.getProperty('name', def); 86 | } 87 | 88 | setHidden(hidden) { 89 | return this.setProperty('hidden', hidden); 90 | } 91 | 92 | getHidden(def) { 93 | return this.getProperty('hidden', def); 94 | } 95 | 96 | setParentfeature(parentfeature) { 97 | return this.setProperty('parentfeature', parentfeature); 98 | } 99 | 100 | getParentfeature(def) { 101 | return this.getProperty('parentfeature', def); 102 | } 103 | 104 | setTimeVolume(timeVolume) { 105 | return this.setProperty('timeVolume', timeVolume); 106 | } 107 | 108 | getTimeVolume(def) { 109 | return this.getProperty('timeVolume', def); 110 | } 111 | 112 | setStartDate(startDate) { 113 | return this.setProperty('startDate', startDate); 114 | } 115 | 116 | getStartDate(def) { 117 | return this.getProperty('startDate', def); 118 | } 119 | 120 | getInUse(def) { 121 | return this.getProperty('inUse', def); 122 | } 123 | 124 | getPrice(def) { 125 | return this.getProperty('price', def); 126 | } 127 | 128 | getCurrency(def) { 129 | return this.getProperty('currency', def); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/entities/LicenseTemplate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * License template entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number (across all products of a vendor) that identifies the license template. Vendor can 16 | * assign this number when creating a license template or let NetLicensing generate one. 17 | * Read-only after creation of the first license from this license template. 18 | * @property string number 19 | * 20 | * If set to false, the license template is disabled. Licensee can not obtain any new licenses off this 21 | * license template. 22 | * @property boolean active 23 | * 24 | * Name for the licensed item. 25 | * @property string name 26 | * 27 | * Type of licenses created from this license template. Supported types: "FEATURE", "TIMEVOLUME", 28 | * "FLOATING", "QUANTITY" 29 | * @property string licenseType 30 | * 31 | * Price for the license. If >0, it must always be accompanied by the currency specification. 32 | * @property double price 33 | * 34 | * Specifies currency for the license price. Check data types to discover which currencies are 35 | * supported. 36 | * @property string currency 37 | * 38 | * If set to true, every new licensee automatically gets one license out of this license template on 39 | * creation. Automatic licenses must have their price set to 0. 40 | * @property boolean automatic 41 | * 42 | * If set to true, this license template is not shown in NetLicensing Shop as offered for purchase. 43 | * @property boolean hidden 44 | * 45 | * If set to true, licenses from this license template are not visible to the end customer, but 46 | * participate in validation. 47 | * @property boolean hideLicenses 48 | * 49 | * If set to true, this license template defines grace period of validity granted after subscription expiration. 50 | * @property boolean gracePeriod 51 | * 52 | * Mandatory for 'TIMEVOLUME' license type. 53 | * @property integer timeVolume 54 | * 55 | * Time volume period for 'TIMEVOLUME' license type. Supported types: "DAY", "WEEK", "MONTH", "YEAR" 56 | * @property integer timeVolumePeriod 57 | * 58 | * Mandatory for 'FLOATING' license type. 59 | * @property integer maxSessions 60 | * 61 | * Mandatory for 'QUANTITY' license type. 62 | * @property integer quantity 63 | * 64 | * @constructor 65 | */ 66 | export default class LicenseTemplate extends BaseEntity { 67 | constructor(properties) { 68 | super({ 69 | properties, 70 | // The attributes that should be cast to native types. 71 | casts: { 72 | number: 'string', 73 | active: 'boolean', 74 | name: 'string', 75 | licenseType: 'string', 76 | price: 'double', 77 | currency: 'string', 78 | automatic: 'boolean', 79 | hidden: 'boolean', 80 | hideLicenses: 'boolean', 81 | gracePeriod: 'boolean', 82 | timeVolume: 'int', 83 | timeVolumePeriod: 'string', 84 | maxSessions: 'int', 85 | quantity: 'int', 86 | inUse: 'boolean', 87 | }, 88 | }); 89 | } 90 | 91 | setNumber(number) { 92 | return this.setProperty('number', number); 93 | } 94 | 95 | getNumber(def) { 96 | return this.getProperty('number', def); 97 | } 98 | 99 | setActive(active) { 100 | return this.setProperty('active', active); 101 | } 102 | 103 | getActive(def) { 104 | return this.getProperty('active', def); 105 | } 106 | 107 | setName(name) { 108 | return this.setProperty('name', name); 109 | } 110 | 111 | getName(def) { 112 | return this.getProperty('name', def); 113 | } 114 | 115 | setLicenseType(licenseType) { 116 | return this.setProperty('licenseType', licenseType); 117 | } 118 | 119 | getLicenseType(def) { 120 | return this.getProperty('licenseType', def); 121 | } 122 | 123 | setPrice(price) { 124 | return this.setProperty('price', price); 125 | } 126 | 127 | getPrice(def) { 128 | return this.getProperty('price', def); 129 | } 130 | 131 | setCurrency(currency) { 132 | return this.setProperty('currency', currency); 133 | } 134 | 135 | getCurrency(def) { 136 | return this.getProperty('currency', def); 137 | } 138 | 139 | setAutomatic(automatic) { 140 | return this.setProperty('automatic', automatic); 141 | } 142 | 143 | getAutomatic(def) { 144 | return this.getProperty('automatic', def); 145 | } 146 | 147 | setHidden(hidden) { 148 | return this.setProperty('hidden', hidden); 149 | } 150 | 151 | getHidden(def) { 152 | return this.getProperty('hidden', def); 153 | } 154 | 155 | setHideLicenses(hideLicenses) { 156 | return this.setProperty('hideLicenses', hideLicenses); 157 | } 158 | 159 | getHideLicenses(def) { 160 | return this.getProperty('hideLicenses', def); 161 | } 162 | 163 | setTimeVolume(timeVolume) { 164 | return this.setProperty('timeVolume', timeVolume); 165 | } 166 | 167 | getTimeVolume(def) { 168 | return this.getProperty('timeVolume', def); 169 | } 170 | 171 | setTimeVolumePeriod(timeVolumePeriod) { 172 | return this.setProperty('timeVolumePeriod', timeVolumePeriod); 173 | } 174 | 175 | getTimeVolumePeriod(def) { 176 | return this.getProperty('timeVolumePeriod', def); 177 | } 178 | 179 | setMaxSessions(maxSessions) { 180 | return this.setProperty('maxSessions', maxSessions); 181 | } 182 | 183 | getMaxSessions(def) { 184 | return this.getProperty('maxSessions', def); 185 | } 186 | 187 | setQuantity(quantity) { 188 | return this.setProperty('quantity', quantity); 189 | } 190 | 191 | getQuantity(def) { 192 | return this.getProperty('quantity', def); 193 | } 194 | 195 | getInUse(def) { 196 | return this.getProperty('inUse', def); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/entities/LicenseTransactionJoin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | export default class LicenseTransactionJoin { 8 | constructor(transaction, license) { 9 | this.transaction = transaction; 10 | this.license = license; 11 | } 12 | 13 | setTransaction(transaction) { 14 | this.transaction = transaction; 15 | return this; 16 | } 17 | 18 | getTransaction(def) { 19 | return this.transaction || def; 20 | } 21 | 22 | setLicense(license) { 23 | this.license = license; 24 | return this; 25 | } 26 | 27 | getLicense(def) { 28 | return this.license || def; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/entities/Licensee.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * Licensee entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number (across all products of a vendor) that identifies the licensee. Vendor can assign this 16 | * number when creating a licensee or let NetLicensing generate one. Read-only after creation of the first license for 17 | * the licensee. 18 | * @property string number 19 | * 20 | * Licensee name. 21 | * @property string name 22 | * 23 | * If set to false, the licensee is disabled. Licensee can not obtain new licenses, and validation is 24 | * disabled (tbd). 25 | * @property boolean active 26 | * 27 | * Licensee Secret for licensee 28 | * @property string licenseeSecret 29 | * 30 | * Mark licensee for transfer. 31 | * @property boolean markedForTransfer 32 | * 33 | * Arbitrary additional user properties of string type may be associated with each licensee. The name of user property 34 | * must not be equal to any of the fixed property names listed above and must be none of id, deleted, productNumber 35 | * 36 | * @constructor 37 | */ 38 | export default class Licensee extends BaseEntity { 39 | constructor(properties) { 40 | super({ 41 | properties, 42 | // The attributes that should be cast to native types. 43 | casts: { 44 | number: 'string', 45 | active: 'boolean', 46 | name: 'string', 47 | licenseeSecret: 'string', 48 | markedForTransfer: 'boolean', 49 | inUse: 'boolean', 50 | }, 51 | }); 52 | } 53 | 54 | setNumber(number) { 55 | return this.setProperty('number', number); 56 | } 57 | 58 | getNumber(def) { 59 | return this.getProperty('number', def); 60 | } 61 | 62 | setActive(active) { 63 | return this.setProperty('active', active); 64 | } 65 | 66 | getActive(def) { 67 | return this.getProperty('active', def); 68 | } 69 | 70 | setName(name) { 71 | return this.setProperty('name', name); 72 | } 73 | 74 | getName(def) { 75 | return this.getProperty('name', def); 76 | } 77 | 78 | setProductNumber(productNumber) { 79 | return this.setProperty('productNumber', productNumber); 80 | } 81 | 82 | getProductNumber(def) { 83 | return this.getProperty('productNumber', def); 84 | } 85 | 86 | /** 87 | * @deprecated 88 | */ 89 | setLicenseeSecret(licenseeSecret) { 90 | return this.setProperty('licenseeSecret', licenseeSecret); 91 | } 92 | 93 | /** 94 | * @deprecated 95 | */ 96 | getLicenseeSecret(def) { 97 | return this.getProperty('licenseeSecret', def); 98 | } 99 | 100 | setMarkedForTransfer(markedForTransfer) { 101 | return this.setProperty('markedForTransfer', markedForTransfer); 102 | } 103 | 104 | getMarkedForTransfer(def) { 105 | return this.getProperty('markedForTransfer', def); 106 | } 107 | 108 | getInUse(def) { 109 | return this.getProperty('inUse', def); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/entities/Notification.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * NetLicensing Notification entity. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number that identifies the notification. Vendor can assign this number when creating a notification or 16 | * let NetLicensing generate one. 17 | * @property string number 18 | * 19 | * If set to false, the notification is disabled. The notification will not be fired when the event triggered. 20 | * @property boolean active 21 | * 22 | * Notification name. 23 | * @property string name 24 | * 25 | * Notification type. Indicate the method of transmitting notification, ex: EMAIL, WEBHOOK. 26 | * @property float type 27 | * 28 | * Comma separated string of events that fire the notification when emitted. 29 | * @property string events 30 | * 31 | * Notification response payload. 32 | * @property string payload 33 | * 34 | * Notification response url. Optional. Uses only for WEBHOOK type notification. 35 | * @property string url 36 | * 37 | * Arbitrary additional user properties of string type may be associated with each notification. The name of user property 38 | * must not be equal to any of the fixed property names listed above and must be none of id, deleted. 39 | * 40 | * @constructor 41 | */ 42 | export default class Notification extends BaseEntity { 43 | constructor(properties) { 44 | super({ 45 | properties, 46 | // The attributes that should be cast to native types. 47 | casts: { 48 | number: 'string', 49 | active: 'boolean', 50 | name: 'string', 51 | protocol: 'string', 52 | events: 'string', 53 | payload: 'string', 54 | endpoint: 'string', 55 | }, 56 | }); 57 | } 58 | 59 | setNumber(number) { 60 | return this.setProperty('number', number); 61 | } 62 | 63 | getNumber(def) { 64 | return this.getProperty('number', def); 65 | } 66 | 67 | setActive(active) { 68 | return this.setProperty('active', active); 69 | } 70 | 71 | getActive(def) { 72 | return this.getProperty('active', def); 73 | } 74 | 75 | setName(name) { 76 | return this.setProperty('name', name); 77 | } 78 | 79 | getName(def) { 80 | return this.getProperty('name', def); 81 | } 82 | 83 | setProtocol(type) { 84 | return this.setProperty('protocol', type); 85 | } 86 | 87 | getProtocol(def) { 88 | return this.getProperty('protocol', def); 89 | } 90 | 91 | setEvents(events) { 92 | return this.setProperty('events', events); 93 | } 94 | 95 | getEvents(def) { 96 | return this.getProperty('events', def); 97 | } 98 | 99 | setPayload(payload) { 100 | return this.setProperty('payload', payload); 101 | } 102 | 103 | getPayload(def) { 104 | return this.getProperty('payload', def); 105 | } 106 | 107 | setEndpoint(endpoint) { 108 | return this.setProperty('endpoint', endpoint); 109 | } 110 | 111 | getEndpoint(def) { 112 | return this.getProperty('endpoint', def); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/entities/PaymentMethod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * PaymentMethod entity used internally by NetLicensing. 12 | * 13 | * @property string number 14 | * @property boolean active 15 | * 16 | * @constructor 17 | */ 18 | export default class PaymentMethod extends BaseEntity { 19 | constructor(properties) { 20 | super({ 21 | properties, 22 | // The attributes that should be cast to native types. 23 | casts: { 24 | number: 'string', 25 | active: 'boolean', 26 | 'paypal.subject': 'string', 27 | }, 28 | }); 29 | } 30 | 31 | setNumber(number) { 32 | return this.setProperty('number', number); 33 | } 34 | 35 | getNumber(def) { 36 | return this.getProperty('number', def); 37 | } 38 | 39 | setActive(active) { 40 | return this.setProperty('active', active); 41 | } 42 | 43 | getActive(def) { 44 | return this.getProperty('active', def); 45 | } 46 | 47 | setPaypalSubject(paypalSubject) { 48 | return this.setProperty('paypal.subject', paypalSubject); 49 | } 50 | 51 | getPaypalSubject(def) { 52 | return this.getProperty('paypal.subject', def); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/entities/Product.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | import ProductDiscount from './ProductDiscount'; 10 | 11 | /** 12 | * The discounts map 13 | * @type {{}} 14 | * @private 15 | */ 16 | const discountsMap = new WeakMap(); 17 | 18 | /** 19 | * An identifier that show if discounts was touched 20 | * @type {{}} 21 | * @private 22 | */ 23 | const discountsTouched = new WeakMap(); 24 | 25 | /** 26 | * NetLicensing Product entity. 27 | * 28 | * Properties visible via NetLicensing API: 29 | * 30 | * Unique number that identifies the product. Vendor can assign this number when creating a product or 31 | * let NetLicensing generate one. Read-only after creation of the first licensee for the product. 32 | * @property string number 33 | * 34 | * If set to false, the product is disabled. No new licensees can be registered for the product, 35 | * existing licensees can not obtain new licenses. 36 | * @property boolean active 37 | * 38 | * Product name. Together with the version identifies the product for the end customer. 39 | * @property string name 40 | * 41 | * Product version. Convenience parameter, additional to the product name. 42 | * @property float version 43 | * 44 | * If set to 'true', non-existing licensees will be created at first validation attempt. 45 | * @property boolean licenseeAutoCreate 46 | * 47 | * Licensee secret mode for product.Supported types: "DISABLED", "PREDEFINED", "CLIENT" 48 | * @property boolean licenseeSecretMode 49 | * 50 | * Product description. Optional. 51 | * @property string description 52 | * 53 | * Licensing information. Optional. 54 | * @property string licensingInfo 55 | * 56 | * @property boolean inUse 57 | * 58 | * Arbitrary additional user properties of string type may be associated with each product. The name of user property 59 | * must not be equal to any of the fixed property names listed above and must be none of id, deleted. 60 | * 61 | * @constructor 62 | */ 63 | export default class Product extends BaseEntity { 64 | constructor(properties) { 65 | super({ 66 | properties, 67 | // The attributes that should be cast to native types. 68 | casts: { 69 | number: 'string', 70 | active: 'boolean', 71 | name: 'string', 72 | version: 'string', 73 | description: 'string', 74 | licensingInfo: 'string', 75 | licenseeAutoCreate: 'boolean', 76 | licenseeSecretMode: 'string', 77 | inUse: 'boolean', 78 | }, 79 | }); 80 | 81 | discountsMap.set(this, []); 82 | discountsTouched.set(this, false); 83 | } 84 | 85 | setNumber(number) { 86 | return this.setProperty('number', number); 87 | } 88 | 89 | getNumber(def) { 90 | return this.getProperty('number', def); 91 | } 92 | 93 | setActive(active) { 94 | return this.setProperty('active', active); 95 | } 96 | 97 | getActive(def) { 98 | return this.getProperty('active', def); 99 | } 100 | 101 | setName(name) { 102 | return this.setProperty('name', name); 103 | } 104 | 105 | getName(def) { 106 | return this.getProperty('name', def); 107 | } 108 | 109 | setVersion(version) { 110 | return this.setProperty('version', version); 111 | } 112 | 113 | getVersion(def) { 114 | return this.getProperty('version', def); 115 | } 116 | 117 | setLicenseeAutoCreate(licenseeAutoCreate) { 118 | return this.setProperty('licenseeAutoCreate', licenseeAutoCreate); 119 | } 120 | 121 | getLicenseeAutoCreate(def) { 122 | return this.getProperty('licenseeAutoCreate', def); 123 | } 124 | 125 | /** 126 | * @deprecated use ProductModule.setLicenseeSecretMode instead 127 | */ 128 | setLicenseeSecretMode(licenseeSecretMode) { 129 | return this.setProperty('licenseeSecretMode', licenseeSecretMode); 130 | } 131 | 132 | /** 133 | * @deprecated use ProductModule.getLicenseeSecretMode instead 134 | */ 135 | getLicenseeSecretMode(def) { 136 | return this.getProperty('licenseeSecretMode', def); 137 | } 138 | 139 | setDescription(description) { 140 | return this.setProperty('description', description); 141 | } 142 | 143 | getDescription(def) { 144 | return this.getProperty('description', def); 145 | } 146 | 147 | setLicensingInfo(licensingInfo) { 148 | return this.setProperty('licensingInfo', licensingInfo); 149 | } 150 | 151 | getLicensingInfo(def) { 152 | return this.getProperty('licensingInfo', def); 153 | } 154 | 155 | getInUse(def) { 156 | return this.getProperty('inUse', def); 157 | } 158 | 159 | /** 160 | * Add discount to product 161 | * 162 | * @param discount NetLicensing.ProductDiscount 163 | * @returns {NetLicensing.Product} 164 | */ 165 | addDiscount(discount) { 166 | const discounts = discountsMap.get(this); 167 | 168 | let productDiscount = discount; 169 | 170 | if (typeof productDiscount !== 'string' && !(productDiscount instanceof ProductDiscount)) { 171 | productDiscount = new ProductDiscount(productDiscount); 172 | } 173 | 174 | discounts.push(productDiscount); 175 | discountsMap.set(this, discounts); 176 | discountsTouched.set(this, true); 177 | 178 | return this; 179 | } 180 | 181 | /** 182 | * Set discounts to product 183 | * @param discounts 184 | */ 185 | setProductDiscounts(discounts) { 186 | discountsMap.set(this, []); 187 | discountsTouched.set(this, true); 188 | 189 | if (!discounts) return this; 190 | 191 | if (Array.isArray(discounts)) { 192 | discounts.forEach((discount) => { 193 | this.addDiscount(discount); 194 | }); 195 | 196 | return this; 197 | } 198 | 199 | this.addDiscount(discounts); 200 | 201 | return this; 202 | } 203 | 204 | /** 205 | * Get array of objects discounts 206 | * @returns {Array} 207 | */ 208 | getProductDiscounts() { 209 | return Object.assign([], discountsMap.get(this)); 210 | } 211 | 212 | asPropertiesMap() { 213 | const propertiesMap = super.asPropertiesMap(); 214 | 215 | if (discountsMap.get(this).length) { 216 | propertiesMap.discount = discountsMap.get(this).map((discount) => discount.toString()); 217 | } 218 | 219 | if (!propertiesMap.discount && discountsTouched.get(this)) { 220 | propertiesMap.discount = ''; 221 | } 222 | 223 | return propertiesMap; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/entities/ProductDiscount.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | import BaseEntity from './BaseEntity'; 8 | 9 | export default class ProductDiscount extends BaseEntity { 10 | constructor(properties) { 11 | super({ 12 | properties, 13 | // The attributes that should be cast to native types. 14 | casts: { 15 | totalPrice: 'float', 16 | currency: 'string', 17 | amountFix: 'float', 18 | amountPercent: 'int', 19 | }, 20 | }); 21 | } 22 | 23 | setTotalPrice(totalPrice) { 24 | return this.setProperty('totalPrice', totalPrice); 25 | } 26 | 27 | getTotalPrice(def) { 28 | return this.getProperty('totalPrice', def); 29 | } 30 | 31 | setCurrency(currency) { 32 | return this.setProperty('currency', currency); 33 | } 34 | 35 | getCurrency(def) { 36 | return this.getProperty('currency', def); 37 | } 38 | 39 | setAmountFix(amountFix) { 40 | return this.setProperty('amountFix', amountFix).removeProperty('amountPercent'); 41 | } 42 | 43 | getAmountFix(def) { 44 | return this.getProperty('amountFix', def); 45 | } 46 | 47 | setAmountPercent(amountPercent) { 48 | return this.setProperty('amountPercent', amountPercent).removeProperty('amountFix'); 49 | } 50 | 51 | getAmountPercent(def) { 52 | return this.getProperty('amountPercent', def); 53 | } 54 | 55 | toString() { 56 | const totalPrice = this.getTotalPrice(); 57 | const currency = this.getCurrency(); 58 | let amount = 0; 59 | 60 | if (this.getAmountFix(null)) amount = this.getAmountFix(); 61 | if (this.getAmountPercent(null)) amount = `${this.getAmountPercent()}%`; 62 | 63 | return `${totalPrice};${currency};${amount}`; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/entities/ProductModule.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * Product module entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number (across all products of a vendor) that identifies the product module. Vendor can assign 16 | * this number when creating a product module or let NetLicensing generate one. Read-only after creation of the first 17 | * licensee for the product. 18 | * @property string number 19 | * 20 | * If set to false, the product module is disabled. Licensees can not obtain any new licenses for this 21 | * product module. 22 | * @property boolean active 23 | * 24 | * Product module name that is visible to the end customers in NetLicensing Shop. 25 | * @property string name 26 | * 27 | * Licensing model applied to this product module. Defines what license templates can be 28 | * configured for the product module and how licenses for this product module are processed during validation. 29 | * @property string licensingModel 30 | * 31 | * Maximum checkout validity (days). Mandatory for 'Floating' licensing model. 32 | * @property integer maxCheckoutValidity 33 | * 34 | * Remaining time volume for yellow level. Mandatory for 'Rental' licensing model. 35 | * @property integer yellowThreshold 36 | * 37 | * Remaining time volume for red level. Mandatory for 'Rental' licensing model. 38 | * @property integer redThreshold 39 | * 40 | * License template. Mandatory for 'Try & Buy' licensing model. Supported types: "TIMEVOLUME", "FEATURE". 41 | * @property string licenseTemplate 42 | * 43 | * Licensee secret mode for product.Supported types: "PREDEFINED", "CLIENT" 44 | * @property boolean licenseeSecretMode 45 | * 46 | * @constructor 47 | */ 48 | export default class ProductModule extends BaseEntity { 49 | constructor(properties) { 50 | super({ 51 | properties, 52 | // The attributes that should be cast to native types. 53 | casts: { 54 | number: 'string', 55 | active: 'boolean', 56 | name: 'string', 57 | licensingModel: 'string', 58 | maxCheckoutValidity: 'int', 59 | yellowThreshold: 'int', 60 | redThreshold: 'int', 61 | licenseTemplate: 'string', 62 | inUse: 'boolean', 63 | licenseeSecretMode: 'string', 64 | }, 65 | }); 66 | } 67 | 68 | setNumber(number) { 69 | return this.setProperty('number', number); 70 | } 71 | 72 | getNumber(def) { 73 | return this.getProperty('number', def); 74 | } 75 | 76 | setActive(active) { 77 | return this.setProperty('active', active); 78 | } 79 | 80 | getActive(def) { 81 | return this.getProperty('active', def); 82 | } 83 | 84 | setName(name) { 85 | return this.setProperty('name', name); 86 | } 87 | 88 | getName(def) { 89 | return this.getProperty('name', def); 90 | } 91 | 92 | setLicensingModel(licensingModel) { 93 | return this.setProperty('licensingModel', licensingModel); 94 | } 95 | 96 | getLicensingModel(def) { 97 | return this.getProperty('licensingModel', def); 98 | } 99 | 100 | setMaxCheckoutValidity(maxCheckoutValidity) { 101 | return this.setProperty('maxCheckoutValidity', maxCheckoutValidity); 102 | } 103 | 104 | getMaxCheckoutValidity(def) { 105 | return this.getProperty('maxCheckoutValidity', def); 106 | } 107 | 108 | setYellowThreshold(yellowThreshold) { 109 | return this.setProperty('yellowThreshold', yellowThreshold); 110 | } 111 | 112 | getYellowThreshold(def) { 113 | return this.getProperty('yellowThreshold', def); 114 | } 115 | 116 | setRedThreshold(redThreshold) { 117 | return this.setProperty('redThreshold', redThreshold); 118 | } 119 | 120 | getRedThreshold(def) { 121 | return this.getProperty('redThreshold', def); 122 | } 123 | 124 | setLicenseTemplate(licenseTemplate) { 125 | return this.setProperty('licenseTemplate', licenseTemplate); 126 | } 127 | 128 | getLicenseTemplate(def) { 129 | return this.getProperty('licenseTemplate', def); 130 | } 131 | 132 | getInUse(def) { 133 | return this.getProperty('inUse', def); 134 | } 135 | 136 | setLicenseeSecretMode(licenseeSecretMode) { 137 | return this.setProperty('licenseeSecretMode', licenseeSecretMode); 138 | } 139 | 140 | getLicenseeSecretMode(def) { 141 | return this.getProperty('licenseeSecretMode', def); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/entities/Token.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | 10 | /** 11 | * Product module entity used internally by NetLicensing. 12 | * 13 | * Properties visible via NetLicensing API: 14 | * 15 | * Unique number 16 | * @property string number 17 | * 18 | * If set to false, the token is disabled. 19 | * @property boolean active 20 | * 21 | * Expiration Time 22 | * @property string expirationTime 23 | * 24 | * @property string vendorNumber 25 | * 26 | * Token type to be generated. 27 | * DEFAULT - default one-time token (will be expired after first request) 28 | * SHOP - shop token is used to redirect customer to the netlicensingShop(licenseeNumber is mandatory) 29 | * APIKEY - APIKey-token 30 | * @property string tokenType 31 | * 32 | * @property string licenseeNumber 33 | * 34 | * @constructor 35 | */ 36 | export default class Token extends BaseEntity { 37 | constructor(properties) { 38 | super({ 39 | properties, 40 | // The attributes that should be cast to native types. 41 | casts: { 42 | number: 'string', 43 | active: 'boolean', 44 | expirationTime: 'date', 45 | vendorNumber: 'string', 46 | tokenType: 'string', 47 | licenseeNumber: 'string', 48 | successURL: 'string', 49 | successURLTitle: 'string', 50 | cancelURL: 'string', 51 | cancelURLTitle: 'string', 52 | shopURL: 'string', 53 | }, 54 | }); 55 | } 56 | 57 | setNumber(number) { 58 | return this.setProperty('number', number); 59 | } 60 | 61 | getNumber(def) { 62 | return this.getProperty('number', def); 63 | } 64 | 65 | setActive(active) { 66 | return this.setProperty('active', active); 67 | } 68 | 69 | getActive(def) { 70 | return this.getProperty('active', def); 71 | } 72 | 73 | setExpirationTime(expirationTime) { 74 | return this.setProperty('expirationTime', expirationTime); 75 | } 76 | 77 | getExpirationTime(def) { 78 | return this.getProperty('expirationTime', def); 79 | } 80 | 81 | setVendorNumber(vendorNumber) { 82 | return this.setProperty('vendorNumber', vendorNumber); 83 | } 84 | 85 | getVendorNumber(def) { 86 | return this.getProperty('vendorNumber', def); 87 | } 88 | 89 | setTokenType(tokenType) { 90 | return this.setProperty('tokenType', tokenType); 91 | } 92 | 93 | getTokenType(def) { 94 | return this.getProperty('tokenType', def); 95 | } 96 | 97 | setLicenseeNumber(licenseeNumber) { 98 | return this.setProperty('licenseeNumber', licenseeNumber); 99 | } 100 | 101 | getLicenseeNumber(def) { 102 | return this.getProperty('licenseeNumber', def); 103 | } 104 | 105 | setSuccessURL(successURL) { 106 | return this.setProperty('successURL', successURL); 107 | } 108 | 109 | getSuccessURL(def) { 110 | return this.getProperty('successURL', def); 111 | } 112 | 113 | setSuccessURLTitle(successURLTitle) { 114 | return this.setProperty('successURLTitle', successURLTitle); 115 | } 116 | 117 | getSuccessURLTitle(def) { 118 | return this.getProperty('successURLTitle', def); 119 | } 120 | 121 | setCancelURL(cancelURL) { 122 | return this.setProperty('cancelURL', cancelURL); 123 | } 124 | 125 | getCancelURL(def) { 126 | return this.getProperty('cancelURL', def); 127 | } 128 | 129 | setCancelURLTitle(cancelURLTitle) { 130 | return this.setProperty('cancelURLTitle', cancelURLTitle); 131 | } 132 | 133 | getCancelURLTitle(def) { 134 | return this.getProperty('cancelURLTitle', def); 135 | } 136 | 137 | getShopURL(def) { 138 | return this.getProperty('shopURL', def); 139 | } 140 | 141 | /** 142 | * @deprecated 143 | * @alias setApiKeyRole 144 | * @param role 145 | * @returns {*} 146 | */ 147 | setRole(role) { 148 | return this.setApiKeyRole(role); 149 | } 150 | 151 | /** 152 | * @deprecated 153 | * @alias getApiKeyRole 154 | * @param def 155 | * @returns {*} 156 | */ 157 | getRole(def) { 158 | return this.getApiKeyRole(def); 159 | } 160 | 161 | setApiKeyRole(apiKeyRole) { 162 | return this.setProperty('apiKeyRole', apiKeyRole); 163 | } 164 | 165 | getApiKeyRole(def) { 166 | return this.getProperty('apiKeyRole', def); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/entities/Transaction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import BaseEntity from './BaseEntity'; 9 | import LicenseTransactionJoin from './LicenseTransactionJoin'; 10 | import License from './License'; 11 | 12 | /** 13 | * Transaction entity used internally by NetLicensing. 14 | * 15 | * Properties visible via NetLicensing API: 16 | * 17 | * Unique number (across all products of a vendor) that identifies the transaction. This number is 18 | * always generated by NetLicensing. 19 | * @property string number 20 | * 21 | * always true for transactions 22 | * @property boolean active 23 | * 24 | * Status of transaction. "CANCELLED", "CLOSED", "PENDING". 25 | * @property string status 26 | * 27 | * "SHOP". AUTO transaction for internal use only. 28 | * @property string source 29 | * 30 | * grand total for SHOP transaction (see source). 31 | * @property float grandTotal 32 | * 33 | * discount for SHOP transaction (see source). 34 | * @property float discount 35 | * 36 | * specifies currency for money fields (grandTotal and discount). Check data types to discover which 37 | * @property string currency 38 | * 39 | * Date created. Optional. 40 | * @property string dateCreated 41 | * 42 | * Date closed. Optional. 43 | * @property string dateClosed 44 | * 45 | * @constructor 46 | */ 47 | export default class Transaction extends BaseEntity { 48 | constructor(properties) { 49 | super({ 50 | properties, 51 | // The attributes that should be cast to native types. 52 | casts: { 53 | number: 'string', 54 | name: 'string', 55 | status: 'string', 56 | source: 'string', 57 | grandTotal: 'float', 58 | discount: 'float', 59 | currency: 'string', 60 | dateCreated: 'date', 61 | dateClosed: 'date', 62 | active: 'boolean', 63 | paymentMethod: 'string', 64 | }, 65 | }); 66 | } 67 | 68 | setNumber(number) { 69 | return this.setProperty('number', number); 70 | } 71 | 72 | getNumber(def) { 73 | return this.getProperty('number', def); 74 | } 75 | 76 | setName(name) { 77 | return this.setProperty('name', name); 78 | } 79 | 80 | getName(def) { 81 | return this.getProperty('name', def); 82 | } 83 | 84 | setStatus(status) { 85 | return this.setProperty('status', status); 86 | } 87 | 88 | getStatus(def) { 89 | return this.getProperty('status', def); 90 | } 91 | 92 | setSource(source) { 93 | return this.setProperty('source', source); 94 | } 95 | 96 | getSource(def) { 97 | return this.getProperty('source', def); 98 | } 99 | 100 | setGrandTotal(grandTotal) { 101 | return this.setProperty('grandTotal', grandTotal); 102 | } 103 | 104 | getGrandTotal(def) { 105 | return this.getProperty('grandTotal', def); 106 | } 107 | 108 | setDiscount(discount) { 109 | return this.setProperty('discount', discount); 110 | } 111 | 112 | getDiscount(def) { 113 | return this.getProperty('discount', def); 114 | } 115 | 116 | setCurrency(currency) { 117 | return this.setProperty('currency', currency); 118 | } 119 | 120 | getCurrency(def) { 121 | return this.getProperty('currency', def); 122 | } 123 | 124 | setDateCreated(dateCreated) { 125 | return this.setProperty('dateCreated', dateCreated); 126 | } 127 | 128 | getDateCreated(def) { 129 | return this.getProperty('dateCreated', def); 130 | } 131 | 132 | setDateClosed(dateClosed) { 133 | return this.setProperty('dateClosed', dateClosed); 134 | } 135 | 136 | getDateClosed(def) { 137 | return this.getProperty('dateClosed', def); 138 | } 139 | 140 | setPaymentMethod(paymentMethod) { 141 | return this.setProperty('paymentMethod', paymentMethod); 142 | } 143 | 144 | getPaymentMethod(def) { 145 | return this.getProperty('paymentMethod', def); 146 | } 147 | 148 | setActive() { 149 | return this.setProperty('active', true); 150 | } 151 | 152 | getLicenseTransactionJoins(def) { 153 | return this.getProperty('licenseTransactionJoins', def); 154 | } 155 | 156 | setLicenseTransactionJoins(licenseTransactionJoins) { 157 | return this.setProperty('licenseTransactionJoins', licenseTransactionJoins); 158 | } 159 | 160 | setListLicenseTransactionJoin(properties) { 161 | if (!properties) return; 162 | 163 | const licenseTransactionJoins = this.getProperty('licenseTransactionJoins', []); 164 | const licenseTransactionJoin = new LicenseTransactionJoin(); 165 | 166 | properties.forEach((property) => { 167 | if (property.name === 'licenseNumber') { 168 | licenseTransactionJoin.setLicense(new License({ number: property.value })); 169 | } 170 | 171 | if (property.name === 'transactionNumber') { 172 | licenseTransactionJoin.setTransaction(new Transaction({ number: property.value })); 173 | } 174 | }); 175 | 176 | licenseTransactionJoins.push(licenseTransactionJoin); 177 | this.setProperty('licenseTransactionJoins', licenseTransactionJoins); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/errors/NlicError.js: -------------------------------------------------------------------------------- 1 | export default class NlicError extends Error { 2 | constructor(...args) { 3 | super(...args); 4 | 5 | this.config = {}; 6 | this.response = {}; 7 | this.request = {}; 8 | this.code = ''; 9 | 10 | this.isNlicError = true; 11 | this.isAxiosError = true; 12 | } 13 | 14 | toJSON() { 15 | return { 16 | // Standard 17 | message: this.message, 18 | name: this.name, 19 | // Microsoft 20 | description: this.description, 21 | number: this.number, 22 | // Mozilla 23 | fileName: this.fileName, 24 | lineNumber: this.lineNumber, 25 | columnNumber: this.columnNumber, 26 | stack: this.stack, 27 | // Axios 28 | config: this.config, 29 | code: this.code, 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // Constants 2 | import Constants from './Constants'; 3 | 4 | // VO 5 | import Context from './vo/Context'; 6 | import Page from './vo/Page'; 7 | import ValidationParameters from './vo/ValidationParameters'; 8 | import ValidationResults from './vo/ValidationResults'; 9 | 10 | // Services 11 | import Service from './services/Service'; 12 | import LicenseeService from './services/LicenseeService'; 13 | import LicenseService from './services/LicenseService'; 14 | import LicenseTemplateService from './services/LicenseTemplateService'; 15 | import PaymentMethodService from './services/PaymentMethodService'; 16 | import ProductModuleService from './services/ProductModuleService'; 17 | import ProductService from './services/ProductService'; 18 | import TokenService from './services/TokenService'; 19 | import TransactionService from './services/TransactionService'; 20 | import UtilityService from './services/UtilityService'; 21 | import BundleService from './services/BundleService'; 22 | import NotificationService from './services/NotificationService'; 23 | 24 | // Entities 25 | import BaseEntity from './entities/BaseEntity'; 26 | import Country from './entities/Country'; 27 | import License from './entities/License'; 28 | import Licensee from './entities/Licensee'; 29 | import LicenseTemplate from './entities/LicenseTemplate'; 30 | import PaymentMethod from './entities/PaymentMethod'; 31 | import Product from './entities/Product'; 32 | import ProductDiscount from './entities/ProductDiscount'; 33 | import ProductModule from './entities/ProductModule'; 34 | import Token from './entities/Token'; 35 | import Transaction from './entities/Transaction'; 36 | import LicenseTransactionJoin from './entities/LicenseTransactionJoin'; 37 | import Bundle from './entities/Bundle'; 38 | import Notification from './entities/Notification'; 39 | 40 | // Converters 41 | import itemToCountry from './converters/itemToCountry'; 42 | import itemToLicense from './converters/itemToLicense'; 43 | import itemToLicensee from './converters/itemToLicensee'; 44 | import itemToLicenseTemplate from './converters/itemToLicenseTemplate'; 45 | import itemToObject from './converters/itemToObject'; 46 | import itemToPaymentMethod from './converters/itemToPaymentMethod'; 47 | import itemToProduct from './converters/itemToProduct'; 48 | import itemToProductModule from './converters/itemToProductModule'; 49 | import itemToToken from './converters/itemToToken'; 50 | import itemToTransaction from './converters/itemToTransaction'; 51 | import itemToBundle from './converters/itemToBundle'; 52 | 53 | // Utils 54 | import CastsUtils from './util/CastsUtils'; 55 | import CheckUtils from './util/CheckUtils'; 56 | import FilterUtils from './util/FilterUtils'; 57 | 58 | // Errors 59 | import NlicError from './errors/NlicError'; 60 | 61 | // Create the default instance to be exported 62 | // eslint-disable-next-line import/prefer-default-export 63 | export { 64 | // Constants 65 | Constants, 66 | 67 | // Expose VO 68 | Context, 69 | Page, 70 | ValidationParameters, 71 | ValidationResults, 72 | 73 | // Expose Services 74 | Service, 75 | LicenseeService, 76 | LicenseService, 77 | LicenseTemplateService, 78 | PaymentMethodService, 79 | ProductModuleService, 80 | ProductService, 81 | TokenService, 82 | TransactionService, 83 | UtilityService, 84 | BundleService, 85 | NotificationService, 86 | 87 | // Expose Entities 88 | BaseEntity, 89 | Country, 90 | License, 91 | Licensee, 92 | LicenseTemplate, 93 | PaymentMethod, 94 | Product, 95 | ProductDiscount, 96 | ProductModule, 97 | Token, 98 | Transaction, 99 | LicenseTransactionJoin, 100 | Bundle, 101 | Notification, 102 | 103 | // Expose Converters 104 | itemToCountry, 105 | itemToLicense, 106 | itemToLicensee, 107 | itemToLicenseTemplate, 108 | itemToObject, 109 | itemToPaymentMethod, 110 | itemToProduct, 111 | itemToProductModule, 112 | itemToToken, 113 | itemToTransaction, 114 | itemToBundle, 115 | 116 | // Expose Utils 117 | CastsUtils, 118 | CheckUtils, 119 | FilterUtils, 120 | 121 | // Errors 122 | NlicError, 123 | }; 124 | 125 | // module.exports = NetLicensing; 126 | 127 | // Allow use of default import syntax in TypeScript 128 | -------------------------------------------------------------------------------- /src/services/BundleService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Service from './Service'; 9 | import Constants from '../Constants'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToBundle from '../converters/itemToBundle'; 13 | import itemToLicense from '../converters/itemToLicense'; 14 | import Page from '../vo/Page'; 15 | 16 | /** 17 | * JS representation of the Bundle Service. See NetLicensingAPI for details: 18 | * https://netlicensing.io/wiki/bundle-services 19 | * 20 | * @constructor 21 | */ 22 | 23 | export default { 24 | /** 25 | * Creates new bundle with given properties.See NetLicensingAPI for details: 26 | * @see https://netlicensing.io/wiki/bundle-services#create-bundle 27 | * 28 | * determines the vendor on whose behalf the call is performed 29 | * @param context NetLicensing.Context 30 | * 31 | * non-null properties will be taken for the new object, null properties will either stay null, or will 32 | * be set to a default value, depending on property. 33 | * @param bundle NetLicensing.Bundle 34 | * 35 | * return the newly created bundle object in promise 36 | * @returns {Promise} 37 | */ 38 | 39 | async create(context, bundle) { 40 | const { data: { items: { item: items } } } = await Service 41 | .post(context, Constants.Bundle.ENDPOINT_PATH, bundle.asPropertiesMap()); 42 | 43 | const [item] = items.filter(({ type }) => type === 'Bundle'); 44 | 45 | return itemToBundle(item); 46 | }, 47 | 48 | /** 49 | * Gets bundle by its number.See NetLicensingAPI for details: 50 | * @see https://netlicensing.io/wiki/bundle-services#get-bundle 51 | * 52 | * determines the vendor on whose behalf the call is performed 53 | * @param context NetLicensing.Context 54 | * 55 | * the bundle number 56 | * @param number string 57 | * 58 | * return the bundle object in promise 59 | * @returns {Promise} 60 | */ 61 | async get(context, number) { 62 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 63 | 64 | const { data: { items: { item: items } } } = await Service 65 | .get(context, `${Constants.Bundle.ENDPOINT_PATH}/${number}`); 66 | 67 | const [item] = items.filter(({ type }) => type === 'Bundle'); 68 | 69 | return itemToBundle(item); 70 | }, 71 | 72 | /** 73 | * Returns bundle of a vendor.See NetLicensingAPI for details: 74 | * @see https://netlicensing.io/wiki/bundle-services#bundles-list 75 | * 76 | * determines the vendor on whose behalf the call is performed 77 | * @param context NetLicensing.Context 78 | * 79 | * reserved for the future use, must be omitted / set to NULL 80 | * @param filter string|null 81 | * 82 | * array of bundle entities or empty array if nothing found in promise. 83 | * @returns {Promise} 84 | */ 85 | async list(context, filter) { 86 | const queryParams = {}; 87 | 88 | if (filter) { 89 | if (!CheckUtils.isValid(filter)) throw new TypeError(`filter has bad value ${filter}`); 90 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 91 | } 92 | 93 | const { data } = await Service.get(context, Constants.Bundle.ENDPOINT_PATH, queryParams); 94 | 95 | return Page( 96 | data.items.item.filter(({ type }) => type === 'Bundle').map((v) => itemToBundle(v)), 97 | data.items.pagenumber, 98 | data.items.itemsnumber, 99 | data.items.totalpages, 100 | data.items.totalitems, 101 | ); 102 | }, 103 | 104 | /** 105 | * Updates bundle properties.See NetLicensingAPI for details: 106 | * @see https://netlicensing.io/wiki/bundle-services#update-bundle 107 | * 108 | * determines the vendor on whose behalf the call is performed 109 | * @param context NetLicensing.Context 110 | * 111 | * bundle number 112 | * @param number string 113 | * 114 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 115 | * @param bundle NetLicensing.Bundle 116 | * 117 | * updated bundle in promise. 118 | * @returns {Promise} 119 | */ 120 | async update(context, number, bundle) { 121 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 122 | 123 | const { data: { items: { item: items } } } = await Service 124 | .post(context, `${Constants.Bundle.ENDPOINT_PATH}/${number}`, bundle.asPropertiesMap()); 125 | 126 | const [item] = items.filter(({ type }) => type === 'Bundle'); 127 | 128 | return itemToBundle(item); 129 | }, 130 | 131 | /** 132 | * Deletes bundle.See NetLicensingAPI for details: 133 | * @see https://netlicensing.io/wiki/bundle-services#delete-bundle 134 | * 135 | * determines the vendor on whose behalf the call is performed 136 | * @param context NetLicensing.Context 137 | * 138 | * bundle number 139 | * @param number string 140 | * 141 | * if true, any entities that depend on the one being deleted will be deleted too 142 | * @param forceCascade boolean 143 | * 144 | * return boolean state of delete in promise 145 | * @returns {Promise} 146 | */ 147 | delete(context, number, forceCascade) { 148 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 149 | 150 | const queryParams = { forceCascade: Boolean(forceCascade) }; 151 | 152 | return Service.delete(context, `${Constants.Bundle.ENDPOINT_PATH}/${number}`, queryParams); 153 | }, 154 | 155 | /** 156 | * Obtain bundle.See NetLicensingAPI for details: 157 | * @see https://netlicensing.io/wiki/bundle-services#obtain-bundle 158 | * 159 | * determines the vendor on whose behalf the call is performed 160 | * @param context NetLicensing.Context 161 | * 162 | * bundle number 163 | * @param number string 164 | * 165 | * licensee number 166 | * @param licenseeNumber String 167 | * 168 | * return array of licenses 169 | * @returns {Promise} 170 | */ 171 | async obtain(context, number, licenseeNumber) { 172 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 173 | CheckUtils.paramNotEmpty(licenseeNumber, Constants.Licensee.LICENSEE_NUMBER); 174 | 175 | const { ENDPOINT_PATH, ENDPOINT_OBTAIN_PATH } = Constants.Bundle; 176 | 177 | const queryParams = { [Constants.Licensee.LICENSEE_NUMBER]: licenseeNumber }; 178 | 179 | const { data: { items: { item: items } } } = await Service 180 | .post(context, `${ENDPOINT_PATH}/${number}/${ENDPOINT_OBTAIN_PATH}`, queryParams); 181 | 182 | return items.filter(({ type }) => type === 'License').map((i) => itemToLicense(i)); 183 | }, 184 | }; 185 | -------------------------------------------------------------------------------- /src/services/LicenseTemplateService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import CheckUtils from '../util/CheckUtils'; 9 | import Constants from '../Constants'; 10 | import Service from './Service'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToLicenseTemplate from '../converters/itemToLicenseTemplate'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the ProductModule Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/license-template-services 18 | * 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Creates new license template object with given properties.See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/license-template-services#create-license-template 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * parent product module to which the new license template is to be added 31 | * @param productModuleNumber 32 | * 33 | * non-null properties will be taken for the new object, null properties will either stay null, or will 34 | * be set to a default value, depending on property. 35 | * @param licenseTemplate NetLicensing.LicenseTemplate 36 | * 37 | * the newly created license template object in promise 38 | * @returns {Promise} 39 | */ 40 | async create(context, productModuleNumber, licenseTemplate) { 41 | CheckUtils.paramNotEmpty(productModuleNumber, Constants.ProductModule.PRODUCT_MODULE_NUMBER); 42 | 43 | licenseTemplate.setProperty(Constants.ProductModule.PRODUCT_MODULE_NUMBER, productModuleNumber); 44 | 45 | const { data: { items: { item: items } } } = await Service 46 | .post(context, Constants.LicenseTemplate.ENDPOINT_PATH, licenseTemplate.asPropertiesMap()); 47 | 48 | const [item] = items.filter(({ type }) => type === 'LicenseTemplate'); 49 | 50 | return itemToLicenseTemplate(item); 51 | }, 52 | 53 | /** 54 | * Gets license template by its number.See NetLicensingAPI for details: 55 | * @see https://netlicensing.io/wiki/license-template-services#get-license-template 56 | * 57 | * determines the vendor on whose behalf the call is performed 58 | * @param context NetLicensing.Context 59 | * 60 | * the license template number 61 | * @param number string 62 | * 63 | * return the license template object in promise 64 | * @returns {Promise} 65 | */ 66 | async get(context, number) { 67 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 68 | 69 | const { data: { items: { item: items } } } = await Service 70 | .get(context, `${Constants.LicenseTemplate.ENDPOINT_PATH}/${number}`); 71 | 72 | const [item] = items.filter(({ type }) => type === 'LicenseTemplate'); 73 | 74 | return itemToLicenseTemplate(item); 75 | }, 76 | 77 | /** 78 | * Returns all license templates of a vendor.See NetLicensingAPI for details: 79 | * @see https://netlicensing.io/wiki/license-template-services#license-templates-list 80 | * 81 | * determines the vendor on whose behalf the call is performed 82 | * @param context NetLicensing.Context 83 | * 84 | * reserved for the future use, must be omitted / set to NULL 85 | * @param filter string|null 86 | * 87 | * array of license templates (of all products/modules) or null/empty list if nothing found in promise. 88 | * @returns {Promise} 89 | */ 90 | async list(context, filter) { 91 | const queryParams = {}; 92 | 93 | if (filter) { 94 | if (!CheckUtils.isValid(filter)) { 95 | throw new TypeError(`filter has bad value ${filter}`); 96 | } 97 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 98 | } 99 | 100 | const { data } = await Service 101 | .get(context, Constants.LicenseTemplate.ENDPOINT_PATH, queryParams); 102 | 103 | return Page( 104 | data.items.item.filter(({ type }) => type === 'LicenseTemplate').map((v) => itemToLicenseTemplate(v)), 105 | data.items.pagenumber, 106 | data.items.itemsnumber, 107 | data.items.totalpages, 108 | data.items.totalitems, 109 | ); 110 | }, 111 | 112 | /** 113 | * Updates license template properties.See NetLicensingAPI for details: 114 | * @see https://netlicensing.io/wiki/license-template-services#update-license-template 115 | * 116 | * determines the vendor on whose behalf the call is performed 117 | * @param context NetLicensing.Context 118 | * 119 | * license template number 120 | * @param number string 121 | * 122 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 123 | * @param licenseTemplate NetLicensing.LicenseTemplate 124 | * 125 | * updated license template in promise. 126 | * @returns {Promise} 127 | */ 128 | async update(context, number, licenseTemplate) { 129 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 130 | 131 | const path = `${Constants.LicenseTemplate.ENDPOINT_PATH}/${number}`; 132 | 133 | const { data: { items: { item: items } } } = await Service 134 | .post(context, path, licenseTemplate.asPropertiesMap()); 135 | 136 | const [item] = items.filter(({ type }) => type === 'LicenseTemplate'); 137 | 138 | return itemToLicenseTemplate(item); 139 | }, 140 | 141 | /** 142 | * Deletes license template.See NetLicensingAPI JavaDoc for details: 143 | * @see https://netlicensing.io/wiki/license-template-services#delete-license-template 144 | * 145 | * determines the vendor on whose behalf the call is performed 146 | * @param context NetLicensing.Context 147 | * 148 | * license template number 149 | * @param number string 150 | * 151 | * if true, any entities that depend on the one being deleted will be deleted too 152 | * @param forceCascade boolean 153 | * 154 | * return boolean state of delete in promise 155 | * @returns {Promise} 156 | */ 157 | delete(context, number, forceCascade) { 158 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 159 | 160 | const queryParams = { forceCascade: Boolean(forceCascade) }; 161 | 162 | return Service 163 | .delete(context, `${Constants.LicenseTemplate.ENDPOINT_PATH}/${number}`, queryParams); 164 | }, 165 | }; 166 | -------------------------------------------------------------------------------- /src/services/NotificationService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Service from './Service'; 9 | import Constants from '../Constants'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToNotification from '../converters/itemToNotification'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the Notification Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/notification-services 18 | * 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Creates new notification with given properties.See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/notification-services#create-notification 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * non-null properties will be taken for the new object, null properties will either stay null, or will 31 | * be set to a default value, depending on property. 32 | * @param notification NetLicensing.Notification 33 | * 34 | * return the newly created notification object in promise 35 | * @returns {Promise} 36 | */ 37 | 38 | async create(context, notification) { 39 | const { data: { items: { item: items } } } = await Service 40 | .post(context, Constants.Notification.ENDPOINT_PATH, notification.asPropertiesMap()); 41 | 42 | const [item] = items.filter(({ type }) => type === 'Notification'); 43 | 44 | return itemToNotification(item); 45 | }, 46 | 47 | /** 48 | * Gets notification by its number.See NetLicensingAPI for details: 49 | * @see https://netlicensing.io/wiki/notification-services#get-notification 50 | * 51 | * determines the vendor on whose behalf the call is performed 52 | * @param context NetLicensing.Context 53 | * 54 | * the notification number 55 | * @param number string 56 | * 57 | * return the notification object in promise 58 | * @returns {Promise} 59 | */ 60 | async get(context, number) { 61 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 62 | 63 | const { data: { items: { item: items } } } = await Service 64 | .get(context, `${Constants.Notification.ENDPOINT_PATH}/${number}`); 65 | 66 | const [item] = items.filter(({ type }) => type === 'Notification'); 67 | 68 | return itemToNotification(item); 69 | }, 70 | 71 | /** 72 | * Returns notifications of a vendor.See NetLicensingAPI for details: 73 | * @see https://netlicensing.io/wiki/notification-services#notifications-list 74 | * 75 | * determines the vendor on whose behalf the call is performed 76 | * @param context NetLicensing.Context 77 | * 78 | * reserved for the future use, must be omitted / set to NULL 79 | * @param filter string|null 80 | * 81 | * array of notification entities or empty array if nothing found in promise. 82 | * @returns {Promise} 83 | */ 84 | async list(context, filter) { 85 | const queryParams = {}; 86 | 87 | if (filter) { 88 | if (!CheckUtils.isValid(filter)) throw new TypeError(`filter has bad value ${filter}`); 89 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 90 | } 91 | 92 | const { data } = await Service.get(context, Constants.Notification.ENDPOINT_PATH, queryParams); 93 | 94 | return Page( 95 | data.items.item.filter(({ type }) => type === 'Notification').map((v) => itemToNotification(v)), 96 | data.items.pagenumber, 97 | data.items.itemsnumber, 98 | data.items.totalpages, 99 | data.items.totalitems, 100 | ); 101 | }, 102 | 103 | /** 104 | * Updates notification properties.See NetLicensingAPI for details: 105 | * @see https://netlicensing.io/wiki/notification-services#update-notification 106 | * 107 | * determines the vendor on whose behalf the call is performed 108 | * @param context NetLicensing.Context 109 | * 110 | * notification number 111 | * @param number string 112 | * 113 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 114 | * @param notification NetLicensing.Notification 115 | * 116 | * updated notification in promise. 117 | * @returns {Promise} 118 | */ 119 | async update(context, number, notification) { 120 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 121 | 122 | const { data: { items: { item: items } } } = await Service 123 | .post(context, `${Constants.Notification.ENDPOINT_PATH}/${number}`, notification.asPropertiesMap()); 124 | 125 | const [item] = items.filter(({ type }) => type === 'Notification'); 126 | 127 | return itemToNotification(item); 128 | }, 129 | 130 | /** 131 | * Deletes notification.See NetLicensingAPI for details: 132 | * @see https://netlicensing.io/wiki/notification-services#delete-notification 133 | * 134 | * determines the vendor on whose behalf the call is performed 135 | * @param context NetLicensing.Context 136 | * 137 | * notification number 138 | * @param number string 139 | * 140 | * return boolean state of delete in promise 141 | * @returns {Promise} 142 | */ 143 | delete(context, number) { 144 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 145 | 146 | return Service.delete(context, `${Constants.Notification.ENDPOINT_PATH}/${number}`); 147 | }, 148 | }; 149 | -------------------------------------------------------------------------------- /src/services/PaymentMethodService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Constants from '../Constants'; 9 | import CheckUtils from '../util/CheckUtils'; 10 | import Service from './Service'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToPaymentMethod from '../converters/itemToPaymentMethod'; 13 | import Page from '../vo/Page'; 14 | 15 | export default { 16 | /** 17 | * Gets payment method by its number.See NetLicensingAPI for details: 18 | * @see https://netlicensing.io/wiki/payment-method-services#get-payment-method 19 | * 20 | * determines the vendor on whose behalf the call is performed 21 | * @param context NetLicensing.Context 22 | * 23 | * the payment method number 24 | * @param number string 25 | * 26 | * return the payment method in promise 27 | * @returns {Promise} 28 | */ 29 | async get(context, number) { 30 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 31 | 32 | const { data: { items: { item: items } } } = await Service 33 | .get(context, `${Constants.PaymentMethod.ENDPOINT_PATH}/${number}`); 34 | 35 | const [item] = items.filter(({ type }) => type === 'PaymentMethod'); 36 | 37 | return itemToPaymentMethod(item); 38 | }, 39 | 40 | /** 41 | * Returns payment methods of a vendor.See NetLicensingAPI for details: 42 | * @see https://netlicensing.io/wiki/payment-method-services#payment-methods-list 43 | * 44 | * determines the vendor on whose behalf the call is performed 45 | * @param context NetLicensing.Context 46 | * 47 | * reserved for the future use, must be omitted / set to NULL 48 | * @param filter string|null 49 | * 50 | * array of payment method entities or empty array if nothing found in promise. 51 | * @returns {Promise} 52 | */ 53 | async list(context, filter) { 54 | const queryParams = {}; 55 | 56 | if (filter) { 57 | if (!CheckUtils.isValid(filter)) { 58 | throw new TypeError(`filter has bad value ${filter}`); 59 | } 60 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 61 | } 62 | 63 | const { data } = await Service 64 | .get(context, Constants.PaymentMethod.ENDPOINT_PATH, queryParams); 65 | 66 | return Page( 67 | data.items.item.filter(({ type }) => type === 'PaymentMethod').map((v) => itemToPaymentMethod(v)), 68 | data.items.pagenumber, 69 | data.items.itemsnumber, 70 | data.items.totalpages, 71 | data.items.totalitems, 72 | ); 73 | }, 74 | 75 | /** 76 | * Updates payment method properties.See NetLicensingAPI for details: 77 | * @see https://netlicensing.io/wiki/payment-method-services#update-payment-method 78 | * 79 | * determines the vendor on whose behalf the call is performed 80 | * @param context NetLicensing.Context 81 | * 82 | * the payment method number 83 | * @param number string 84 | * 85 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 86 | * @param paymentMethod NetLicensing.PaymentMethod 87 | * 88 | * return updated payment method in promise. 89 | * @returns {Promise} 90 | */ 91 | async update(context, number, paymentMethod) { 92 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 93 | 94 | const path = `${Constants.PaymentMethod.ENDPOINT_PATH}/${number}`; 95 | 96 | const { data: { items: { item: items } } } = await Service 97 | .post(context, path, paymentMethod.asPropertiesMap()); 98 | 99 | const [item] = items.filter(({ type }) => type === 'PaymentMethod'); 100 | 101 | return itemToPaymentMethod(item); 102 | }, 103 | }; 104 | -------------------------------------------------------------------------------- /src/services/ProductModuleService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import CheckUtils from '../util/CheckUtils'; 9 | import Constants from '../Constants'; 10 | import Service from './Service'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToProductModule from '../converters/itemToProductModule'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the ProductModule Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/product-module-services 18 | * 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Creates new product module object with given properties.See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/product-module-services#create-product-module 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * parent product to which the new product module is to be added 31 | * @param productNumber string 32 | * 33 | * non-null properties will be taken for the new object, null properties will either stay null, or will 34 | * be set to a default value, depending on property. 35 | * @param productModule NetLicensing.ProductModule 36 | * 37 | * the newly created product module object in promise 38 | * @returns {Promise} 39 | */ 40 | async create(context, productNumber, productModule) { 41 | CheckUtils.paramNotEmpty(productNumber, Constants.Product.PRODUCT_NUMBER); 42 | 43 | productModule.setProperty(Constants.Product.PRODUCT_NUMBER, productNumber); 44 | 45 | const { data: { items: { item: items } } } = await Service 46 | .post(context, Constants.ProductModule.ENDPOINT_PATH, productModule.asPropertiesMap()); 47 | 48 | const [item] = items.filter(({ type }) => type === 'ProductModule'); 49 | 50 | return itemToProductModule(item); 51 | }, 52 | 53 | /** 54 | * Gets product module by its number.See NetLicensingAPI for details: 55 | * @see https://netlicensing.io/wiki/product-module-services#get-product-module 56 | * 57 | * determines the vendor on whose behalf the call is performed 58 | * @param context NetLicensing.Context 59 | * 60 | * the product module number 61 | * @param number string 62 | * 63 | * return the product module object in promise 64 | * @returns {Promise} 65 | */ 66 | async get(context, number) { 67 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 68 | 69 | const { data: { items: { item: items } } } = await Service 70 | .get(context, `${Constants.ProductModule.ENDPOINT_PATH}/${number}`); 71 | 72 | const [item] = items.filter(({ type }) => type === 'ProductModule'); 73 | 74 | return itemToProductModule(item); 75 | }, 76 | 77 | /** 78 | * Returns products of a vendor.See NetLicensingAPI for details: 79 | * @see https://netlicensing.io/wiki/product-module-services#product-modules-list 80 | * 81 | * determines the vendor on whose behalf the call is performed 82 | * @param context NetLicensing.Context 83 | * 84 | * reserved for the future use, must be omitted / set to NULL 85 | * @param filter string|null 86 | * 87 | * array of product modules entities or empty array if nothing found in promise. 88 | * @returns {Promise} 89 | */ 90 | async list(context, filter) { 91 | const queryParams = {}; 92 | 93 | if (filter) { 94 | if (!CheckUtils.isValid(filter)) { 95 | throw new TypeError(`filter has bad value ${filter}`); 96 | } 97 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 98 | } 99 | 100 | const { data } = await Service.get(context, Constants.ProductModule.ENDPOINT_PATH, queryParams); 101 | 102 | return Page( 103 | data.items.item.filter(({ type }) => type === 'ProductModule').map((v) => itemToProductModule(v)), 104 | data.items.pagenumber, 105 | data.items.itemsnumber, 106 | data.items.totalpages, 107 | data.items.totalitems, 108 | ); 109 | }, 110 | 111 | /** 112 | * Updates product module properties.See NetLicensingAPI for details: 113 | * @see https://netlicensing.io/wiki/product-module-services#update-product-module 114 | * 115 | * determines the vendor on whose behalf the call is performed 116 | * @param context NetLicensing.Context 117 | * 118 | * product module number 119 | * @param number string 120 | * 121 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 122 | * @param productModule NetLicensing.ProductModule 123 | * 124 | * updated product module in promise. 125 | * @returns {Promise} 126 | */ 127 | async update(context, number, productModule) { 128 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 129 | 130 | const { data: { items: { item: items } } } = await Service 131 | .post(context, `${Constants.ProductModule.ENDPOINT_PATH}/${number}`, productModule.asPropertiesMap()); 132 | 133 | const [item] = items.filter(({ type }) => type === 'ProductModule'); 134 | 135 | return itemToProductModule(item); 136 | }, 137 | 138 | /** 139 | * Deletes product module.See NetLicensingAPI for details: 140 | * @see https://netlicensing.io/wiki/product-module-services#delete-product-module 141 | * 142 | * determines the vendor on whose behalf the call is performed 143 | * @param context NetLicensing.Context 144 | * 145 | * product module number 146 | * @param number string 147 | * 148 | * if true, any entities that depend on the one being deleted will be deleted too 149 | * @param forceCascade boolean 150 | * 151 | * return boolean state of delete in promise 152 | * @returns {Promise} 153 | */ 154 | delete(context, number, forceCascade) { 155 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 156 | 157 | const queryParams = { forceCascade: Boolean(forceCascade) }; 158 | 159 | return Service.delete(context, `${Constants.ProductModule.ENDPOINT_PATH}/${number}`, queryParams); 160 | }, 161 | }; 162 | -------------------------------------------------------------------------------- /src/services/ProductService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Service from './Service'; 9 | import Constants from '../Constants'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToProduct from '../converters/itemToProduct'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the Product Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/product-services 18 | * 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Creates new product with given properties.See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/product-services#create-product 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * non-null properties will be taken for the new object, null properties will either stay null, or will 31 | * be set to a default value, depending on property. 32 | * @param product NetLicensing.Product 33 | * 34 | * return the newly created product object in promise 35 | * @returns {Promise} 36 | */ 37 | 38 | async create(context, product) { 39 | const { data: { items: { item: items } } } = await Service 40 | .post(context, Constants.Product.ENDPOINT_PATH, product.asPropertiesMap()); 41 | 42 | const [item] = items.filter(({ type }) => type === 'Product'); 43 | 44 | return itemToProduct(item); 45 | }, 46 | 47 | /** 48 | * Gets product by its number.See NetLicensingAPI for details: 49 | * @see https://netlicensing.io/wiki/product-services#get-product 50 | * 51 | * determines the vendor on whose behalf the call is performed 52 | * @param context NetLicensing.Context 53 | * 54 | * the product number 55 | * @param number string 56 | * 57 | * return the product object in promise 58 | * @returns {Promise} 59 | */ 60 | async get(context, number) { 61 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 62 | 63 | const { data: { items: { item: items } } } = await Service 64 | .get(context, `${Constants.Product.ENDPOINT_PATH}/${number}`); 65 | 66 | const [item] = items.filter(({ type }) => type === 'Product'); 67 | 68 | return itemToProduct(item); 69 | }, 70 | 71 | /** 72 | * Returns products of a vendor.See NetLicensingAPI for details: 73 | * @see https://netlicensing.io/wiki/product-services#products-list 74 | * 75 | * determines the vendor on whose behalf the call is performed 76 | * @param context NetLicensing.Context 77 | * 78 | * reserved for the future use, must be omitted / set to NULL 79 | * @param filter string|null 80 | * 81 | * array of product entities or empty array if nothing found in promise. 82 | * @returns {Promise} 83 | */ 84 | async list(context, filter) { 85 | const queryParams = {}; 86 | 87 | if (filter) { 88 | if (!CheckUtils.isValid(filter)) throw new TypeError(`filter has bad value ${filter}`); 89 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 90 | } 91 | 92 | const { data } = await Service.get(context, Constants.Product.ENDPOINT_PATH, queryParams); 93 | 94 | return Page( 95 | data.items.item.filter(({ type }) => type === 'Product').map((v) => itemToProduct(v)), 96 | data.items.pagenumber, 97 | data.items.itemsnumber, 98 | data.items.totalpages, 99 | data.items.totalitems, 100 | ); 101 | }, 102 | 103 | /** 104 | * Updates product properties.See NetLicensingAPI for details: 105 | * @see https://netlicensing.io/wiki/product-services#update-product 106 | * 107 | * determines the vendor on whose behalf the call is performed 108 | * @param context NetLicensing.Context 109 | * 110 | * product number 111 | * @param number string 112 | * 113 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 114 | * @param product NetLicensing.Product 115 | * 116 | * updated product in promise. 117 | * @returns {Promise} 118 | */ 119 | async update(context, number, product) { 120 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 121 | 122 | const { data: { items: { item: items } } } = await Service 123 | .post(context, `${Constants.Product.ENDPOINT_PATH}/${number}`, product.asPropertiesMap()); 124 | 125 | const [item] = items.filter(({ type }) => type === 'Product'); 126 | 127 | return itemToProduct(item); 128 | }, 129 | 130 | /** 131 | * Deletes product.See NetLicensingAPI for details: 132 | * @see https://netlicensing.io/wiki/product-services#delete-product 133 | * 134 | * determines the vendor on whose behalf the call is performed 135 | * @param context NetLicensing.Context 136 | * 137 | * product number 138 | * @param number string 139 | * 140 | * if true, any entities that depend on the one being deleted will be deleted too 141 | * @param forceCascade boolean 142 | * 143 | * return boolean state of delete in promise 144 | * @returns {Promise} 145 | */ 146 | delete(context, number, forceCascade) { 147 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 148 | 149 | const queryParams = { forceCascade: Boolean(forceCascade) }; 150 | 151 | return Service.delete(context, `${Constants.Product.ENDPOINT_PATH}/${number}`, queryParams); 152 | }, 153 | }; 154 | -------------------------------------------------------------------------------- /src/services/TokenService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Constants from '../Constants'; 9 | import Service from './Service'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToToken from '../converters/itemToToken'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the Token Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/token-services 18 | * 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Creates new token.See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/token-services#create-token 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 31 | * @param token NetLicensing.Token 32 | * 33 | * return created token in promise 34 | * @returns {Promise} 35 | */ 36 | async create(context, token) { 37 | const { data: { items: { item: items } } } = await Service 38 | .post(context, Constants.Token.ENDPOINT_PATH, token.asPropertiesMap()); 39 | 40 | const [item] = items.filter(({ type }) => type === 'Token'); 41 | 42 | return itemToToken(item); 43 | }, 44 | 45 | /** 46 | * Gets token by its number..See NetLicensingAPI for details: 47 | * @see https://netlicensing.io/wiki/token-services#get-token 48 | * 49 | * determines the vendor on whose behalf the call is performed 50 | * @param context NetLicensing.Context 51 | * 52 | * the token number 53 | * @param number 54 | * 55 | * return the token in promise 56 | * @returns {Promise} 57 | */ 58 | async get(context, number) { 59 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 60 | 61 | const { data: { items: { item: items } } } = await Service 62 | .get(context, `${Constants.Token.ENDPOINT_PATH}/${number}`); 63 | 64 | const [item] = items.filter(({ type }) => type === 'Token'); 65 | 66 | return itemToToken(item); 67 | }, 68 | 69 | /** 70 | * Returns tokens of a vendor.See NetLicensingAPI for details: 71 | * @see https://netlicensing.io/wiki/token-services#tokens-list 72 | * 73 | * determines the vendor on whose behalf the call is performed 74 | * @param context NetLicensing.Context 75 | * 76 | * reserved for the future use, must be omitted / set to NULL 77 | * @param filter string|null 78 | * 79 | * array of token entities or empty array if nothing found. 80 | * @return array 81 | */ 82 | async list(context, filter) { 83 | const queryParams = {}; 84 | 85 | if (filter) { 86 | if (!CheckUtils.isValid(filter)) { 87 | throw new TypeError(`filter has bad value ${filter}`); 88 | } 89 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 90 | } 91 | 92 | const { data } = await Service 93 | .get(context, Constants.Token.ENDPOINT_PATH, queryParams); 94 | 95 | return Page( 96 | data.items.item.filter(({ type }) => type === 'Token').map((v) => itemToToken(v)), 97 | data.items.pagenumber, 98 | data.items.itemsnumber, 99 | data.items.totalpages, 100 | data.items.totalitems, 101 | ); 102 | }, 103 | 104 | /** 105 | * Delete token by its number.See NetLicensingAPI for details: 106 | * @see https://netlicensing.io/wiki/token-services#delete-token 107 | * 108 | * determines the vendor on whose behalf the call is performed 109 | * @param context NetLicensing.Context 110 | * 111 | * the token number 112 | * @param number string 113 | * 114 | * return boolean state of delete in promise 115 | * @returns {Promise} 116 | */ 117 | delete(context, number) { 118 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 119 | 120 | return Service 121 | .delete(context, `${Constants.Token.ENDPOINT_PATH}/${number}`); 122 | }, 123 | }; 124 | -------------------------------------------------------------------------------- /src/services/TransactionService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Constants from '../Constants'; 9 | import Service from './Service'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToTransaction from '../converters/itemToTransaction'; 13 | import Page from '../vo/Page'; 14 | 15 | /** 16 | * JS representation of the Transaction Service. See NetLicensingAPI for details: 17 | * https://netlicensing.io/wiki/transaction-services 18 | * 19 | * Transaction is created each time change to LicenseService licenses happens. For instance licenses are 20 | * obtained by a licensee, licenses disabled by vendor, licenses deleted, etc. Transaction is created no matter what 21 | * source has initiated the change to licenses: it can be either a direct purchase of licenses by a licensee via 22 | * NetLicensing Shop, or licenses can be given to a licensee by a vendor. Licenses can also be assigned implicitly by 23 | * NetLicensing if it is defined so by a license model (e.g. evaluation license may be given automatically). All these 24 | * events are reflected in transactions. Of all the transaction handling routines only read-only routines are exposed to 25 | * the public API, as transactions are only allowed to be created and modified by NetLicensing internally. 26 | * 27 | * @constructor 28 | */ 29 | 30 | export default { 31 | /** 32 | * Creates new transaction object with given properties.See NetLicensingAPI for details: 33 | * @see https://netlicensing.io/wiki/transaction-services#create-transaction 34 | * 35 | * determines the vendor on whose behalf the call is performed 36 | * @param context NetLicensing.Context 37 | * 38 | * non-null properties will be taken for the new object, null properties will either stay null, or will 39 | * be set to a default value, depending on property. 40 | * @param transaction NetLicensing.Transaction 41 | * 42 | * return the newly created transaction object in promise 43 | * @returns {Promise} 44 | */ 45 | async create(context, transaction) { 46 | const { data: { items: { item: items } } } = await Service 47 | .post(context, Constants.Transaction.ENDPOINT_PATH, transaction.asPropertiesMap()); 48 | 49 | const [item] = items.filter(({ type }) => type === 'Transaction'); 50 | 51 | return itemToTransaction(item); 52 | }, 53 | 54 | /** 55 | * Gets transaction by its number.See NetLicensingAPI for details: 56 | * @see https://netlicensing.io/wiki/transaction-services#get-transaction 57 | * 58 | * determines the vendor on whose behalf the call is performed 59 | * @param context NetLicensing.Context 60 | * 61 | * the transaction number 62 | * @param number string 63 | * 64 | * return the transaction in promise 65 | * @returns {Promise} 66 | */ 67 | async get(context, number) { 68 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 69 | 70 | const { data: { items: { item: items } } } = await Service 71 | .get(context, `${Constants.Transaction.ENDPOINT_PATH}/${number}`); 72 | 73 | const [item] = items.filter(({ type }) => type === 'Transaction'); 74 | 75 | return itemToTransaction(item); 76 | }, 77 | 78 | /** 79 | * Returns all transactions of a vendor.See NetLicensingAPI for details: 80 | * @see https://netlicensing.io/wiki/transaction-services#transactions-list 81 | * 82 | * determines the vendor on whose behalf the call is performed 83 | * @param context NetLicensing.Context 84 | * 85 | * reserved for the future use, must be omitted / set to NULL 86 | * @param filter string 87 | * 88 | * array of transaction entities or empty array if nothing found in promise. 89 | * @returns {Promise} 90 | */ 91 | async list(context, filter) { 92 | const queryParams = {}; 93 | 94 | if (filter) { 95 | if (!CheckUtils.isValid(filter)) { 96 | throw new TypeError(`filter has bad value ${filter}`); 97 | } 98 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 99 | } 100 | 101 | const { data } = await Service 102 | .get(context, Constants.Transaction.ENDPOINT_PATH, queryParams); 103 | 104 | return Page( 105 | data.items.item.filter(({ type }) => type === 'Transaction').map((v) => itemToTransaction(v)), 106 | data.items.pagenumber, 107 | data.items.itemsnumber, 108 | data.items.totalpages, 109 | data.items.totalitems, 110 | ); 111 | }, 112 | 113 | /** 114 | * Updates transaction properties.See NetLicensingAPI for details: 115 | * @see https://netlicensing.io/wiki/transaction-services#update-transaction 116 | * 117 | * determines the vendor on whose behalf the call is performed 118 | * @param context NetLicensing.Context 119 | * 120 | * transaction number 121 | * @param number string 122 | * 123 | * non-null properties will be updated to the provided values, null properties will stay unchanged. 124 | * @param transaction NetLicensing.Transaction 125 | * 126 | * return updated transaction in promise. 127 | * @returns {Promise} 128 | */ 129 | async update(context, number, transaction) { 130 | CheckUtils.paramNotEmpty(number, Constants.NUMBER); 131 | 132 | const { data: { items: { item: items } } } = await Service 133 | .post(context, `${Constants.Transaction.ENDPOINT_PATH}/${number}`, transaction.asPropertiesMap()); 134 | 135 | const [item] = items.filter(({ type }) => type === 'Transaction'); 136 | 137 | return itemToTransaction(item); 138 | }, 139 | }; 140 | -------------------------------------------------------------------------------- /src/services/UtilityService.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import Constants from '../Constants'; 9 | import Service from './Service'; 10 | import CheckUtils from '../util/CheckUtils'; 11 | import FilterUtils from '../util/FilterUtils'; 12 | import itemToObject from '../converters/itemToObject'; 13 | import Page from '../vo/Page'; 14 | import itemToCountry from '../converters/itemToCountry'; 15 | 16 | /** 17 | * JS representation of the Utility Service. See NetLicensingAPI for details: 18 | * https://netlicensing.io/wiki/utility-services 19 | * @constructor 20 | */ 21 | 22 | export default { 23 | /** 24 | * Returns all license types. See NetLicensingAPI for details: 25 | * @see https://netlicensing.io/wiki/utility-services#license-types-list 26 | * 27 | * determines the vendor on whose behalf the call is performed 28 | * @param context NetLicensing.Context 29 | * 30 | * array of available license types or empty array if nothing found in promise. 31 | * @returns {Promise} 32 | */ 33 | async listLicenseTypes(context) { 34 | const { data } = await Service 35 | .get(context, `${Constants.Utility.ENDPOINT_PATH}/${Constants.Utility.ENDPOINT_PATH_LICENSE_TYPES}`); 36 | 37 | return Page( 38 | data.items.item.filter(({ type }) => type === 'LicenseType').map((v) => itemToObject(v)), 39 | data.items.pagenumber, 40 | data.items.itemsnumber, 41 | data.items.totalpages, 42 | data.items.totalitems, 43 | ); 44 | }, 45 | 46 | /** 47 | * Returns all license models. See NetLicensingAPI for details: 48 | * @see https://netlicensing.io/wiki/utility-services#licensing-models-list 49 | * 50 | * determines the vendor on whose behalf the call is performed 51 | * @param context NetLicensing.Context 52 | * 53 | * array of available license models or empty array if nothing found in promise. 54 | * @returns {Promise} 55 | */ 56 | async listLicensingModels(context) { 57 | const { data } = await Service 58 | .get(context, `${Constants.Utility.ENDPOINT_PATH}/${Constants.Utility.ENDPOINT_PATH_LICENSING_MODELS}`); 59 | 60 | return Page( 61 | data.items.item.filter(({ type }) => type === 'LicensingModelProperties').map((v) => itemToObject(v)), 62 | data.items.pagenumber, 63 | data.items.itemsnumber, 64 | data.items.totalpages, 65 | data.items.totalitems, 66 | ); 67 | }, 68 | 69 | /** 70 | * Returns all countries. 71 | * 72 | * determines the vendor on whose behalf the call is performed 73 | * @param context 74 | * 75 | * reserved for the future use, must be omitted / set to NULL 76 | * @param filter 77 | * 78 | * collection of available countries or null/empty list if nothing found in promise. 79 | * @returns {Promise} 80 | */ 81 | async listCountries(context, filter) { 82 | const queryParams = {}; 83 | 84 | if (filter) { 85 | if (!CheckUtils.isValid(filter)) { 86 | throw new TypeError(`filter has bad value ${filter}`); 87 | } 88 | queryParams[Constants.FILTER] = typeof filter === 'string' ? filter : FilterUtils.encode(filter); 89 | } 90 | 91 | const { data } = await Service 92 | .get( 93 | context, 94 | `${Constants.Utility.ENDPOINT_PATH}/${Constants.Utility.ENDPOINT_PATH_COUNTRIES}`, 95 | queryParams, 96 | ); 97 | 98 | return Page( 99 | data.items.item.filter(({ type }) => type === 'Country').map((v) => itemToCountry(v)), 100 | data.items.pagenumber, 101 | data.items.itemsnumber, 102 | data.items.totalpages, 103 | data.items.totalitems, 104 | ); 105 | }, 106 | }; 107 | -------------------------------------------------------------------------------- /src/util/CastsUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | // Cast an attribute to a native JS type. 9 | export default (key, value) => { 10 | switch (key.trim().toLowerCase()) { 11 | case 'str': 12 | case 'string': 13 | return String(value); 14 | case 'int': 15 | case 'integer': { 16 | const n = parseInt(value, 10); 17 | return Number.isNaN(n) ? value : n; 18 | } 19 | case 'float': 20 | case 'double': { 21 | const n = parseFloat(value); 22 | return Number.isNaN(n) ? value : n; 23 | } 24 | case 'bool': 25 | case 'boolean': 26 | switch (value) { 27 | case 'true': 28 | case 'TRUE': 29 | return true; 30 | case 'false': 31 | case 'FALSE': 32 | return false; 33 | default: 34 | return Boolean(value); 35 | } 36 | case 'date': 37 | return (value === 'now') ? 'now' : new Date(String(value)); 38 | default: 39 | return value; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /src/util/CheckUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | export default { 9 | isValid(value) { 10 | let valid = (value !== undefined && typeof value !== 'function'); 11 | if (typeof value === 'number') valid = Number.isFinite(value) && !Number.isNaN(value); 12 | return valid; 13 | }, 14 | 15 | paramNotNull(parameter, parameterName) { 16 | if (!this.isValid(parameter)) throw new TypeError(`Parameter ${parameterName} has bad value ${parameter}`); 17 | if (parameter === null) throw new TypeError(`Parameter ${parameterName} cannot be null`); 18 | }, 19 | 20 | paramNotEmpty(parameter, parameterName) { 21 | if (!this.isValid(parameter)) throw new TypeError(`Parameter ${parameterName} has bad value ${parameter}`); 22 | if (!parameter) throw new TypeError(`Parameter ${parameterName} cannot be null or empty string`); 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /src/util/FilterUtils.js: -------------------------------------------------------------------------------- 1 | export default { 2 | FILTER_DELIMITER: ';', 3 | FILTER_PAIR_DELIMITER: '=', 4 | encode(filter = {}) { 5 | const query = []; 6 | const has = Object.prototype.hasOwnProperty; 7 | Object.keys(filter).forEach((key) => { 8 | if (has.call(filter, key)) { 9 | query.push(`${key}${this.FILTER_PAIR_DELIMITER}${filter[key]}`); 10 | } 11 | }); 12 | return query.join(this.FILTER_DELIMITER); 13 | }, 14 | decode(query = '') { 15 | const filter = {}; 16 | query.split(this.FILTER_DELIMITER).forEach((v) => { 17 | const [name, value] = v.split(this.FILTER_PAIR_DELIMITER); 18 | filter[name] = value; 19 | }); 20 | return filter; 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /src/vo/Context.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | import Constants from '../Constants'; 8 | import CheckUtils from '../util/CheckUtils'; 9 | 10 | /** 11 | * The context values. 12 | * @type {{}} 13 | * @private 14 | */ 15 | const valuesMap = new WeakMap(); 16 | 17 | /** 18 | * List of values that was defined 19 | * @type {{}} 20 | * @private 21 | */ 22 | const definedMap = new WeakMap(); 23 | 24 | /** 25 | * Context defaults 26 | * @type {{baseUrl: string, securityMode}} 27 | * @private 28 | */ 29 | const defaultsMap = new WeakMap(); 30 | 31 | export default class Context { 32 | constructor(values) { 33 | defaultsMap.set(this, { 34 | baseUrl: 'https://go.netlicensing.io/core/v2/rest', 35 | securityMode: Constants.BASIC_AUTHENTICATION, 36 | }); 37 | 38 | valuesMap.set(this, {}); 39 | 40 | definedMap.set(this, {}); 41 | 42 | this.setValues({ ...defaultsMap.get(this), ...values }); 43 | } 44 | 45 | setBaseUrl(baseUrl) { 46 | return this.setValue('baseUrl', baseUrl); 47 | } 48 | 49 | getBaseUrl(def) { 50 | return this.getValue('baseUrl', def); 51 | } 52 | 53 | setUsername(username) { 54 | return this.setValue('username', username); 55 | } 56 | 57 | getUsername(def) { 58 | return this.getValue('username', def); 59 | } 60 | 61 | setPassword(password) { 62 | return this.setValue('password', password); 63 | } 64 | 65 | getPassword(def) { 66 | return this.getValue('password', def); 67 | } 68 | 69 | setApiKey(apiKey) { 70 | return this.setValue('apiKey', apiKey); 71 | } 72 | 73 | getApiKey(def) { 74 | return this.getValue('apiKey', def); 75 | } 76 | 77 | setSecurityMode(securityMode) { 78 | return this.setValue('securityMode', securityMode); 79 | } 80 | 81 | getSecurityMode(def) { 82 | return this.getValue('securityMode', def); 83 | } 84 | 85 | setVendorNumber(vendorNumber) { 86 | return this.setValue('vendorNumber', vendorNumber); 87 | } 88 | 89 | getVendorNumber(def) { 90 | return this.getValue('vendorNumber', def); 91 | } 92 | 93 | /** 94 | * Set a given values on the context. 95 | * @param key 96 | * @param value 97 | * @returns {Context} 98 | */ 99 | setValue(key, value) { 100 | // check values 101 | if (!CheckUtils.isValid(key) || typeof key === 'object') throw new Error(`Bad value key:${key}`); 102 | if (!CheckUtils.isValid(value)) throw new Error(`Value ${key} has wrong value${value}`); 103 | 104 | // define keys 105 | this.define(key); 106 | 107 | let copedValue = value; 108 | 109 | if (typeof value === 'object' && value !== null) { 110 | copedValue = (Array.isArray(value)) ? Object.assign([], value) : ({ ...value }); 111 | } 112 | 113 | const values = valuesMap.get(this); 114 | values[key] = copedValue; 115 | 116 | return this; 117 | } 118 | 119 | /** 120 | * Set the array of context values. 121 | * @param values 122 | * @returns {Context} 123 | */ 124 | setValues(values) { 125 | this.removeValues(); 126 | 127 | const has = Object.prototype.hasOwnProperty; 128 | 129 | Object.keys(values).forEach((key) => { 130 | if (has.call(values, key)) { 131 | this.setValue(key, values[key]); 132 | } 133 | }); 134 | 135 | return this; 136 | } 137 | 138 | /** 139 | * Get an value from the context. 140 | * @param key 141 | * @param def 142 | * @returns {*} 143 | */ 144 | getValue(key, def) { 145 | return (key in valuesMap.get(this)) 146 | ? valuesMap.get(this)[key] 147 | : def; 148 | } 149 | 150 | /** 151 | * Get all of the current value on the context. 152 | */ 153 | getValues() { 154 | return { ...valuesMap.get(this) }; 155 | } 156 | 157 | /** 158 | * Remove value 159 | * @param key 160 | * @returns {Context} 161 | */ 162 | removeValue(key) { 163 | const values = valuesMap.get(this); 164 | delete values[key]; 165 | 166 | this.removeDefine(key); 167 | return this; 168 | } 169 | 170 | /** 171 | * Remove values 172 | * @param keys 173 | */ 174 | removeValues(keys) { 175 | const keysAr = keys || Object.keys(valuesMap.get(this)); 176 | keysAr.forEach((key) => this.removeValue(key)); 177 | } 178 | 179 | /** 180 | * Define value getter and setter 181 | * @param key 182 | * @param onlyGetter 183 | * @private 184 | */ 185 | define(key, onlyGetter) { 186 | if (this.hasDefine(key)) return; 187 | 188 | if (!CheckUtils.isValid(key) || typeof property === 'object') { 189 | throw new TypeError(`Bad value name:${key}`); 190 | } 191 | 192 | const self = this; 193 | 194 | // delete property 195 | delete this[key]; 196 | 197 | const descriptors = { 198 | enumerable: true, 199 | configurable: true, 200 | get() { 201 | return self.getValue(key); 202 | }, 203 | }; 204 | 205 | if (!onlyGetter) { 206 | descriptors.set = (value) => self.setValue(key, value); 207 | } 208 | 209 | const defined = definedMap.get(this); 210 | defined[key] = true; 211 | 212 | Object.defineProperty(this, key, descriptors); 213 | } 214 | 215 | /** 216 | * Check if value has defined 217 | * @param key 218 | * @private 219 | */ 220 | hasDefine(key) { 221 | return Boolean(definedMap.get(this)[key]); 222 | } 223 | 224 | /** 225 | * Remove value getter and setter 226 | * @param key 227 | * @private 228 | */ 229 | removeDefine(key) { 230 | if (!this.hasDefine(key)) return; 231 | 232 | const defined = definedMap.get(this); 233 | delete defined[key]; 234 | 235 | delete this[key]; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/vo/Page.js: -------------------------------------------------------------------------------- 1 | export default (content = [], pageNumber = 0, itemsNumber = 0, totalPages = 0, totalItems = 0) => { 2 | const paginator = { 3 | getContent() { 4 | return content; 5 | }, 6 | 7 | getPageNumber() { 8 | return pageNumber; 9 | }, 10 | 11 | getItemsNumber() { 12 | return itemsNumber; 13 | }, 14 | 15 | getTotalPages() { 16 | return totalPages; 17 | }, 18 | 19 | getTotalItems() { 20 | return totalItems; 21 | }, 22 | 23 | hasNext() { 24 | return (totalPages > pageNumber + 1); 25 | }, 26 | }; 27 | 28 | const paginatorKeys = Object.keys(paginator); 29 | 30 | return new Proxy(content, { 31 | get(target, key) { 32 | if (paginatorKeys.indexOf(key) !== -1) { 33 | return paginator[key]; 34 | } 35 | return target[key]; 36 | }, 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /src/vo/ValidationParameters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | export default class ValidationParameters { 9 | constructor() { 10 | this.parameters = {}; 11 | this.licenseeProperties = {}; 12 | } 13 | 14 | /** 15 | * Sets the target product 16 | * 17 | * optional productNumber, must be provided in case licensee auto-create is enabled 18 | * @param productNumber 19 | * @returns {ValidationParameters} 20 | */ 21 | setProductNumber(productNumber) { 22 | this.productNumber = productNumber; 23 | return this; 24 | } 25 | 26 | /** 27 | * Get the target product 28 | * @returns {*} 29 | */ 30 | getProductNumber() { 31 | return this.productNumber; 32 | } 33 | 34 | /** 35 | * Sets the name for the new licensee 36 | * 37 | * optional human-readable licensee name in case licensee will be auto-created. This parameter must not 38 | * be the name, but can be used to store any other useful string information with new licensees, up to 39 | * 1000 characters. 40 | * @param licenseeName 41 | * @returns {ValidationParameters} 42 | */ 43 | setLicenseeName(licenseeName) { 44 | this.licenseeProperties.licenseeName = licenseeName; 45 | return this; 46 | } 47 | 48 | /** 49 | * Get the licensee name 50 | * @returns {*} 51 | */ 52 | getLicenseeName() { 53 | return this.licenseeProperties.licenseeName; 54 | } 55 | 56 | /** 57 | * Sets the licensee secret 58 | * 59 | * licensee secret stored on the client side. Refer to Licensee Secret documentation for details. 60 | * @param licenseeSecret 61 | * @returns {ValidationParameters} 62 | * @deprecated use 'NodeLocked' licensingModel instead 63 | */ 64 | setLicenseeSecret(licenseeSecret) { 65 | this.licenseeProperties.licenseeSecret = licenseeSecret; 66 | return this; 67 | } 68 | 69 | /** 70 | * Get the licensee secret 71 | * @returns {*} 72 | * @deprecated use 'NodeLocked' licensingModel instead 73 | */ 74 | getLicenseeSecret() { 75 | return this.licenseeProperties.licenseeSecret; 76 | } 77 | 78 | /** 79 | * Get all licensee properties 80 | */ 81 | getLicenseeProperties() { 82 | return this.licenseeProperties; 83 | } 84 | 85 | /** 86 | * Set licensee property 87 | * @param key 88 | * @param value 89 | */ 90 | setLicenseeProperty(key, value) { 91 | this.licenseeProperties[key] = value; 92 | return this; 93 | } 94 | 95 | /** 96 | * Get licensee property 97 | * @param key 98 | */ 99 | getLicenseeProperty(key, def) { 100 | return this.licenseeProperties[key] || def; 101 | } 102 | 103 | /** 104 | * Indicates, that the validation response is intended the offline use 105 | * 106 | * @param forOfflineUse 107 | * if "true", validation response will be extended with data required for the offline use 108 | */ 109 | setForOfflineUse(forOfflineUse) { 110 | this.forOfflineUse = !!forOfflineUse; 111 | return this; 112 | } 113 | 114 | isForOfflineUse() { 115 | return !!this.forOfflineUse; 116 | } 117 | 118 | setDryRun(dryRun) { 119 | this.dryRun = !!dryRun; 120 | return this; 121 | } 122 | 123 | getDryRun(def) { 124 | return this.dryRun || def; 125 | } 126 | 127 | /** 128 | * Get validation parameters 129 | * @returns {*} 130 | */ 131 | getParameters() { 132 | return { ...this.parameters }; 133 | } 134 | 135 | getProductModuleValidationParameters(productModuleNumber) { 136 | return { ...this.parameters[productModuleNumber] }; 137 | } 138 | 139 | setProductModuleValidationParameters(productModuleNumber, productModuleParameters) { 140 | if (this.parameters[productModuleNumber] === undefined 141 | || !Object.keys(this.parameters[productModuleNumber]).length) { 142 | this.parameters[productModuleNumber] = {}; 143 | } 144 | 145 | this.parameters[productModuleNumber] = { ...this.parameters[productModuleNumber], ...productModuleParameters }; 146 | 147 | return this; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/vo/ValidationResults.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Labs64 3 | * @license Apache-2.0 4 | * @link https://netlicensing.io 5 | * @copyright 2017 Labs64 NetLicensing 6 | */ 7 | 8 | import CheckUtils from '../util/CheckUtils'; 9 | 10 | export default class ValidationResults { 11 | constructor() { 12 | this.validators = {}; 13 | } 14 | 15 | getValidators() { 16 | return { ...this.validators }; 17 | } 18 | 19 | setProductModuleValidation(productModuleNumber, productModuleValidation) { 20 | if (!CheckUtils.isValid(productModuleNumber) || typeof productModuleNumber === 'object') { 21 | throw new TypeError(`Bad productModuleNumber:${productModuleNumber}`); 22 | } 23 | 24 | this.validators[productModuleNumber] = productModuleValidation; 25 | 26 | return this; 27 | } 28 | 29 | getProductModuleValidation(productModuleNumber) { 30 | if (!CheckUtils.isValid(productModuleNumber) || typeof productModuleNumber === 'object') { 31 | throw new TypeError(`Bad productModuleNumber:${productModuleNumber}`); 32 | } 33 | 34 | return this.validators[productModuleNumber]; 35 | } 36 | 37 | setTtl(ttl) { 38 | if (!CheckUtils.isValid(ttl) || typeof ttl === 'object') { 39 | throw new TypeError(`Bad ttl:${ttl}`); 40 | } 41 | this.ttl = new Date(String(ttl)); 42 | 43 | return this; 44 | } 45 | 46 | getTtl() { 47 | return (this.ttl) ? new Date(this.ttl) : undefined; 48 | } 49 | 50 | toString() { 51 | let data = 'ValidationResult ['; 52 | 53 | const validators = this.getValidators(); 54 | const has = Object.prototype.hasOwnProperty; 55 | 56 | Object.keys(validators).forEach((productModuleNumber) => { 57 | data += `ProductModule<${productModuleNumber}>`; 58 | if (has.call(validators, productModuleNumber)) { 59 | data += JSON.stringify(validators[productModuleNumber]); 60 | } 61 | }); 62 | 63 | data += ']'; 64 | 65 | return data; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /test/factories/bundle.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Bundle from '@/entities/Bundle'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new Bundle({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | custom_property: faker.lorem.words(), 10 | 11 | ...data, 12 | })); 13 | -------------------------------------------------------------------------------- /test/factories/factory.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-param-reassign */ 2 | import isPlainObject from 'lodash/isPlainObject'; 3 | 4 | export default (factory) => (count = 1, data = {}) => { 5 | if (isPlainObject(count)) { 6 | data = count; 7 | count = 1; 8 | } 9 | const result = []; 10 | for (let i = 0; i < count; i += 1) { 11 | result.push(factory(data)); 12 | } 13 | 14 | return (result.length === 1) ? result[0] : result; 15 | }; 16 | -------------------------------------------------------------------------------- /test/factories/license.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import License from '@/entities/License'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new License({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.name.findName(), 8 | active: faker.datatype.boolean(), 9 | custom_property: faker.lorem.words(), 10 | 11 | ...data, 12 | })); 13 | -------------------------------------------------------------------------------- /test/factories/licenseTemplate.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import LicenseTemplate from '@/entities/LicenseTemplate'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new LicenseTemplate({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | licenseType: 'TIMEVOLUME', 10 | timeVolume: faker.datatype.number({ min: 1, max: 10 }), 11 | price: parseFloat(faker.commerce.price()), 12 | currency: 'EUR', 13 | custom_property: faker.lorem.words(), 14 | 15 | ...data, 16 | })); 17 | -------------------------------------------------------------------------------- /test/factories/licensee.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Licensee from '@/entities/Licensee'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new Licensee({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | custom_property: faker.lorem.words(), 10 | 11 | ...data, 12 | })); 13 | -------------------------------------------------------------------------------- /test/factories/notification.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Notification from '@/entities/Notification'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new Notification({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | protocol: Math.round(Math.random()) ? 'WEBHOOK' : 'EMAIL', 10 | events: faker.hacker.verb(), 11 | payload: faker.lorem.sentence(), 12 | endpoint: faker.internet.url(), 13 | custom_property: faker.lorem.words(), 14 | 15 | ...data, 16 | })); 17 | -------------------------------------------------------------------------------- /test/factories/paymentMethod.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import PaymentMethod from '@/entities/PaymentMethod'; 3 | import factory from './factory'; 4 | 5 | const randomItem = (array) => array[Math.floor(Math.random() * array.length)]; 6 | 7 | export default factory((data = {}) => new PaymentMethod({ 8 | number: randomItem(['PAYPAL', 'PAYPAL_SANDBOX', 'STRIPE']), 9 | active: faker.datatype.boolean(), 10 | 11 | ...data, 12 | })); 13 | -------------------------------------------------------------------------------- /test/factories/product.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Product from '@/entities/Product'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new Product({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | version: faker.system.semver(), 10 | description: faker.lorem.sentence(), 11 | licensingInfo: faker.lorem.sentence(), 12 | licenseeAutoCreate: faker.datatype.boolean(), 13 | custom_property: faker.lorem.words(), 14 | 15 | ...data, 16 | })); 17 | -------------------------------------------------------------------------------- /test/factories/productDiscount.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import ProductDiscount from '@/entities/ProductDiscount'; 3 | import factory from './factory'; 4 | 5 | export const fix = factory((data = {}) => new ProductDiscount({ 6 | totalPrice: faker.commerce.price(50), 7 | currency: 'EUR', 8 | amountFix: faker.datatype.number({ min: 1, max: 10 }), 9 | 10 | ...data, 11 | })); 12 | 13 | export const percent = factory((data = {}) => new ProductDiscount({ 14 | totalPrice: faker.commerce.price(50), 15 | currency: 'EUR', 16 | amountPercent: faker.datatype.number({ min: 1, max: 10 }), 17 | 18 | ...data, 19 | })); 20 | 21 | export default { 22 | fix, 23 | percent, 24 | }; 25 | -------------------------------------------------------------------------------- /test/factories/productModule.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import ProductModule from '@/entities/ProductModule'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new ProductModule({ 6 | number: Math.random().toString(36).substr(2, 9), 7 | name: faker.lorem.words(), 8 | active: faker.datatype.boolean(), 9 | licensingModel: 'Subscription', 10 | custom_property: faker.lorem.words(), 11 | 12 | ...data, 13 | })); 14 | -------------------------------------------------------------------------------- /test/factories/token.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Constants from '@/Constants'; 3 | import Token from '@/entities/Token'; 4 | import factory from './factory'; 5 | 6 | const randomItem = (array) => array[Math.floor(Math.random() * array.length)]; 7 | 8 | export default factory((data = {}) => { 9 | const token = new Token({ 10 | number: faker.datatype.uuid(), 11 | active: faker.datatype.boolean(), 12 | expirationTime: faker.date.future(), 13 | tokenType: randomItem(Object.values(Constants.Token.Type)), 14 | 15 | ...data, 16 | }); 17 | 18 | if (!token.licenseeNumber && token.tokenType === Constants.Token.Type.SHOP) { 19 | token.licenseeNumber = faker.datatype.uuid(); 20 | } 21 | 22 | return token; 23 | }); 24 | -------------------------------------------------------------------------------- /test/factories/transaction.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import Transaction from '@/entities/Transaction'; 3 | import factory from './factory'; 4 | 5 | export default factory((data = {}) => new Transaction({ 6 | number: faker.datatype.uuid(), 7 | source: 'SHOP', 8 | status: 'PENDING', 9 | 10 | ...data, 11 | })); 12 | -------------------------------------------------------------------------------- /test/factories/utility.js: -------------------------------------------------------------------------------- 1 | import factory from './factory'; 2 | 3 | const randomItem = (array) => array[Math.floor(Math.random() * array.length)]; 4 | 5 | export const licenseType = factory(() => ({ 6 | name: randomItem(['FEATURE', 'TIMEVOLUME', 'FLOATING', 'QUANTITY']), 7 | })); 8 | 9 | export const licensingModel = factory(() => ({ 10 | name: randomItem(['TimeLimitedEvaluation', 'TimeVolume', 'FeatureWithTimeVolume']), 11 | })); 12 | 13 | export default { 14 | licenseType, 15 | licensingModel, 16 | }; 17 | -------------------------------------------------------------------------------- /test/factories/validate.js: -------------------------------------------------------------------------------- 1 | import faker from 'faker'; 2 | import factory from './factory'; 3 | 4 | export default factory((data = {}) => ({ 5 | productModuleNumber: Math.random().toString(36).substr(2, 9), 6 | valid: faker.datatype.boolean(), 7 | expires: faker.date.future(), 8 | licensingModel: 'Subscription', 9 | 10 | ...data, 11 | })); 12 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import 'es6-promise/auto'; 2 | 3 | // require all test files (files that ends with .spec.js) 4 | const testsContext = require.context('./specs', true, /\.spec$/); 5 | testsContext.keys().forEach(testsContext); 6 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | const isDocker = require('is-docker')(); 6 | 7 | const webpackConfig = require('../build/webpack.test.conf.cjs'); 8 | 9 | delete webpackConfig.output; 10 | 11 | const browsers = ['Chrome']; 12 | 13 | if (!isDocker) { 14 | // browsers.push('Firefox'); 15 | } 16 | 17 | module.exports = (config) => { 18 | config.set({ 19 | // to run in additional browsers: 20 | // 1. install corresponding karma launcher 21 | // http://karma-runner.github.io/0.13/config/browsers.html 22 | // 2. add it to the `browsers` array below. 23 | browsers, 24 | customLaunchers: { 25 | Chrome: { 26 | base: 'ChromeHeadless', 27 | // We must disable the Chrome sandbox when running Chrome inside Docker 28 | // Chrome's sandbox needs more permissions than Docker allows by default 29 | flags: isDocker ? ['--no-sandbox'] : [], 30 | }, 31 | }, 32 | 33 | frameworks: ['jasmine', 'webpack'], 34 | 35 | reporters: ['spec'], 36 | 37 | files: [ 38 | './index.js', 39 | ], 40 | 41 | preprocessors: { 42 | './index.js': ['webpack', 'sourcemap'], 43 | }, 44 | 45 | webpack: webpackConfig, 46 | 47 | webpackMiddleware: { 48 | noInfo: true, 49 | }, 50 | 51 | coverageReporter: { 52 | dir: './coverage', 53 | reporters: [ 54 | { 55 | type: 'lcov', 56 | subdir: '.', 57 | }, 58 | { 59 | type: 'text-summary', 60 | }, 61 | ], 62 | }, 63 | }); 64 | }; 65 | -------------------------------------------------------------------------------- /test/response/Info.js: -------------------------------------------------------------------------------- 1 | export default class info { 2 | constructor(value, id, type = 'error') { 3 | this.value = value; 4 | this.id = id; 5 | this.type = type; 6 | } 7 | 8 | setValue(value) { 9 | this.value = value; 10 | return this; 11 | } 12 | 13 | getValue() { 14 | return this.value; 15 | } 16 | 17 | setId(id) { 18 | this.id = id; 19 | return this; 20 | } 21 | 22 | getId() { 23 | return this.id; 24 | } 25 | 26 | setType(type) { 27 | this.type = type; 28 | return this; 29 | } 30 | 31 | getType() { 32 | return this.type; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/response/Item.js: -------------------------------------------------------------------------------- 1 | import _each from 'lodash/each'; 2 | import _castArray from 'lodash/castArray'; 3 | import _isObject from 'lodash/isObject'; 4 | 5 | export default class Item { 6 | constructor(object = {}, type = null) { 7 | this.type = type || object.constructor.name; 8 | this.property = []; 9 | this.list = []; 10 | 11 | const covert = (obj, handler = { property: [], list: [] }) => { 12 | _each(obj, (value, name) => { 13 | if (_isObject(value)) { 14 | _each(_castArray(value), (v) => { 15 | const list = { property: [], list: [], name, type: v.constructor.name }; 16 | handler.list.push(list); 17 | covert(v, list); 18 | }); 19 | return; 20 | } 21 | 22 | const property = { value, name }; 23 | handler.property.push(property); 24 | }); 25 | }; 26 | 27 | if (_isObject(object)) { 28 | covert(object, this); 29 | } 30 | } 31 | 32 | getProperty() { 33 | return this.property; 34 | } 35 | 36 | addProperty(key, value) { 37 | this.property.push(key, value); 38 | return this; 39 | } 40 | 41 | getList() { 42 | return this.list; 43 | } 44 | 45 | setType(type) { 46 | this.type = type; 47 | } 48 | 49 | getType() { 50 | return this.type; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/response/index.js: -------------------------------------------------------------------------------- 1 | import _castArray from 'lodash/castArray'; 2 | import Item from './Item'; 3 | import Info from './Info'; 4 | 5 | export default class Response { 6 | constructor(data = []) { 7 | this.id = null; 8 | this.ttl = null; 9 | this.items = { 10 | item: [], 11 | pagenumber: null, 12 | itemsnumber: null, 13 | totalpages: null, 14 | totalitems: null, 15 | hasnext: null, 16 | }; 17 | this.infos = { info: [] }; 18 | 19 | _castArray(data).forEach((v) => { 20 | if (v instanceof Item) { 21 | this.items.item.push(v); 22 | } else if (v instanceof Info) { 23 | this.infos.info.push(v); 24 | } 25 | }); 26 | 27 | this.setPage(); 28 | } 29 | 30 | addItem(item) { 31 | if (!(item instanceof Item)) { 32 | throw new Error('Expected item to be an instance of the "Item"'); 33 | } 34 | 35 | this.items.item.push(item); 36 | 37 | const page = this.items.pagenumber; 38 | const perPage = this.items.totalitems / this.items.totalpages; 39 | const totalItems = this.items.totalitems; 40 | 41 | this.setPage(page, perPage, totalItems); 42 | 43 | return this; 44 | } 45 | 46 | addInfo(info) { 47 | if (!(info instanceof Info)) { 48 | throw new Error('Expected info to be an instance of the "Info"'); 49 | } 50 | 51 | this.infos.info.push(info); 52 | 53 | return this; 54 | } 55 | 56 | setTTL(ttl) { 57 | this.ttl = ttl; 58 | } 59 | 60 | setPage(page = 0, perPage = 100, totalItems = this.items.item.length) { 61 | this.items.pagenumber = page; 62 | this.items.itemsnumber = this.items.item.length; 63 | this.items.totalpages = Math.ceil(totalItems / perPage); 64 | this.items.totalitems = totalItems; 65 | this.items.hasnext = this.items.totalpages > this.items.pagenumber + 1; 66 | return this; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /test/specs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jasmine": true 4 | }, 5 | "plugins": [ 6 | "jasmine" 7 | ] 8 | } -------------------------------------------------------------------------------- /test/specs/entities/Country.spec.js: -------------------------------------------------------------------------------- 1 | import Country from '@/entities/Country'; 2 | 3 | describe('entities/Country', () => { 4 | let country; 5 | 6 | beforeEach(() => { 7 | country = new Country(); 8 | }); 9 | 10 | it('check "code" property setters/getters', () => { 11 | country.setProperty('code', 'DE'); 12 | expect(country.getProperty('code')).toBe('DE'); 13 | expect(country.getCode()).toBe('DE'); 14 | expect(country.code).toBe('DE'); 15 | 16 | country.setCode('BY'); 17 | expect(country.getProperty('code')).toBe('BY'); 18 | expect(country.getCode()).toBe('BY'); 19 | expect(country.code).toBe('BY'); 20 | 21 | country.code = 'UA'; 22 | expect(country.getProperty('code')).toBe('UA'); 23 | expect(country.getCode()).toBe('UA'); 24 | expect(country.code).toBe('UA'); 25 | }); 26 | 27 | it('check "name" property setters/getters', () => { 28 | country.setProperty('name', 'name_0'); 29 | expect(country.getProperty('name')).toBe('name_0'); 30 | expect(country.getName()).toBe('name_0'); 31 | expect(country.name).toBe('name_0'); 32 | 33 | country.setName('name_1'); 34 | expect(country.getProperty('name')).toBe('name_1'); 35 | expect(country.getName()).toBe('name_1'); 36 | expect(country.name).toBe('name_1'); 37 | 38 | country.name = 'name_2'; 39 | expect(country.getProperty('name')).toBe('name_2'); 40 | expect(country.getName()).toBe('name_2'); 41 | expect(country.name).toBe('name_2'); 42 | }); 43 | 44 | it('check "vatPercent" property setters/getters', () => { 45 | country.setProperty('vatPercent', 10); 46 | expect(country.getProperty('vatPercent')).toBe(10); 47 | expect(country.getVatPercent()).toBe(10); 48 | expect(country.vatPercent).toBe(10); 49 | 50 | country.setVatPercent(20); 51 | expect(country.getProperty('vatPercent')).toBe(20); 52 | expect(country.getVatPercent()).toBe(20); 53 | expect(country.vatPercent).toBe(20); 54 | 55 | country.vatPercent = 30; 56 | expect(country.getProperty('vatPercent')).toBe(30); 57 | expect(country.getVatPercent()).toBe(30); 58 | expect(country.vatPercent).toBe(30); 59 | }); 60 | 61 | it('check "isEu" property setters/getters', () => { 62 | country.setProperty('isEu', true); 63 | expect(country.getProperty('isEu')).toBe(true); 64 | expect(country.getIsEu()).toBe(true); 65 | expect(country.isEu).toBe(true); 66 | 67 | country.setIsEu(false); 68 | expect(country.getProperty('isEu')).toBe(false); 69 | expect(country.getIsEu()).toBe(false); 70 | expect(country.isEu).toBe(false); 71 | 72 | country.isEu = true; 73 | expect(country.getProperty('isEu')).toBe(true); 74 | expect(country.getIsEu()).toBe(true); 75 | expect(country.isEu).toBe(true); 76 | }); 77 | 78 | it('check cast an properties to a native js type', () => { 79 | country.setProperty('code', 1); 80 | expect(country.getProperty('code')).toBe('1'); 81 | country.setProperty('code', true); 82 | expect(country.getProperty('code')).toBe('true'); 83 | 84 | country.setProperty('name', 1); 85 | expect(country.getProperty('name')).toBe('1'); 86 | country.setProperty('name', true); 87 | expect(country.getProperty('name')).toBe('true'); 88 | 89 | country.setProperty('vatPercent', '015'); 90 | expect(country.getProperty('vatPercent')).toBe(15); 91 | country.setProperty('vatPercent', 15.99); 92 | expect(country.getProperty('vatPercent')).toBe(15); 93 | country.setProperty('vatPercent', '15*3'); 94 | expect(country.getProperty('vatPercent')).toBe(15); 95 | country.setProperty('vatPercent', '15e2'); 96 | expect(country.getProperty('vatPercent')).toBe(15); 97 | 98 | country.setProperty('isEu', 1); 99 | expect(country.getProperty('isEu')).toBe(true); 100 | country.setProperty('isEu', 0); 101 | expect(country.getProperty('isEu')).toBe(false); 102 | country.setProperty('isEu', ''); 103 | expect(country.getProperty('isEu')).toBe(false); 104 | country.setProperty('isEu', '123'); 105 | expect(country.getProperty('isEu')).toBe(true); 106 | country.setProperty('isEu', null); 107 | expect(country.getProperty('isEu')).toBe(false); 108 | }); 109 | 110 | it('check "removeProperty" method', () => { 111 | country.setProperty('code', 'EU'); 112 | country.removeProperty('code'); 113 | 114 | expect(country.getProperty('code')).toBe(undefined); 115 | expect(country.code).toBe(undefined); 116 | expect(country.getCode()).toBe(undefined); 117 | }); 118 | 119 | it('check "removeDefine" method', () => { 120 | country.setProperty('code', 'EU'); 121 | country.removeDefine('code'); 122 | 123 | expect(country.code).toBe(undefined); 124 | expect(country.getProperty('code')).toBe('EU'); 125 | expect(country.getCode()).toBe('EU'); 126 | 127 | country.code = 'DE'; 128 | 129 | expect(country.code).toBe('DE'); 130 | expect(country.getProperty('code')).toBe('EU'); 131 | expect(country.getCode()).toBe('EU'); 132 | }); 133 | }); 134 | -------------------------------------------------------------------------------- /test/specs/entities/PaymentMethod.spec.js: -------------------------------------------------------------------------------- 1 | import PaymentMethod from '@/entities/PaymentMethod'; 2 | 3 | describe('entities/PaymentMethod', () => { 4 | let paymentMethod; 5 | 6 | beforeEach(() => { 7 | paymentMethod = new PaymentMethod(); 8 | }); 9 | 10 | it('check "number" property setters/getters', () => { 11 | paymentMethod.setProperty('number', 'number_0'); 12 | expect(paymentMethod.getProperty('number')).toBe('number_0'); 13 | expect(paymentMethod.getNumber()).toBe('number_0'); 14 | expect(paymentMethod.number).toBe('number_0'); 15 | 16 | paymentMethod.setNumber('number_1'); 17 | expect(paymentMethod.getProperty('number')).toBe('number_1'); 18 | expect(paymentMethod.getNumber()).toBe('number_1'); 19 | expect(paymentMethod.number).toBe('number_1'); 20 | 21 | paymentMethod.number = 'number_2'; 22 | expect(paymentMethod.getProperty('number')).toBe('number_2'); 23 | expect(paymentMethod.getNumber()).toBe('number_2'); 24 | expect(paymentMethod.number).toBe('number_2'); 25 | }); 26 | 27 | it('check "active" property setters/getters', () => { 28 | paymentMethod.setProperty('active', true); 29 | expect(paymentMethod.getProperty('active')).toBe(true); 30 | expect(paymentMethod.getActive()).toBe(true); 31 | expect(paymentMethod.active).toBe(true); 32 | 33 | paymentMethod.setActive(false); 34 | expect(paymentMethod.getProperty('active')).toBe(false); 35 | expect(paymentMethod.getActive()).toBe(false); 36 | expect(paymentMethod.active).toBe(false); 37 | 38 | paymentMethod.active = true; 39 | expect(paymentMethod.getProperty('active')).toBe(true); 40 | expect(paymentMethod.getActive()).toBe(true); 41 | expect(paymentMethod.active).toBe(true); 42 | }); 43 | 44 | it('check "paypal.subject" property setters/getters', () => { 45 | paymentMethod.setProperty('paypal.subject', 'subject_0'); 46 | expect(paymentMethod.getProperty('paypal.subject')).toBe('subject_0'); 47 | expect(paymentMethod.getPaypalSubject()).toBe('subject_0'); 48 | expect(paymentMethod['paypal.subject']).toBe('subject_0'); 49 | 50 | paymentMethod.setPaypalSubject('subject_1'); 51 | expect(paymentMethod.getProperty('paypal.subject')).toBe('subject_1'); 52 | expect(paymentMethod.getPaypalSubject()).toBe('subject_1'); 53 | expect(paymentMethod['paypal.subject']).toBe('subject_1'); 54 | 55 | paymentMethod['paypal.subject'] = 'subject_2'; 56 | expect(paymentMethod.getProperty('paypal.subject')).toBe('subject_2'); 57 | expect(paymentMethod.getPaypalSubject()).toBe('subject_2'); 58 | expect(paymentMethod['paypal.subject']).toBe('subject_2'); 59 | }); 60 | 61 | it('check cast an properties to a native js type', () => { 62 | paymentMethod.setProperty('number', 1); 63 | expect(paymentMethod.getProperty('number')).toBe('1'); 64 | paymentMethod.setProperty('number', true); 65 | expect(paymentMethod.getProperty('number')).toBe('true'); 66 | 67 | paymentMethod.setProperty('active', 1); 68 | expect(paymentMethod.getProperty('active')).toBe(true); 69 | paymentMethod.setProperty('active', 0); 70 | expect(paymentMethod.getProperty('active')).toBe(false); 71 | paymentMethod.setProperty('active', ''); 72 | expect(paymentMethod.getProperty('active')).toBe(false); 73 | paymentMethod.setProperty('active', '123'); 74 | expect(paymentMethod.getProperty('active')).toBe(true); 75 | paymentMethod.setProperty('active', null); 76 | expect(paymentMethod.getProperty('active')).toBe(false); 77 | 78 | paymentMethod.setProperty('paypal.subject', 1); 79 | expect(paymentMethod.getProperty('paypal.subject')).toBe('1'); 80 | paymentMethod.setProperty('paypal.subject', true); 81 | expect(paymentMethod.getProperty('paypal.subject')).toBe('true'); 82 | }); 83 | 84 | it('check "removeProperty" method', () => { 85 | paymentMethod.setProperty('number', 'number'); 86 | paymentMethod.removeProperty('number'); 87 | 88 | expect(paymentMethod.getProperty('number')).toBe(undefined); 89 | expect(paymentMethod.number).toBe(undefined); 90 | expect(paymentMethod.getNumber()).toBe(undefined); 91 | }); 92 | 93 | it('check "removeDefine" method', () => { 94 | paymentMethod.setProperty('number', 'number'); 95 | paymentMethod.removeDefine('number'); 96 | 97 | expect(paymentMethod.number).toBe(undefined); 98 | expect(paymentMethod.getProperty('number')).toBe('number'); 99 | expect(paymentMethod.getNumber()).toBe('number'); 100 | 101 | paymentMethod.number = 'number_1'; 102 | 103 | expect(paymentMethod.number).toBe('number_1'); 104 | expect(paymentMethod.getProperty('number')).toBe('number'); 105 | expect(paymentMethod.getNumber()).toBe('number'); 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /test/specs/entities/ProductDiscount.spec.js: -------------------------------------------------------------------------------- 1 | import ProductDiscount from '@/entities/ProductDiscount'; 2 | 3 | describe('entities/ProductDiscount', () => { 4 | let productDiscount; 5 | 6 | beforeEach(() => { 7 | productDiscount = new ProductDiscount(); 8 | }); 9 | 10 | it('check "totalPrice" property setters/getters', () => { 11 | productDiscount.setProperty('totalPrice', 10); 12 | expect(productDiscount.getProperty('totalPrice')).toBe(10); 13 | expect(productDiscount.getTotalPrice()).toBe(10); 14 | expect(productDiscount.totalPrice).toBe(10); 15 | 16 | productDiscount.setTotalPrice(20); 17 | expect(productDiscount.getProperty('totalPrice')).toBe(20); 18 | expect(productDiscount.getTotalPrice()).toBe(20); 19 | expect(productDiscount.totalPrice).toBe(20); 20 | 21 | productDiscount.totalPrice = 30; 22 | expect(productDiscount.getProperty('totalPrice')).toBe(30); 23 | expect(productDiscount.getTotalPrice()).toBe(30); 24 | expect(productDiscount.totalPrice).toBe(30); 25 | }); 26 | 27 | it('check "currency" property setters/getters', () => { 28 | productDiscount.setProperty('currency', 'EUR'); 29 | expect(productDiscount.getProperty('currency')).toBe('EUR'); 30 | expect(productDiscount.getCurrency()).toBe('EUR'); 31 | expect(productDiscount.currency).toBe('EUR'); 32 | 33 | productDiscount.setCurrency('USD'); 34 | expect(productDiscount.getProperty('currency')).toBe('USD'); 35 | expect(productDiscount.getCurrency()).toBe('USD'); 36 | expect(productDiscount.currency).toBe('USD'); 37 | 38 | productDiscount.currency = 'BYN'; 39 | expect(productDiscount.getProperty('currency')).toBe('BYN'); 40 | expect(productDiscount.getCurrency()).toBe('BYN'); 41 | expect(productDiscount.currency).toBe('BYN'); 42 | }); 43 | 44 | it('check "amountFix" property setters/getters', () => { 45 | productDiscount.setProperty('amountFix', 10); 46 | expect(productDiscount.getProperty('amountFix')).toBe(10); 47 | expect(productDiscount.getAmountFix()).toBe(10); 48 | expect(productDiscount.amountFix).toBe(10); 49 | 50 | productDiscount.setAmountFix(20); 51 | expect(productDiscount.getProperty('amountFix')).toBe(20); 52 | expect(productDiscount.getAmountFix()).toBe(20); 53 | expect(productDiscount.amountFix).toBe(20); 54 | 55 | productDiscount.amountFix = 30; 56 | expect(productDiscount.getProperty('amountFix')).toBe(30); 57 | expect(productDiscount.getAmountFix()).toBe(30); 58 | expect(productDiscount.amountFix).toBe(30); 59 | }); 60 | 61 | it('check "amountPercent" property setters/getters', () => { 62 | productDiscount.setProperty('amountPercent', 10); 63 | expect(productDiscount.getProperty('amountPercent')).toBe(10); 64 | expect(productDiscount.getAmountPercent()).toBe(10); 65 | expect(productDiscount.amountPercent).toBe(10); 66 | 67 | productDiscount.setAmountPercent(20); 68 | expect(productDiscount.getProperty('amountPercent')).toBe(20); 69 | expect(productDiscount.getAmountPercent()).toBe(20); 70 | expect(productDiscount.amountPercent).toBe(20); 71 | 72 | productDiscount.amountPercent = 30; 73 | expect(productDiscount.getProperty('amountPercent')).toBe(30); 74 | expect(productDiscount.getAmountPercent()).toBe(30); 75 | expect(productDiscount.amountPercent).toBe(30); 76 | }); 77 | 78 | it('check "toString" method', () => { 79 | productDiscount.setProperty('totalPrice', 100); 80 | productDiscount.setProperty('currency', 'EUR'); 81 | productDiscount.setProperty('amountFix', 5); 82 | expect(productDiscount.toString()).toBe('100;EUR;5'); 83 | 84 | productDiscount.setProperty('totalPrice', 50); 85 | productDiscount.setProperty('currency', 'USD'); 86 | productDiscount.setProperty('amountPercent', 10); 87 | expect(productDiscount.toString()).toBe('50;USD;10%'); 88 | }); 89 | 90 | it('check cast an properties to a native js type', () => { 91 | productDiscount.setProperty('totalPrice', '3.14'); 92 | expect(productDiscount.getProperty('totalPrice')).toBe(3.14); 93 | productDiscount.setProperty('totalPrice', '314e-2'); 94 | expect(productDiscount.getProperty('totalPrice')).toBe(3.14); 95 | productDiscount.setProperty('totalPrice', '0.0314E+2'); 96 | expect(productDiscount.getProperty('totalPrice')).toBe(3.14); 97 | productDiscount.setProperty('totalPrice', '3.14any non-numeric characters'); 98 | expect(productDiscount.getProperty('totalPrice')).toBe(3.14); 99 | 100 | productDiscount.setProperty('currency', 1); 101 | expect(productDiscount.getProperty('currency')).toBe('1'); 102 | productDiscount.setProperty('currency', true); 103 | expect(productDiscount.getProperty('currency')).toBe('true'); 104 | 105 | productDiscount.setProperty('amountFix', '3.14'); 106 | expect(productDiscount.getProperty('amountFix')).toBe(3.14); 107 | productDiscount.setProperty('amountFix', '314e-2'); 108 | expect(productDiscount.getProperty('amountFix')).toBe(3.14); 109 | productDiscount.setProperty('amountFix', '0.0314E+2'); 110 | expect(productDiscount.getProperty('amountFix')).toBe(3.14); 111 | productDiscount.setProperty('amountFix', '3.14any non-numeric characters'); 112 | expect(productDiscount.getProperty('amountFix')).toBe(3.14); 113 | 114 | productDiscount.setProperty('amountPercent', '015'); 115 | expect(productDiscount.getProperty('amountPercent')).toBe(15); 116 | productDiscount.setProperty('amountPercent', 15.99); 117 | expect(productDiscount.getProperty('amountPercent')).toBe(15); 118 | productDiscount.setProperty('amountPercent', '15*3'); 119 | expect(productDiscount.getProperty('amountPercent')).toBe(15); 120 | productDiscount.setProperty('amountPercent', '15e2'); 121 | expect(productDiscount.getProperty('amountPercent')).toBe(15); 122 | }); 123 | 124 | it('check "removeProperty" method', () => { 125 | productDiscount.setProperty('totalPrice', 10); 126 | productDiscount.removeProperty('totalPrice'); 127 | 128 | expect(productDiscount.getProperty('totalPrice')).toBe(undefined); 129 | expect(productDiscount.totalPrice).toBe(undefined); 130 | expect(productDiscount.getTotalPrice()).toBe(undefined); 131 | }); 132 | 133 | it('check "removeDefine" method', () => { 134 | productDiscount.setProperty('totalPrice', 20); 135 | productDiscount.removeDefine('totalPrice'); 136 | 137 | expect(productDiscount.totalPrice).toBe(undefined); 138 | expect(productDiscount.getProperty('totalPrice')).toBe(20); 139 | expect(productDiscount.getTotalPrice()).toBe(20); 140 | 141 | productDiscount.totalPrice = 30; 142 | 143 | expect(productDiscount.totalPrice).toBe(30); 144 | expect(productDiscount.getProperty('totalPrice')).toBe(20); 145 | expect(productDiscount.getTotalPrice()).toBe(20); 146 | }); 147 | }); 148 | -------------------------------------------------------------------------------- /test/specs/services/PaymentMethodService.spec.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import AxiosMockAdapter from 'axios-mock-adapter'; 3 | import paymentMethodFactory from 'test@/factories/paymentMethod'; 4 | import Item from 'test@/response/Item'; 5 | import Info from 'test@/response/Info'; 6 | import Response from 'test@/response'; 7 | import Context from '@/vo/Context'; 8 | import PaymentMethod from '@/entities/PaymentMethod'; 9 | import PaymentMethodService from '@/services/PaymentMethodService'; 10 | import NlicError from '@/errors/NlicError'; 11 | 12 | describe('services/PaymentMethodService', () => { 13 | let context; 14 | let mock; 15 | 16 | beforeAll(() => { 17 | context = new Context().setUsername('Demo').setPassword('demo'); 18 | }); 19 | 20 | beforeEach(() => { 21 | mock = new AxiosMockAdapter(axios); 22 | }); 23 | 24 | describe('check "get" method', () => { 25 | it('should return entity', async () => { 26 | const paymentMethod = paymentMethodFactory(); 27 | 28 | // configure mock for get request 29 | mock.onGet(`${context.getBaseUrl()}/paymentmethod/${paymentMethod.number}`) 30 | .reply(200, new Response(new Item(paymentMethod))); 31 | 32 | const entity = await PaymentMethodService.get(context, paymentMethod.number); 33 | 34 | expect(entity instanceof PaymentMethod).toBe(true); 35 | expect(entity.getProperty('number', null)).toBe(paymentMethod.number); 36 | }); 37 | 38 | it('should throw error when payment method is not supported', async () => { 39 | const number = 'Payment-that-is-not-supported'; 40 | 41 | // configure mock for get request 42 | mock.onGet(`${context.getBaseUrl()}/paymentmethod/${number}`) 43 | .reply(() => { 44 | if (['PAYPAL', 'PAYPAL_SANDBOX', 'STRIPE'].indexOf(number) === -1) { 45 | return [400, new Response( 46 | new Info('Requested payment method is not supported', 'MalformedRequestException'), 47 | )]; 48 | } 49 | 50 | return [200, new Response(new Item(paymentMethodFactory({ number })))]; 51 | }); 52 | 53 | try { 54 | await PaymentMethodService.get(context, number); 55 | 56 | fail('should throw error'); 57 | } catch (e) { 58 | expect(e instanceof Error).toBe(true); 59 | } 60 | }); 61 | 62 | it('should throw error when entity not found', async () => { 63 | const number = 'Any-number-that-not-exist'; 64 | 65 | // configure mock for get request 66 | mock.onGet(`${context.getBaseUrl()}/paymentmethod/${number}`) 67 | .reply(400, new Response( 68 | new Info('Requested paymentMethod does not exist', 'NotFoundException'), 69 | )); 70 | 71 | try { 72 | await PaymentMethodService.get(context, number); 73 | fail('should throw error'); 74 | } catch (e) { 75 | expect(e instanceof NlicError).toBe(true); 76 | } 77 | }); 78 | }); 79 | 80 | describe('check "list" method', async () => { 81 | it('should return entities array', async () => { 82 | const paymentMethods = paymentMethodFactory(3); 83 | 84 | // configure mock for list request 85 | mock.onGet(`${context.getBaseUrl()}/paymentmethod`) 86 | .reply(200, new Response(paymentMethods.map((v) => new Item(v)))); 87 | 88 | const list = await PaymentMethodService.list(context); 89 | 90 | expect(Array.isArray(list)).toBe(true); 91 | expect(list.length).toBe(3); 92 | 93 | list.forEach((entity, k) => { 94 | const paymentMethod = paymentMethods[k]; 95 | expect(entity instanceof PaymentMethod).toBe(true); 96 | expect(entity.getProperty('number', null)).toBe(paymentMethod.number); 97 | expect(entity.getProperty('active', null)).toBe(paymentMethod.active); 98 | }); 99 | }); 100 | 101 | it('should has pagination', async () => { 102 | const paymentMethods = paymentMethodFactory(3); 103 | 104 | // configure mock for list request 105 | mock.onGet(`${context.getBaseUrl()}/paymentmethod`) 106 | .reply(200, new Response(paymentMethods.map((v) => new Item(v)))); 107 | 108 | const list = await PaymentMethodService.list(context); 109 | 110 | expect(list.getPageNumber()).toBe(0); 111 | expect(list.getItemsNumber()).toBe(3); 112 | expect(list.getTotalPages()).toBe(1); 113 | expect(list.getTotalItems()).toBe(3); 114 | expect(list.hasNext()).toBe(false); 115 | }); 116 | }); 117 | }); 118 | -------------------------------------------------------------------------------- /test/specs/services/TokenService.spec.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import AxiosMockAdapter from 'axios-mock-adapter'; 3 | import tokenFactory from 'test@/factories/token'; 4 | import Item from 'test@/response/Item'; 5 | import Info from 'test@/response/Info'; 6 | import Response from 'test@/response'; 7 | import Context from '@/vo/Context'; 8 | import Token from '@/entities/Token'; 9 | import TokenService from '@/services/TokenService'; 10 | import Constants from '@/Constants'; 11 | import Service from '@/services/Service'; 12 | import NlicError from '@/errors/NlicError'; 13 | 14 | describe('services/TokenService', () => { 15 | let context; 16 | let mock; 17 | 18 | beforeAll(() => { 19 | context = new Context().setUsername('Demo').setPassword('demo'); 20 | }); 21 | 22 | beforeEach(() => { 23 | mock = new AxiosMockAdapter(axios); 24 | }); 25 | 26 | it('check "create" method', async () => { 27 | const token = tokenFactory({ 28 | tokenType: Constants.Token.Type.SHOP, 29 | licenseeNumber: 'some number', 30 | }); 31 | 32 | // configure mock for create request 33 | mock.onPost(`${context.getBaseUrl()}/token`) 34 | .reply(200, new Response(new Item(token))); 35 | 36 | const entity = await TokenService.create(context, token); 37 | 38 | expect(entity instanceof Token).toBe(true); 39 | expect(entity.getProperty('number', null)).toBeTruthy(); 40 | expect(entity.getProperty('tokenType', null)).toBe(token.getProperty('tokenType')); 41 | expect(entity.getProperty('licenseeNumber', null)).toBe(token.getProperty('licenseeNumber')); 42 | expect(entity.getProperty('expirationTime', null) instanceof Date).toBe(true); 43 | }); 44 | 45 | describe('check "get" method', () => { 46 | it('should return entity', async () => { 47 | const token = tokenFactory({ 48 | tokenType: Constants.Token.Type.SHOP, 49 | licenseeNumber: 'some number', 50 | }); 51 | 52 | // configure mock for get request 53 | mock.onGet(`${context.getBaseUrl()}/token/${token.number}`) 54 | .reply(200, new Response(new Item(token))); 55 | 56 | const entity = await TokenService.get(context, token.number); 57 | 58 | expect(entity instanceof Token).toBe(true); 59 | expect(entity.getProperty('number', null)).toBeTruthy(); 60 | expect(entity.getProperty('tokenType', null)).toBe(token.tokenType); 61 | expect(entity.getProperty('licenseeNumber', null)).toBe(token.licenseeNumber); 62 | expect(entity.getProperty('expirationTime', null) instanceof Date).toBe(true); 63 | }); 64 | 65 | it('should throw error when entity not found', async () => { 66 | const number = 'Any-number-that-not-exist'; 67 | 68 | // configure mock for product get request 69 | mock.onGet(`${context.getBaseUrl()}/token/${number}`) 70 | .reply(400, new Response( 71 | new Info('Requested token does not exist', 'NotFoundException'), 72 | )); 73 | 74 | try { 75 | await TokenService.get(context, number); 76 | fail('should throw error'); 77 | } catch (e) { 78 | expect(e instanceof NlicError).toBe(true); 79 | } 80 | }); 81 | }); 82 | 83 | describe('check "list" method', async () => { 84 | it('should return entities array', async () => { 85 | const tokens = tokenFactory(10, { 86 | tokenType: Constants.Token.Type.SHOP, 87 | }); 88 | 89 | // configure mock for list request 90 | mock.onGet(`${context.getBaseUrl()}/token`) 91 | .reply(200, new Response(tokens.map((v) => new Item(v)))); 92 | 93 | const list = await TokenService.list(context); 94 | 95 | expect(Array.isArray(list)).toBe(true); 96 | expect(list.length).toBe(10); 97 | 98 | list.forEach((entity, k) => { 99 | const token = tokens[k]; 100 | expect(entity instanceof Token).toBe(true); 101 | expect(entity.getProperty('number', null)).toBeTruthy(); 102 | expect(entity.getProperty('tokenType', null)).toBe(token.tokenType); 103 | expect(entity.getProperty('licenseeNumber', null)).toBe(token.licenseeNumber); 104 | expect(entity.getProperty('expirationTime', null) instanceof Date).toBe(true); 105 | }); 106 | }); 107 | 108 | it('should has pagination', async () => { 109 | const tokens = tokenFactory(100); 110 | 111 | // configure mock for list request 112 | mock.onGet(`${context.getBaseUrl()}/token`) 113 | .reply(() => { 114 | const response = new Response(tokens.map((v) => new Item(v))); 115 | response.setPage(1, 100, 200); 116 | 117 | return [200, response]; 118 | }); 119 | 120 | const list = await TokenService.list(context, { page: 1 }); 121 | 122 | expect(list.getPageNumber()).toBe(1); 123 | expect(list.getItemsNumber()).toBe(100); 124 | expect(list.getTotalPages()).toBe(2); 125 | expect(list.getTotalItems()).toBe(200); 126 | expect(list.hasNext()).toBe(false); 127 | }); 128 | 129 | it('check "filter parameter in list" method', async () => { 130 | const token = tokenFactory({ 131 | tokenType: Constants.Token.Type.SHOP, 132 | licenseeNumber: 'some number', 133 | }); 134 | 135 | // configure mock for list request 136 | mock.onGet(`${context.getBaseUrl()}/token`) 137 | .reply(200, new Response(new Item(token))); 138 | 139 | // if filter parameter is object 140 | await TokenService.list(context, { page: 2, items: 10 }); 141 | 142 | expect(Service.getLastHttpRequestInfo().config.params.filter).toBe('page=2;items=10'); 143 | 144 | // if filter parameter is string 145 | await TokenService.list(context, 'page=3;items=20'); 146 | 147 | expect(Service.getLastHttpRequestInfo().config.params.filter).toBe('page=3;items=20'); 148 | }); 149 | }); 150 | 151 | it('check "delete" method', async () => { 152 | const number = 'some-number'; 153 | 154 | // configure mock for delete request 155 | mock.onDelete(`${context.getBaseUrl()}/token/${number}`) 156 | .reply(204); 157 | 158 | await TokenService.delete(context, number); 159 | 160 | expect(Service.getLastHttpRequestInfo().status).toBe(204); 161 | }); 162 | }); 163 | -------------------------------------------------------------------------------- /test/specs/services/TransactionService.spec.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import AxiosMockAdapter from 'axios-mock-adapter'; 3 | import transactionFactory from 'test@/factories/transaction'; 4 | import Item from 'test@/response/Item'; 5 | import Info from 'test@/response/Info'; 6 | import Response from 'test@/response'; 7 | import Context from '@/vo/Context'; 8 | import Transaction from '@/entities/Transaction'; 9 | import TransactionService from '@/services/TransactionService'; 10 | import Service from '@/services/Service'; 11 | import NlicError from '@/errors/NlicError'; 12 | 13 | describe('services/TransactionService', () => { 14 | let context; 15 | let mock; 16 | 17 | beforeAll(() => { 18 | context = new Context().setUsername('Demo').setPassword('demo'); 19 | }); 20 | 21 | beforeEach(() => { 22 | mock = new AxiosMockAdapter(axios); 23 | }); 24 | 25 | it('check "create" method', async () => { 26 | const transaction = transactionFactory(); 27 | 28 | // configure mock for create request 29 | mock.onPost(`${context.getBaseUrl()}/transaction`) 30 | .reply(200, new Response(new Item(transaction))); 31 | 32 | const entity = await TransactionService.create(context, transaction); 33 | 34 | expect(entity instanceof Transaction).toBe(true); 35 | expect(entity.getProperty('number', null)).toBe(transaction.number); 36 | expect(entity.getProperty('status', null)).toBe(transaction.status); 37 | expect(entity.getProperty('source', null)).toBe(transaction.source); 38 | }); 39 | 40 | describe('check "get" method', () => { 41 | it('should return entity', async () => { 42 | const transaction = transactionFactory(); 43 | 44 | // configure mock for get request 45 | mock.onGet(`${context.getBaseUrl()}/transaction/${transaction.number}`) 46 | .reply(200, new Response(new Item(transaction))); 47 | 48 | const entity = await TransactionService.get(context, transaction.number); 49 | 50 | expect(entity instanceof Transaction).toBe(true); 51 | expect(entity.getProperty('number', null)).toBe(transaction.number); 52 | expect(entity.getProperty('status', null)).toBe(transaction.status); 53 | expect(entity.getProperty('source', null)).toBe(transaction.source); 54 | }); 55 | 56 | it('should throw error when entity not found', async () => { 57 | const number = 'Any-number-that-not-exist'; 58 | 59 | // configure mock for product get request 60 | mock.onGet(`${context.getBaseUrl()}/transaction/${number}`) 61 | .reply(400, new Response( 62 | new Info('Requested transaction does not exist', 'NotFoundException'), 63 | )); 64 | try { 65 | await TransactionService.get(context, number); 66 | fail('should throw error'); 67 | } catch (e) { 68 | expect(e instanceof NlicError).toBe(true); 69 | } 70 | }); 71 | }); 72 | 73 | describe('check "list" method', async () => { 74 | it('should return entities array', async () => { 75 | const transactions = transactionFactory(10); 76 | 77 | // configure mock for list request 78 | mock.onGet(`${context.getBaseUrl()}/transaction`) 79 | .reply(200, new Response(transactions.map((v) => new Item(v)))); 80 | 81 | const list = await TransactionService.list(context); 82 | 83 | expect(Array.isArray(list)).toBe(true); 84 | expect(list.length).toBe(10); 85 | 86 | list.forEach((entity, k) => { 87 | const transaction = transactions[k]; 88 | expect(entity instanceof Transaction).toBe(true); 89 | expect(entity.getProperty('number', null)).toBe(transaction.number); 90 | expect(entity.getProperty('status', null)).toBe(transaction.status); 91 | expect(entity.getProperty('source', null)).toBe(transaction.source); 92 | }); 93 | }); 94 | 95 | it('should has pagination', async () => { 96 | const transactions = transactionFactory(40); 97 | 98 | // configure mock for list request 99 | mock.onGet(`${context.getBaseUrl()}/transaction`) 100 | .reply(() => { 101 | const response = new Response(transactions.map((v) => new Item(v))); 102 | response.setPage(3, 40, 1200); 103 | 104 | return [200, response]; 105 | }); 106 | 107 | const list = await TransactionService.list(context, { page: 3, items: 40 }); 108 | 109 | expect(list.getPageNumber()).toBe(3); 110 | expect(list.getItemsNumber()).toBe(40); 111 | expect(list.getTotalPages()).toBe(30); 112 | expect(list.getTotalItems()).toBe(1200); 113 | expect(list.hasNext()).toBe(true); 114 | }); 115 | 116 | it('check "filter parameter in list" method', async () => { 117 | const transaction = transactionFactory(); 118 | 119 | // configure mock for list request 120 | mock.onGet(`${context.getBaseUrl()}/transaction`) 121 | .reply(200, new Response(new Item(transaction))); 122 | 123 | // if filter parameter is object 124 | await TransactionService.list(context, { page: 2, items: 10 }); 125 | 126 | expect(Service.getLastHttpRequestInfo().config.params.filter).toBe('page=2;items=10'); 127 | 128 | // if filter parameter is string 129 | await TransactionService.list(context, 'page=3;items=20'); 130 | 131 | expect(Service.getLastHttpRequestInfo().config.params.filter).toBe('page=3;items=20'); 132 | }); 133 | }); 134 | 135 | it('check "update" method', async () => { 136 | let transaction = transactionFactory(); 137 | 138 | // configure mock for get request 139 | mock.onGet(`${context.getBaseUrl()}/transaction/${transaction.number}`) 140 | .reply(200, new Response(new Item(transaction))); 141 | 142 | transaction = await TransactionService.get(context, transaction.number); 143 | 144 | transaction.setProperty('status', 'CLOSED'); 145 | 146 | // configure mock for update request 147 | mock.onPost(`${context.getBaseUrl()}/transaction/${transaction.number}`) 148 | .reply(200, new Response(new Item(transaction))); 149 | 150 | const updated = await TransactionService.update(context, transaction.getProperty('number'), transaction); 151 | 152 | expect(updated instanceof Transaction).toBe(true); 153 | expect(updated.getProperty('status', null)).toBe(transaction.getProperty('status')); 154 | }); 155 | }); 156 | --------------------------------------------------------------------------------