├── .editorconfig ├── .github └── workflows │ ├── pull-request-to-master.yml │ └── semantic-publishing.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── ROADMAP.md ├── angular.json ├── apps └── todo-app-backend │ ├── .prettierrc │ ├── CHANGELOG.md │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── app │ │ ├── .gitkeep │ │ ├── app.controller.spec.ts │ │ ├── app.controller.ts │ │ ├── app.module.ts │ │ ├── defaults.ts │ │ ├── helpers.ts │ │ ├── lib │ │ │ ├── parse-query.pipe.ts │ │ │ └── partial.ts │ │ └── todo-storage.service.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ └── main.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── tslint.json ├── build-all-libs.js ├── build-and-publish.sh ├── jest.config.js ├── jest.preset.js ├── lerna.json ├── libs ├── definitions │ ├── CHANGELOG.md │ ├── README.md │ ├── aspects │ │ ├── ng-package.json │ │ └── src │ │ │ ├── index.ts │ │ │ ├── public_api.ts │ │ │ └── types │ │ │ ├── aspect-keyword.ts │ │ │ ├── has-buffer-data.ts │ │ │ ├── has-combined-variants.ts │ │ │ ├── has-const-value.ts │ │ │ ├── has-content-type.ts │ │ │ ├── has-default.ts │ │ │ ├── has-description.ts │ │ │ ├── has-enumeration.ts │ │ │ ├── has-example.ts │ │ │ ├── has-id.ts │ │ │ ├── has-items.ts │ │ │ ├── has-nullable.ts │ │ │ ├── has-numeric-value.ts │ │ │ ├── has-properties.ts │ │ │ ├── has-ref.ts │ │ │ ├── has-responses.ts │ │ │ └── has-string-value.ts │ ├── jest.config.js │ ├── json-schema │ │ ├── ng-package.json │ │ ├── package.json │ │ └── src │ │ │ ├── generic.ts │ │ │ ├── index.ts │ │ │ ├── public_api.ts │ │ │ ├── schema.spec.ts │ │ │ └── schema.ts │ ├── ng-package.json │ ├── oas3 │ │ ├── ng-package.json │ │ ├── package.json │ │ └── src │ │ │ ├── index.ts │ │ │ ├── public_api.ts │ │ │ └── types │ │ │ ├── abstract-parameter.ts │ │ │ ├── contact.ts │ │ │ ├── external-document.ts │ │ │ ├── has-content │ │ │ ├── has-content.ts │ │ │ ├── index.ts │ │ │ └── media-content.ts │ │ │ ├── header-parameter.ts │ │ │ ├── headers.ts │ │ │ ├── info.ts │ │ │ ├── license.ts │ │ │ ├── oas3-specification.ts │ │ │ ├── operation.ts │ │ │ ├── parameter-style.ts │ │ │ ├── parameter-target.ts │ │ │ ├── parameter.ts │ │ │ ├── path-item.ts │ │ │ ├── paths.ts │ │ │ ├── request.ts │ │ │ ├── response.ts │ │ │ ├── reusable-components.ts │ │ │ ├── server-variable.ts │ │ │ └── server.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── public_api.ts │ │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── ng-http-tools │ ├── CHANGELOG.md │ ├── jest.config.js │ ├── ng-package.json │ ├── package.json │ ├── rx-operators │ │ ├── ng-package.json │ │ └── src │ │ │ ├── index.ts │ │ │ ├── lib │ │ │ └── pick-responses.ts │ │ │ └── public_api.ts │ ├── src │ │ ├── index.ts │ │ ├── lib │ │ │ ├── entrypoint-abstract │ │ │ │ ├── entrypoint-abstract.ts │ │ │ │ ├── entrypoint-response.ts │ │ │ │ ├── http-method.ts │ │ │ │ ├── request-options.ts │ │ │ │ ├── server-environment.ts │ │ │ │ ├── utils │ │ │ │ │ ├── create-url.spec.ts │ │ │ │ │ ├── create-url.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── parse-request-arguments.ts │ │ │ │ │ ├── prepare-request-options.ts │ │ │ │ │ └── serialize-form-data.ts │ │ │ │ └── validation │ │ │ │ │ ├── ajv-wrapper.service.ts │ │ │ │ │ ├── entrypoint-validation.service.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── validation-error-stream.ts │ │ │ │ │ └── validation-error.ts │ │ │ └── ng-http-tools.module.ts │ │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── oapi3ts │ ├── CHANGELOG.md │ ├── README.md │ ├── contract │ │ ├── ng-package.json │ │ └── src │ │ │ ├── index.ts │ │ │ ├── lib │ │ │ ├── facade.ts │ │ │ ├── file-saving-strategy.ts │ │ │ ├── operation.ts │ │ │ └── source.ts │ │ │ └── public_api.ts │ ├── index.ts │ ├── jest.config.js │ ├── ng-package.json │ ├── package.json │ ├── src │ │ ├── facade.spec.ts │ │ ├── facade.ts │ │ ├── index.ts │ │ ├── legacy │ │ │ ├── adapters │ │ │ │ └── typescript │ │ │ │ │ ├── convertor.ts │ │ │ │ │ ├── descriptors │ │ │ │ │ ├── abstract.ts │ │ │ │ │ ├── all-of.ts │ │ │ │ │ ├── any.ts │ │ │ │ │ ├── array.ts │ │ │ │ │ ├── boolean.ts │ │ │ │ │ ├── enum.ts │ │ │ │ │ ├── generic.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── instanceof.ts │ │ │ │ │ ├── null.ts │ │ │ │ │ ├── number.ts │ │ │ │ │ ├── object.ts │ │ │ │ │ ├── some-of.ts │ │ │ │ │ └── string.ts │ │ │ │ │ └── index.ts │ │ │ └── core │ │ │ │ ├── api-meta-info.ts │ │ │ │ ├── config.ts │ │ │ │ ├── convertor.ts │ │ │ │ ├── data-type-descriptor.ts │ │ │ │ ├── index.ts │ │ │ │ └── parsing-problems.ts │ │ ├── schemas │ │ │ └── complex.json │ │ ├── stubs │ │ │ └── dummy-file-saving-strategy.ts │ │ ├── test-setup.ts │ │ └── utils │ │ │ ├── extract-common-dependencies.ts │ │ │ ├── index.ts │ │ │ └── uniq-dependencies.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ └── tslint.json ├── schematics-example │ ├── CHANGELOG.md │ ├── README.md │ ├── jest.config.js │ ├── ng-package.json │ ├── package.json │ ├── schematics │ │ ├── backend-services │ │ │ ├── files │ │ │ │ ├── __moduleName@dasherize__.module.ts.template │ │ │ │ ├── __operationId@dasherize__-backend.service.ts.template │ │ │ │ └── index.ts.template │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ ├── schema.ts │ │ │ └── utilities │ │ │ │ └── get-prepared-options.ts │ │ └── collection.json │ ├── src │ │ ├── index.ts │ │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.schematics.json │ ├── tsconfig.spec.json │ └── tslint.json ├── schematics-tools │ ├── CHANGELOG.md │ ├── jest.config.js │ ├── ng-package.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── lib │ │ │ └── schematic-host-saving.strategy.ts │ │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ └── tslint.json └── todo-app-contract │ ├── CHANGELOG.md │ ├── domain-schema │ ├── ng-package.json │ └── src │ │ └── index.ts │ ├── jest.config.js │ ├── jest.config.prod.js │ ├── ng-package.json │ ├── package.json │ ├── src │ ├── index.ts │ ├── lib │ │ ├── todo-app.spec.ts │ │ └── todo-app │ │ │ ├── common │ │ │ ├── attachment-meta-document.ts │ │ │ ├── attachment-meta-image.ts │ │ │ ├── http-error-bad-request.ts │ │ │ ├── http-error-conflict.ts │ │ │ ├── http-error-not-found.ts │ │ │ ├── http-error-server.ts │ │ │ ├── image-options.ts │ │ │ ├── json-error.ts │ │ │ ├── to-do-group-blank.ts │ │ │ ├── to-do-group-extended-data.ts │ │ │ ├── to-do-group.ts │ │ │ ├── to-do-task-blank.ts │ │ │ └── to-do-task.ts │ │ │ ├── create-group-item │ │ │ ├── create-group-item-backend.service.ts │ │ │ ├── create-group-item-parameters.ts │ │ │ ├── create-group-item-request.ts │ │ │ └── create-group-item-response.ts │ │ │ ├── create-group │ │ │ ├── create-group-backend.service.ts │ │ │ ├── create-group-request.ts │ │ │ └── create-group-response.ts │ │ │ ├── delete-group │ │ │ ├── delete-group-backend.service.ts │ │ │ ├── delete-group-parameters.ts │ │ │ └── delete-group-response.ts │ │ │ ├── get-group-items │ │ │ ├── get-group-items-backend.service.ts │ │ │ ├── get-group-items-parameters.ts │ │ │ └── get-group-items-response.ts │ │ │ ├── get-group │ │ │ ├── get-group-backend.service.ts │ │ │ ├── get-group-parameters.ts │ │ │ └── get-group-response.ts │ │ │ ├── get-groups │ │ │ ├── get-groups-backend.service.ts │ │ │ ├── get-groups-parameters.ts │ │ │ └── get-groups-response.ts │ │ │ ├── index.ts │ │ │ ├── rewrite-group-item │ │ │ ├── rewrite-group-item-backend.service.ts │ │ │ ├── rewrite-group-item-parameters.ts │ │ │ ├── rewrite-group-item-request.ts │ │ │ └── rewrite-group-item-response.ts │ │ │ ├── rewrite-group │ │ │ ├── rewrite-group-backend.service.ts │ │ │ ├── rewrite-group-parameters.ts │ │ │ ├── rewrite-group-request.ts │ │ │ └── rewrite-group-response.ts │ │ │ ├── todo-app.module.ts │ │ │ ├── update-few-items │ │ │ ├── update-few-items-backend.service.ts │ │ │ ├── update-few-items-parameters.ts │ │ │ ├── update-few-items-request.ts │ │ │ └── update-few-items-response.ts │ │ │ ├── update-group-item │ │ │ ├── update-group-item-backend.service.ts │ │ │ ├── update-group-item-parameters.ts │ │ │ ├── update-group-item-request.ts │ │ │ └── update-group-item-response.ts │ │ │ └── update-group │ │ │ ├── update-group-backend.service.ts │ │ │ ├── update-group-parameters.ts │ │ │ ├── update-group-request.ts │ │ │ └── update-group-response.ts │ ├── oas │ │ └── app-demo.json │ └── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ ├── tsconfig.spec.prod.json │ └── tslint.json ├── nx.json ├── package-lock.json ├── package.json ├── tools ├── generators │ └── .gitkeep └── tsconfig.tools.json ├── tsconfig.base.json ├── tsconfig.lib.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.{json,yml,html}] 12 | indent_size = 2 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-to-master.yml: -------------------------------------------------------------------------------- 1 | # Test libraries on push 2 | 3 | name: Test libraries on pull requests to master 4 | 5 | on: 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [16.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | with: 21 | fetch-depth: 0 22 | - name: Fetch origin branches for nx:affected 23 | run: git fetch --no-tags --prune --depth=5 origin master 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - name: Install dependencies (npm ci) 29 | run: npm ci 30 | - name: Lint 31 | run: npx nx affected:lint --base=origin/master --head=HEAD 32 | - name: Test libraries in monorepo mode (without prebuilt libs) 33 | run: npx nx affected:test --base=origin/master --head=HEAD 34 | - name: Clear already built libs 35 | run: npm run clear:prebuilt-libs 36 | - name: Build libraries and update example generated lib (todo-app-contract) 37 | run: npm run todo-app-contract:update 38 | - name: Build updated example generated lib (todo-app-contract) 39 | run: npx ng build todo-app-contract 40 | - name: Test prebuilt libraries 41 | run: npx nx affected:test --base=origin/master --head=HEAD --configuration=ci 42 | -------------------------------------------------------------------------------- /.github/workflows/semantic-publishing.yml: -------------------------------------------------------------------------------- 1 | name: Semantic version increment, libraries building and publishing to NPM 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | matrix: 14 | node-version: [16.x] 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | with: 19 | fetch-depth: 0 20 | - name: Fetch origin tags for Lerna (see https://bit.ly/2KNS172) 21 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* 22 | - name: Auth with repo for push 23 | run: git remote add -f pub https://${GITHUB_TOKEN}@github.com/koshevy/codegena.git 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | - name: Use Node.js ${{ matrix.node-version }} 27 | uses: actions/setup-node@v1 28 | with: 29 | node-version: ${{ matrix.node-version }} 30 | registry-url: https://registry.npmjs.org/ 31 | - name: Install dependencies with 32 | run: npm ci 33 | - name: Clear already built libs 34 | run: npm run clear:prebuilt-libs 35 | - name: Build libraries and update example generated lib (todo-app-contract) 36 | run: npm run todo-app-contract:update 37 | - name: Build updated example generated lib (todo-app-contract) 38 | run: npx ng build todo-app-contract 39 | - name: Set git credentials 40 | run: git config --global user.email "koshevy@gmail.com" && git config --global user.name "Alexander Koshevy" 41 | - name: Run publishing script (powered by LernaVersion and AngularCLI) 42 | run: ./build-and-publish.sh 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | dist 6 | #complied prepare scripts 7 | prepare-dist/*/* 8 | 9 | /tmp 10 | /out-tsc 11 | # Only exists if Bazel was run 12 | /bazel-out 13 | 14 | # dependencies 15 | node_modules 16 | 17 | # profiling files 18 | chrome-profiler-events.json 19 | speed-measure-plugin.json 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json 36 | .history/* 37 | 38 | # misc 39 | /.sass-cache 40 | /connect.lock 41 | /coverage 42 | /libpeerconnection.log 43 | testem.log 44 | /typings 45 | .npmrc 46 | 47 | # System Files 48 | .DS_Store 49 | Thumbs.db 50 | 51 | # Logs 52 | logs 53 | *.log 54 | npm-debug.log* 55 | yarn-debug.log* 56 | yarn-error.log* 57 | lerna-debug.log* 58 | 59 | # OS 60 | .DS_Store 61 | 62 | # Tests 63 | /coverage 64 | /.nyc_output 65 | 66 | # Autogenerated services 67 | todo-app-scheme/src/lib/**/*.ts 68 | scripts/update-typings.js 69 | auto-generated/**/*.ts 70 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "singleQuote": true, 4 | "semi": true 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "nrwl.angular-console", 4 | "angular.ng-template", 5 | "ms-vscode.vscode-typescript-tslint-plugin", 6 | "esbenp.prettier-vscode", 7 | "firsttris.vscode-jest-runner" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 Alexander Koshevoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # CODEGENA 3.x: Actual Roadmap 2 | 3 | ## Motivation 4 | 5 | This project was originally started as an experiment and 6 | was an experiment (or MVP) over the past two years. 7 | All this time conditions have been coming clearer. 8 | And it has been figuring out what it takes to do this. 9 | 10 | As it turns out, it is quite possible to create robust code generation tool by one person. 11 | Understanding of niche and needs should help me to save efforts and continue with 12 | a clear-cut goals and vision. I think it's a good time to prepare the next stage: 13 | with well figured ideology and contribution guide. 14 | 15 | So, experience to use concepts from this project in real commercial applications had shown: 16 | 17 | - **No need for CLI application**. Every project has its own CI infrastructure with individual requirements and these requirements can't be generalized avoiding huge efforts. 18 | - **No need for readymade code (such as services or functions)**. The same reason: requirements are so much different and not-generalizable that design, development, delivery and support come to be too expensive. It's preferable to provide simple helpers (validation, simple result picking etc.) and promote practice of in-project code generation (see the next thesis). 19 | - **It had better to embed into ecosystems**. Everyone relies on their ecosystem. For instance, there is in Angular ecosystem [Schematics](https://angular.io/guide/schematics) solution has scope and common practices. It's likely, developers accustomed to Angular will try to use Schematics when there is arose to deal with code-generation or any kind of automation. 20 | - **Solution should be simple to integrate and modify (AST)**. Continuing the theme of common ecosystems and solutions (like the Angular Schematics). Once you try to embed auto-generated code into your infrastructure, you facing to need to deal with AST. So you can integrate and modify result of code generating. 21 | - **No point to think about any other languages**. There is no way to support different language because every language requires to deal with it's own ecosystem. A bird in the hand is worth two in the bush, and that bird is the TypeScript. 22 | 23 | ## Goals 24 | 25 | To provide API for OAS3-converting that should be friendly to best practices of code generation in modern applications. The undoubted leader (and pioneer!) in this way is the [Angular Schematics](https://angular.io/guide/schematics). It means convenience to work with Angular Schematics is in priority. 26 | 27 | ## API 28 | 29 | API should facilitate to: 30 | 31 | 1. **Useful work with AST (creating/modification)**. API should generate all necessary entities in AST and allow to traverse through and modify result. 32 | 1. **Useful work with OAS3 metadata**. Generating of new code based on metadata should be simply. As well as the traverse between metadata and already generated related entities. 33 | 34 | ## Roadmap 35 | 36 | 1. Stop supporting all libraries but `oapi3ts` (`axios-wrapper`, `ng-api-service` and `oapi3ts-cli` getting trashed) 37 | 1. Design new API contract 38 | 1. Refactor `oapi3ts` in order to support contract changing (renew tests and simplify structure) 39 | 1. Add bridge between old implementation and new contract 40 | 1. **Make contributing guide** 41 | 1. Continue improving 42 | 43 | ## Time frame 44 | 45 | Time frame is getting clear now. 46 | -------------------------------------------------------------------------------- /apps/todo-app-backend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "none", 4 | "tabWidth": 4 5 | } 6 | -------------------------------------------------------------------------------- /apps/todo-app-backend/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## 0.1.8-alpha.1 (2020-05-01) 7 | 8 | **Note:** Version bump only for package @codegena/todo-app-backend 9 | 10 | 11 | 12 | 13 | 14 | ## 0.1.8-alpha.0 (2020-04-30) 15 | 16 | **Note:** Version bump only for package @codegena/todo-app-backend 17 | 18 | 19 | 20 | 21 | 22 | ## 0.1.7 (2020-04-25) 23 | 24 | **Note:** Version bump only for package @codegena/todo-app-backend 25 | 26 | 27 | 28 | 29 | 30 | ## 0.1.6 (2020-04-25) 31 | 32 | **Note:** Version bump only for package @codegena/todo-app-backend 33 | 34 | 35 | 36 | 37 | 38 | ## 0.1.5 (2020-04-13) 39 | 40 | **Note:** Version bump only for package @codegena/todo-app-backend 41 | 42 | 43 | 44 | 45 | 46 | ## [0.1.4](https://github.com/koshevy/codegena/compare/@codegena/todo-app-backend@0.1.3...@codegena/todo-app-backend@0.1.4) (2020-03-29) 47 | 48 | **Note:** Version bump only for package @codegena/todo-app-backend 49 | 50 | 51 | 52 | 53 | 54 | ## [0.1.3](https://github.com/koshevy/codegena/compare/@codegena/todo-app-backend@0.1.2...@codegena/todo-app-backend@0.1.3) (2020-03-05) 55 | 56 | **Note:** Version bump only for package @codegena/todo-app-backend 57 | 58 | 59 | 60 | 61 | 62 | ## [0.1.2](https://github.com/koshevy/codegena/compare/@codegena/todo-app-backend@0.1.1...@codegena/todo-app-backend@0.1.2) (2020-01-26) 63 | 64 | **Note:** Version bump only for package @codegena/todo-app-backend 65 | 66 | 67 | 68 | 69 | 70 | ## [0.1.1](https://github.com/koshevy/codegena/compare/@codegena/todo-app-backend@0.1.0...@codegena/todo-app-backend@0.1.1) (2020-01-26) 71 | 72 | **Note:** Version bump only for package @codegena/todo-app-backend 73 | 74 | 75 | 76 | 77 | 78 | # 0.1.0 (2020-01-26) 79 | 80 | 81 | ### Features 82 | 83 | * **todo-app-backend:** support predefined `position` of just created task ([a9a4d64](https://github.com/koshevy/codegena/commit/a9a4d6497abc46a45621d7984e01c4e45ec565a9)) 84 | -------------------------------------------------------------------------------- /apps/todo-app-backend/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | name: 'todo-app-backend', 3 | preset: '../../jest.config.js', 4 | coverageDirectory: '../../coverage/apps/todo-app-backend' 5 | }; 6 | -------------------------------------------------------------------------------- /apps/todo-app-backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/todo-app-backend", 3 | "version": "0.1.8-alpha.1", 4 | "description": "", 5 | "author": "", 6 | "license": "MIT", 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "nest build", 10 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 11 | "start": "nest start", 12 | "start:dev": "nest start --watch", 13 | "start:debug": "nest start --debug --watch", 14 | "start:prod": "node dist/main", 15 | "lint": "tslint -p tsconfig.json -c tslint.json", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --config ./test/jest-e2e.json" 21 | }, 22 | "dependencies": { 23 | "express-session": "^1.17.0", 24 | "nanoid": "^3.1.16" 25 | }, 26 | "peerDependencies": { 27 | "@nestjs/common": ">= 7", 28 | "@nestjs/core": ">= 7", 29 | "@nestjs/platform-express": ">= 7.0.0", 30 | "lodash": "*", 31 | "reflect-metadata": ">= 0", 32 | "rimraf": ">= 3.0.0", 33 | "rxjs": ">= 6.0.0", 34 | "typescript": ">= 3.6" 35 | }, 36 | "jest": { 37 | "moduleFileExtensions": [ 38 | "js", 39 | "json", 40 | "ts" 41 | ], 42 | "rootDir": "src", 43 | "testRegex": ".spec.ts$", 44 | "transform": { 45 | "^.+\\.(t|j)s$": "ts-jest" 46 | }, 47 | "coverageDirectory": "./coverage", 48 | "testEnvironment": "node" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koshevy/codegena/2e7933721ff64c48deb97fbf985ac7aba87ac26f/apps/todo-app-backend/src/app/.gitkeep -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { TodoStorageService } from './todo-storage.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [TodoStorageService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | // todo add service tests 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { TodoStorageService } from './todo-storage.service'; 4 | 5 | @Module({ 6 | imports: [], 7 | controllers: [AppController], 8 | providers: [TodoStorageService], 9 | }) 10 | export class AppModule {} 11 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/helpers.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import nanoid from 'nanoid'; 3 | import { 4 | ToDoGroup, 5 | ToDoGroupBlank, 6 | ToDoTask, 7 | ToDoTaskBlank, 8 | } from '@codegena/todo-app-contract'; 9 | import { BadRequestException } from "@nestjs/common"; 10 | 11 | const generateUid = nanoid; 12 | export function getNowISO(): string { 13 | const date = new Date(); 14 | return date.toISOString(); 15 | } 16 | 17 | /** 18 | * Function gives blank of group and returns complete record 19 | * with `dateChanged`, `dateCreated` and `uid`. 20 | * 21 | * @param groupBlank 22 | * @return 23 | */ 24 | export function createGroupFromBlank(groupBlank: ToDoGroupBlank): ToDoGroup { 25 | const nowISO = getNowISO(); 26 | const groupUid = generateUid(); 27 | const items = _.map( 28 | (groupBlank.items || []), 29 | (blankTask: ToDoTaskBlank, index) => { 30 | return createTaskFromBlank( 31 | blankTask, 32 | index, 33 | groupUid, 34 | ); 35 | }, 36 | ); 37 | 38 | return updateIsCompleteStatus({ 39 | ...groupBlank, 40 | dateChanged: nowISO, 41 | dateCreated: nowISO, 42 | items, 43 | uid: groupUid, 44 | }); 45 | } 46 | 47 | /** 48 | * Function gives blank of task and returns complete record 49 | * with `dateChanged`, `dateCreated` and `uid`. 50 | * 51 | * @param blank 52 | * @param position 53 | * @param groupUid 54 | * @return 55 | */ 56 | export function createTaskFromBlank( 57 | blank: ToDoTaskBlank, 58 | position: number | null = null, 59 | groupUid?: string, 60 | ): ToDoTask { 61 | const nowISO = getNowISO(); 62 | const newTask: ToDoTask = { 63 | ...blank, 64 | dateChanged: nowISO, 65 | dateCreated: nowISO, 66 | uid: generateUid(), 67 | position: position ? position : 0 , 68 | }; 69 | 70 | if (Number.isInteger(position) && (position >= 0)) { 71 | newTask.position = position; 72 | } 73 | 74 | if (groupUid) { 75 | newTask.groupUid = groupUid; 76 | } 77 | 78 | return newTask; 79 | } 80 | 81 | export function assertUniqueTitle( 82 | items: Array, 83 | title: string, 84 | excludeUid?: string, 85 | ): void { 86 | const alreadyExists = _.find( 87 | items, 88 | (item: ToDoGroup | ToDoTask) => 89 | item.title === title 90 | && (!excludeUid || (item.uid !== excludeUid)), 91 | ); 92 | 93 | if (alreadyExists) { 94 | throw new BadRequestException([ 95 | 'Title of group/task should be unique!', 96 | `There are alreay exists error with id=${alreadyExists.uid}`, 97 | ].join('\n')); 98 | } 99 | } 100 | 101 | /** 102 | * Recalculate `isComplete` property of {@link ToDoGroup}-object. 103 | * Mutates object. 104 | * 105 | * @param group 106 | */ 107 | export function updateIsCompleteStatus(group: ToDoGroup): ToDoGroup { 108 | group.isComplete = _.reduce( 109 | group.items, 110 | (result, task: ToDoTask) => 111 | !task.isDone 112 | ? false 113 | : (result === null) ? true : result, 114 | null 115 | ); 116 | 117 | return group; 118 | } 119 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/lib/parse-query.pipe.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import { ArgumentMetadata, PipeTransform } from '@nestjs/common'; 3 | 4 | /** 5 | * Parses numbers and booleans in query. 6 | */ 7 | export class ParseQueryPipe 8 | implements PipeTransform { 9 | /** 10 | * Method that accesses and performs optional transformation on argument for 11 | * in-flight requests. 12 | * 13 | * @param value currently processed route argument 14 | * @param metadata contains metadata about the currently processed route argument 15 | */ 16 | async transform(value: object, metadata: ArgumentMetadata): Promise { 17 | return parseValuesOfObject(value); 18 | } 19 | } 20 | 21 | function parseValuesOfObject(data: object): T { 22 | return _.mapValues(data, value => { 23 | if (!value) { 24 | return null; 25 | } 26 | 27 | if ('object' === typeof value) { 28 | return parseValuesOfObject(value); 29 | } 30 | 31 | if (_.includes(['true', 'false'], value)) { 32 | return { 33 | true: true, 34 | false: false 35 | }[value]; 36 | } 37 | 38 | const numValue = Number(value); 39 | 40 | if (!Number.isNaN(numValue)) { 41 | return numValue; 42 | } 43 | 44 | return value; 45 | }) as T; 46 | } 47 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/app/lib/partial.ts: -------------------------------------------------------------------------------- 1 | export type Partial = { 2 | [P in keyof T]?: T[P]; 3 | }; 4 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koshevy/codegena/2e7933721ff64c48deb97fbf985ac7aba87ac26f/apps/todo-app-backend/src/assets/.gitkeep -------------------------------------------------------------------------------- /apps/todo-app-backend/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: false 3 | }; 4 | -------------------------------------------------------------------------------- /apps/todo-app-backend/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as session from 'express-session'; 2 | import { NestFactory } from '@nestjs/core'; 3 | import { AppModule } from './app/app.module'; 4 | 5 | async function bootstrap() { 6 | const app = await NestFactory.create(AppModule); 7 | app.use(session({ 8 | resave: true, 9 | saveUninitialized: true, 10 | secret: 'S2D0MK1DV', 11 | cookie: { 12 | credentials: true, 13 | secure: false, 14 | maxAge: 600000, 15 | }, 16 | })); 17 | app.enableCors({ 18 | credentials: true, 19 | maxAge: 600000, 20 | methods: ['DELETE', 'GET', 'PATCH', 'POST', 'PUT', 'OPTIONS'].join(','), 21 | origin: '*', 22 | preflightContinue: false, 23 | optionsSuccessStatus: 200 24 | }); 25 | await app.listen(3000); 26 | } 27 | bootstrap(); 28 | -------------------------------------------------------------------------------- /apps/todo-app-backend/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node"], 6 | "emitDecoratorMetadata": true, 7 | "target": "es2015" 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /apps/todo-app-backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "strictNullChecks": false 5 | }, 6 | "files": [], 7 | "include": [], 8 | "references": [ 9 | { 10 | "path": "./tsconfig.app.json" 11 | }, 12 | { 13 | "path": "./tsconfig.spec.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /apps/todo-app-backend/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.d.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /apps/todo-app-backend/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "no-implicit-dependencies": false 5 | }, 6 | "linterOptions": { 7 | "exclude": ["!**/*", "!**/*"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /build-all-libs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const { execSync } = require('child_process'); 3 | const { projects } = require('./angular.json'); 4 | const { findKey } = require('lodash'); 5 | const paths = execSync('./node_modules/.bin/lerna list --toposort --parseable') 6 | .toString('utf-8') 7 | .split('\n') 8 | .map(packageName => packageName.trim()) 9 | .filter(packageName => !!packageName) 10 | .map(path => path.replace(__dirname, '')); 11 | 12 | try { 13 | paths.forEach(path => { 14 | const project = findKey(projects, project => { 15 | return path.indexOf(project.root) !== -1; 16 | }); 17 | 18 | const output = execSync( 19 | `./node_modules/.bin/ng build ${project}`, 20 | { maxBuffer: 1000 * 1000 * 5 }, 21 | ); 22 | 23 | console.log(output.toString('utf-8')); 24 | }); 25 | } catch (error) { 26 | throw new Eror('Build failed!'); 27 | } 28 | -------------------------------------------------------------------------------- /build-and-publish.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | branch="$(git symbolic-ref --short -q HEAD)" 4 | releaseMode='' 5 | 6 | if [ "$branch" == "master" ] 7 | then 8 | echo "Starting prerelease publishing..." 9 | releaseMode="--conventional-prerelease" 10 | else 11 | if ["$branch" == "release"] 12 | then 13 | releaseMode="--conventional-graduate --no-push" 14 | echo "Starting release publishing..." 15 | else 16 | echo -e "\033[0;31m"; 17 | echo "╔════════════════════════════════════════════════╗" 18 | echo "║ Publication MUST be run only in master branch ║" 19 | echo "║ or in release branch! ║" 20 | echo "║ ║" 21 | echo "║ Please, make Pull Request in master branch and ║" 22 | echo "║ continue publishing after PR merging. ║" 23 | echo "╚════════════════════════════════════════════════╝" 24 | echo -e "\033[0m"; 25 | exit 1; 26 | fi 27 | fi 28 | 29 | rm -rf dist/* && 30 | # version update error ignoring because 31 | # there may be unpublished packages with updated version 32 | (sh -c "./node_modules/.bin/lerna version --conventional-commits --include-merged-tags --exact --yes $releaseMode" || true) && 33 | npm run build:all-libs && 34 | # build schematics (temporary solution) 35 | npm run schematics-example:build-schematics:dev 36 | 37 | # publish all built libs. errors are ignored 38 | for D in `ls ./dist` 39 | do 40 | (cd ./dist/${D} && npm publish --access public && cd ../../) || true 41 | done 42 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | projects: [ 3 | '/libs/oapi3ts', 4 | '/libs/definitions', 5 | '/libs/schematics-example', 6 | '/libs/ng-http-tools', 7 | '/libs/todo-app-contract', 8 | ], 9 | }; 10 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nrwl/jest/preset'); 2 | module.exports = { 3 | ...nxPreset, 4 | testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], 5 | transform: { 6 | '^.+\\.(ts|js|html)$': 'ts-jest', 7 | }, 8 | resolver: '@nrwl/jest/plugins/resolver', 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageReporters: ['html'], 11 | passWithNoTests: true, 12 | }; 13 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "3.20.2", 3 | "version": "independent", 4 | "command": { 5 | "publish": { 6 | "ignoreChanges": [ 7 | "tslint.json", 8 | "jest.config.js", 9 | "*.spec.ts", 10 | "*.sh", 11 | "lerna.json", 12 | ".github/workflows/*" 13 | ], 14 | "conventionalCommits": true 15 | }, 16 | "version": { 17 | "allowBranch": ["master", "release"], 18 | "message": "chore(release): publish changed libraries" 19 | } 20 | }, 21 | "npmClient": "npm", 22 | "packages": [ 23 | "libs/*" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/definitions/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 0.1.0-alpha.3 (2021-06-20) 7 | 8 | 9 | ### Features 10 | 11 | * **definitions:** support `nullable` in JsonSchema definitions ([7afc5b9](https://github.com/koshevy/codegena/commit/7afc5b9b916f659a6857f1b4aeb42e4c77208d02)) 12 | 13 | 14 | 15 | 16 | 17 | # 0.1.0-alpha.2 (2021-06-13) 18 | 19 | **Note:** Version bump only for package @codegena/definitions 20 | 21 | 22 | 23 | 24 | 25 | # [0.1.0-alpha.1](https://github.com/koshevy/codegena/compare/@codegena/definitions@0.1.0-alpha.0...@codegena/definitions@0.1.0-alpha.1) (2021-06-09) 26 | 27 | 28 | ### Features 29 | 30 | * remove unused npm dependencies ([01b8090](https://github.com/koshevy/codegena/commit/01b8090273656e65d8dcb7d861356aa16279b3bc)) 31 | 32 | 33 | 34 | 35 | 36 | # 0.1.0-alpha.0 (2021-06-09) 37 | 38 | 39 | ### Features 40 | 41 | * **definitions:** add HasResponses, HasContentType and HasId aspects ([c35aab1](https://github.com/koshevy/codegena/commit/c35aab156b5d957ecff12ce1b28397504bae2a52)) 42 | * **definitions:** complete json-schema definitions ([4e14540](https://github.com/koshevy/codegena/commit/4e145406eef981aea567d83da37f8551164d1983)) 43 | * **definitions:** complete most used aspect definitions ([e46a590](https://github.com/koshevy/codegena/commit/e46a5902c9a3156fd3eaa39067146b39b28d1564)) 44 | * **definitions:** complete oas3 definitions ([575c802](https://github.com/koshevy/codegena/commit/575c8024faeaef158369ca88caf0ee02cb6f9158)) 45 | * **definitions:** support OAS3 Server variables ([d7a0f52](https://github.com/koshevy/codegena/commit/d7a0f5202bad34654ddfdda30b769424a7ffc8db)) 46 | * **definitions:** support Oas3Specification for versions 3.0.3 and 3.0.2 ([4144bab](https://github.com/koshevy/codegena/commit/4144babde9f72f1925d15b2ddd15868292a638b1)) 47 | -------------------------------------------------------------------------------- /libs/definitions/README.md: -------------------------------------------------------------------------------- 1 | # definitions 2 | 3 | TBD 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/public_api.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './types/has-buffer-data'; 2 | export * from './types/has-const-value'; 3 | export * from './types/has-combined-variants'; 4 | export * from './types/has-content-type'; 5 | export * from './types/has-default'; 6 | export * from './types/has-description'; 7 | export * from './types/has-enumeration'; 8 | export * from './types/has-example'; 9 | export * from './types/has-id'; 10 | export * from './types/has-items'; 11 | export * from './types/has-nullable'; 12 | export * from './types/has-numeric-value'; 13 | export * from './types/has-properties'; 14 | export * from './types/has-ref'; 15 | export * from './types/has-responses'; 16 | export * from './types/has-string-value'; 17 | export * from './types/aspect-keyword'; 18 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/aspect-keyword.ts: -------------------------------------------------------------------------------- 1 | export type AspectKeyword = 2 | | '$ref' 3 | | '$id' 4 | | 'additionalItems' 5 | | 'additionalProperties' 6 | | 'allOf' 7 | | 'anyOf' 8 | | 'const' 9 | | 'contains' 10 | | 'contentEncoding' 11 | | 'contentMediaType' 12 | | 'default' 13 | | 'dependencies' 14 | | 'description' 15 | | 'enum' 16 | | 'example' 17 | | 'examples' 18 | | 'exclusiveMaximum' 19 | | 'exclusiveMinimum' 20 | | 'format' 21 | | 'items' 22 | | 'maximum' 23 | | 'maxItems' 24 | | 'maxLength' 25 | | 'maxProperties' 26 | | 'minimum' 27 | | 'minItems' 28 | | 'minLength' 29 | | 'minProperties' 30 | | 'multipleOf' 31 | | 'nullable' 32 | | 'oneOf' 33 | | 'pattern' 34 | | 'properties' 35 | | 'propertyNames' 36 | | 'required' 37 | | 'title' 38 | | 'uniqueItems' 39 | ; 40 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-buffer-data.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Media: string-encoding non-JSON data 3 | * 4 | * New in draft 7 5 | * @see http://json-schema.org/understanding-json-schema/reference/non_json_data.html 6 | */ 7 | export interface HasBufferData{ 8 | contentEncoding: string; 9 | contentMediaType: string; 10 | } 11 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-combined-variants.ts: -------------------------------------------------------------------------------- 1 | export interface HasCombinedVariants { 2 | allOf: Partial[]; 3 | anyOf: Partial[]; 4 | oneOf: Partial[]; 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-const-value.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Constant values 3 | * 4 | * New in draft 6 5 | * @see http://json-schema.org/understanding-json-schema/reference/generic.html 6 | */ 7 | export interface HasConstValue { 8 | const: TValue; 9 | } 10 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-content-type.ts: -------------------------------------------------------------------------------- 1 | export interface HasContentType { 2 | 'default'?: TContent; 3 | 'application/javascript'?: TContent; 4 | 'application/json'?: TContent; 5 | 'application/octet-stream'?: TContent; 6 | 'application/xml'?: TContent; 7 | 'application/x-www-form-urlencoded'?: TContent; 8 | 'text/html'?: TContent; 9 | 'text/plain'?: TContent; 10 | 'text/xml'?: TContent; 11 | 'image/gif'?: TContent; 12 | 'image/jpeg'?: TContent; 13 | 'image/pjpeg'?: TContent; 14 | 'image/png'?: TContent; 15 | 'image/svg+xml'?: TContent; 16 | 'multipart/form-data'?: TContent; 17 | 'multipart/mixed'?: TContent; 18 | 'multipart/related'?: TContent; 19 | [key: string]: TContent; 20 | } 21 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-default.ts: -------------------------------------------------------------------------------- 1 | export interface HasDefault { 2 | default: TValue; 3 | } 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-description.ts: -------------------------------------------------------------------------------- 1 | export interface HasDescription { 2 | title: string; 3 | description: string; 4 | } 5 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-enumeration.ts: -------------------------------------------------------------------------------- 1 | export interface HasEnumeration { 2 | enum: TValue[]; 3 | } 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-example.ts: -------------------------------------------------------------------------------- 1 | export interface HasExample { 2 | example: T; 3 | examples: T[]; 4 | } 5 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-id.ts: -------------------------------------------------------------------------------- 1 | export interface HasId { 2 | $id: string; 3 | } 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-items.ts: -------------------------------------------------------------------------------- 1 | export interface HasItems { 2 | additionalItems: boolean; 3 | maxItems: number; 4 | minItems: number; 5 | uniqueItems: boolean; 6 | } 7 | 8 | // contains — new in draft 6, see https://bit.ly/3baVqJE 9 | export type ContainsItems = 10 | | { items: TItemSchema | TItemSchema[]; contains: never } 11 | | { contains: TItemSchema; items: never; } 12 | ; 13 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-nullable.ts: -------------------------------------------------------------------------------- 1 | export interface HasNullable { 2 | nullable: boolean; 3 | } 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-numeric-value.ts: -------------------------------------------------------------------------------- 1 | export type HasNumericValue = & HasMaximum 2 | & HasMinimum 3 | & HasMultiplyOf; 4 | 5 | export type HasMaximum = { 6 | maximum: number; 7 | exclusiveMaximum: never; 8 | } | { 9 | maximum: never; 10 | exclusiveMaximum: number; 11 | } 12 | export type HasMinimum = { 13 | minimum: number; 14 | exclusiveMinimum: never; 15 | } | { 16 | minimum: never; 17 | exclusiveMinimum: number; 18 | } 19 | 20 | export interface HasMultiplyOf { 21 | multipleOf: number; 22 | } 23 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-properties.ts: -------------------------------------------------------------------------------- 1 | export interface HasProperties { 2 | additionalProperties: boolean | TProperty; 3 | dependencies: Partial>; 4 | minProperties: number; 5 | maxProperties: number; 6 | properties: Record, 7 | propertyNames: { 8 | pattern: string; 9 | }; 10 | required: TPropertyNames[]; 11 | } 12 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-ref.ts: -------------------------------------------------------------------------------- 1 | export interface HasRef { 2 | $ref: string; 3 | } 4 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-responses.ts: -------------------------------------------------------------------------------- 1 | export interface HasResponses { 2 | /** 3 | * Default case, when needed status is not described. 4 | * Usually describe error answers. 5 | */ 6 | default?: TResponse; 7 | 8 | // Possible codes 9 | 100?: TResponse; 10 | 101?: TResponse; 11 | 102?: TResponse; 12 | 200?: TResponse; 13 | 201?: TResponse; 14 | 202?: TResponse; 15 | 203?: TResponse; 16 | 204?: TResponse; 17 | 205?: TResponse; 18 | 206?: TResponse; 19 | 207?: TResponse; 20 | 208?: TResponse; 21 | 226?: TResponse; 22 | 300?: TResponse; 23 | 301?: TResponse; 24 | 302?: TResponse; 25 | 303?: TResponse; 26 | 304?: TResponse; 27 | 305?: TResponse; 28 | 306?: TResponse; 29 | 307?: TResponse; 30 | 308?: TResponse; 31 | 400?: TResponse; 32 | 401?: TResponse; 33 | 402?: TResponse; 34 | 403?: TResponse; 35 | 404?: TResponse; 36 | 405?: TResponse; 37 | 406?: TResponse; 38 | 407?: TResponse; 39 | 408?: TResponse; 40 | 409?: TResponse; 41 | 410?: TResponse; 42 | 411?: TResponse; 43 | 412?: TResponse; 44 | 413?: TResponse; 45 | 414?: TResponse; 46 | 415?: TResponse; 47 | 416?: TResponse; 48 | 417?: TResponse; 49 | 418?: TResponse; 50 | 419?: TResponse; 51 | 421?: TResponse; 52 | 422?: TResponse; 53 | 423?: TResponse; 54 | 424?: TResponse; 55 | 426?: TResponse; 56 | 428?: TResponse; 57 | 429?: TResponse; 58 | 431?: TResponse; 59 | 449?: TResponse; 60 | 451?: TResponse; 61 | 481?: TResponse; 62 | 489?: TResponse; 63 | 499?: TResponse; 64 | 500?: TResponse; 65 | 501?: TResponse; 66 | 502?: TResponse; 67 | 503?: TResponse; 68 | 504?: TResponse; 69 | 505?: TResponse; 70 | 506?: TResponse; 71 | 507?: TResponse; 72 | 508?: TResponse; 73 | 509?: TResponse; 74 | 510?: TResponse; 75 | 511?: TResponse; 76 | 520?: TResponse; 77 | 521?: TResponse; 78 | 522?: TResponse; 79 | 523?: TResponse; 80 | 524?: TResponse; 81 | 525?: TResponse; 82 | 526?: TResponse; 83 | } 84 | -------------------------------------------------------------------------------- /libs/definitions/aspects/src/types/has-string-value.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see http://json-schema.org/understanding-json-schema/reference/string.html#built-in-formats 3 | */ 4 | export type BuiltInFormat = 5 | | 'date' 6 | | 'date-time' 7 | | 'email' 8 | | 'hostname' 9 | | 'idn-email' 10 | | 'iri' 11 | | 'iri-reference' 12 | | 'ipv4' 13 | | 'ipv6' 14 | | 'time' 15 | | 'uri' 16 | | 'uri-reference' 17 | ; 18 | 19 | export interface HasStringValue { 20 | format: TFormat; 21 | minLength: number; 22 | maxLength: number; 23 | pattern: string; 24 | } 25 | -------------------------------------------------------------------------------- /libs/definitions/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | setupFilesAfterEnv: ['/src/test-setup.ts'], 4 | globals: { 5 | 'ts-jest': { 6 | stringifyContentPathRegex: '\\.(html|svg)$', 7 | astTransformers: { 8 | before: [ 9 | 'jest-preset-angular/build/InlineFilesTransformer', 10 | 'jest-preset-angular/build/StripStylesTransformer', 11 | ], 12 | }, 13 | tsconfig: '/tsconfig.spec.json', 14 | }, 15 | }, 16 | coverageDirectory: '../../coverage/definitions', 17 | 18 | displayName: 'definitions', 19 | snapshotSerializers: [ 20 | 'jest-preset-angular/build/serializers/no-ng-attributes', 21 | 'jest-preset-angular/build/serializers/ng-snapshot', 22 | 'jest-preset-angular/build/serializers/html-comment', 23 | ], 24 | }; 25 | -------------------------------------------------------------------------------- /libs/definitions/json-schema/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/public_api.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/json-schema/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "peerDependencies": { 3 | "@codegena/definitions": "*" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/json-schema/src/generic.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from './schema'; 2 | 3 | /** 4 | * Generic of schema. 5 | * The `Generic` has also been used in {@link DataTypeDescriptor} 6 | * in same way as a {@link Schema}. 7 | * 8 | * Assumed, {@link DataTypeDescriptor} with `Generic` should be rendered as a: 9 | * ``` 10 | * type SimplestGet01Response = 11 | * Code extends 200 ? 12 | * (ContentType extends 'application/json' ? SuccessResponse : any) 13 | * : Code extends 500 ? 14 | * (ContentType extends 'application/json' ? SuccessResponse : any) 15 | * : null; 16 | * ``` 17 | */ 18 | export class Generic { 19 | constructor(public children: { 20 | [key: string]: Schema | Generic 21 | }) {} 22 | } 23 | -------------------------------------------------------------------------------- /libs/definitions/json-schema/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/definitions/json-schema/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './generic'; 2 | export * from './schema'; 3 | -------------------------------------------------------------------------------- /libs/definitions/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/definitions", 4 | "lib": { 5 | "entryFile": "src/public_api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "@codegena/definitions" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /libs/definitions/oas3/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/public_api.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/oas3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "peerDependencies": { 3 | "@codegena/definitions": "*" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './types/oas3-specification'; 2 | 3 | export { MediaContent as Oas3MediaContent } from './types/has-content/media-content'; 4 | 5 | export { Contact as Oas3Contact } from './types/contact'; 6 | export { ExternalDocument as Oas3ExternalDocument } from './types/external-document'; 7 | export { HeaderParameter as Oas3HeaderParameter } from './types/header-parameter'; 8 | export { Headers as Oas3Headers } from './types/headers'; 9 | export { Info as Oas3Info } from './types/info'; 10 | export { License as Oas3License } from './types/license'; 11 | export { Operation as Oas3Operation } from './types/operation'; 12 | export { Parameter as Oas3Parameter } from './types/parameter'; 13 | export { ParameterStyle as Oas3ParameterStyle } from './types/parameter-style'; 14 | export { ParameterTarget as Oas3ParameterTarget } from './types/parameter-target'; 15 | export { PathItem as Oas3PathItem } from './types/path-item'; 16 | export { Paths as Oas3Paths } from './types/paths'; 17 | export { Request as Oas3Request } from './types/request'; 18 | export { Response as Oas3Response } from './types/response'; 19 | export { ReusableComponents as Oas3ReusableComponents } from './types/reusable-components'; 20 | export { Server as Oas3Server } from './types/server'; 21 | export { ServerVariable as Oas3ServerVariable } from './types/server-variable'; 22 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/contact.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://swagger.io/specification/#contactObject 3 | */ 4 | export interface Contact { 5 | email: string; 6 | name: string; 7 | url: string; 8 | } 9 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/external-document.ts: -------------------------------------------------------------------------------- 1 | import { HasRef } from '@codegena/definitions/aspects'; 2 | 3 | /** 4 | * Allows referencing an external resource for extended documentation. 5 | */ 6 | export interface ExternalDocument extends HasRef { 7 | /** 8 | * A short description of the target documentation. 9 | * CommonMark syntax MAY be used for rich text representation. 10 | */ 11 | description?: string; 12 | 13 | /** 14 | * REQUIRED. The URL for the target documentation. 15 | * Value MUST be in the format of a URL. 16 | */ 17 | url: string; 18 | } 19 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/has-content/has-content.ts: -------------------------------------------------------------------------------- 1 | import { HasContentType } from '@codegena/definitions/aspects'; 2 | import { MediaContent } from './media-content'; 3 | 4 | export interface HasContent { 5 | 6 | /** 7 | * REQUIRED. The content of the request body. The key is a media type or 8 | * {@link https://tools.ietf.org/html/rfc7231#appendix-D | media type range} 9 | * and the value describes it. For requests that match multiple keys, 10 | * only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` 11 | */ 12 | content: HasContentType; 13 | } 14 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/has-content/index.ts: -------------------------------------------------------------------------------- 1 | export * from './has-content'; 2 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/has-content/media-content.ts: -------------------------------------------------------------------------------- 1 | import { HasExample } from '@codegena/definitions/aspects'; 2 | import { Schema } from '@codegena/definitions/json-schema'; 3 | 4 | /** 5 | * Each Media Type Object provides schema and examples for the media type 6 | * identified by its key. 7 | * 8 | * @see https://swagger.io/specification/#mediaTypeObject 9 | */ 10 | export interface MediaContent extends HasExample { 11 | 12 | /** 13 | * The schema defining the content of the request, response, or parameter. 14 | */ 15 | schema?: Schema; 16 | 17 | /** 18 | * https://swagger.io/specification/#encodingObject 19 | * TODO describe and support media type encoding. now is not 20 | */ 21 | encoding?: any; 22 | } 23 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/header-parameter.ts: -------------------------------------------------------------------------------- 1 | import { 2 | HasExample, 3 | HasRef, 4 | } from '@codegena/definitions/aspects'; 5 | 6 | import { AbstractParameter } from './abstract-parameter'; 7 | import { ParameterStyle } from './parameter-style'; 8 | 9 | /** 10 | * Parameter in {@link https://swagger.io/specification/#headerObject}. 11 | */ 12 | export interface HeaderParameter extends HasRef, HasExample, AbstractParameter { 13 | /** 14 | * Describes how the parameter value will be serialized depending on the 15 | * type of the parameter value. Default values (based on value of `in`): 16 | * - for `'query'` - `'form'`; 17 | * - for `'path'` - `'simple'`; 18 | * - for `'header'` - `'simple'`; 19 | * - for `'cookie'` - `'form'`. 20 | * 21 | * @see https://swagger.io/docs/specification/serialization/ 22 | * @see OApiParameter.explode 23 | * 24 | * TODO describe and support style in parameter. now is not. Important! 25 | * FIXME describe and support style in parameter. now is not. Important! 26 | */ 27 | style?: ParameterStyle.Simple; 28 | } 29 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/headers.ts: -------------------------------------------------------------------------------- 1 | import { HeaderParameter } from "./header-parameter"; 2 | 3 | export interface Headers { 4 | [parameterName: string]: HeaderParameter; 5 | } 6 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/info.ts: -------------------------------------------------------------------------------- 1 | import { Contact } from './contact'; 2 | import { License } from './license'; 3 | 4 | /** 5 | * @see https://swagger.io/specification/#infoObject 6 | */ 7 | export interface Info { 8 | contact?: Contact; 9 | description?: string; 10 | license?: License; 11 | termsOfService?: string; 12 | title: string; 13 | version: string; 14 | } 15 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/license.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://swagger.io/specification/#licenseObject 3 | */ 4 | export interface License { 5 | email: string; 6 | name: string; 7 | url?: string; 8 | } 9 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/oas3-specification.ts: -------------------------------------------------------------------------------- 1 | import { ExternalDocument } from './external-document'; 2 | import { Info } from './info'; 3 | import { Paths } from './paths'; 4 | import { ReusableComponents } from './reusable-components'; 5 | import { Server } from './server'; 6 | 7 | /** 8 | * Complete 9 | */ 10 | export interface Oas3Specification { 11 | /** 12 | * REQUIRED. This string MUST be the semantic version number of the 13 | * OpenAPI Specification version that the OpenAPI document uses. 14 | * The `openapi` field SHOULD be used by tooling specifications and clients 15 | * to interpret the OpenAPI document. This is not related to the API 16 | * {@link https://swagger.io/specification/#infoVersion | info.version string}. 17 | */ 18 | openapi: '3.0.3' | '3.0.2' | '3.0.1' | '3.0.0' | '2.0.0'; 19 | 20 | /** 21 | * REQUIRED. Provides metadata about the API. 22 | * The metadata MAY be used by tooling as required. 23 | */ 24 | info: Info; 25 | 26 | /** 27 | * An array of Server Objects, which provide connectivity information to a 28 | * target `server`. If the servers property is not provided, or is an empty array, 29 | * the default value would be a `Server Object` with a url value of `/`. 30 | * 31 | * @see https://swagger.io/specification/#serverObject 32 | */ 33 | servers: Server[]; 34 | 35 | /** 36 | * REQUIRED. The available paths and operations for the API. 37 | * 38 | * @see https://swagger.io/specification/#pathsObject 39 | */ 40 | paths: Paths; 41 | 42 | /** 43 | * Holds a set of reusable objects for different aspects of the OAS. 44 | * All objects defined within the schema object will have no effect on 45 | * the API unless they are explicitly referenced from properties outside the 46 | * schema object. 47 | * 48 | * @see https://swagger.io/specification/#componentsObject 49 | */ 50 | components: ReusableComponents; 51 | 52 | /** 53 | * A declaration of which security mechanisms can be used across the API. 54 | * The list of values includes alternative security requirement objects that 55 | * can be used. Only one of the security requirement objects need to be satisfied 56 | * to authorize a request. Individual operations can override this definition. 57 | * 58 | * @see https://swagger.io/specification/#securityRequirementObject 59 | * 60 | * TODO describe and implement support of security 61 | */ 62 | security: any; 63 | 64 | /** 65 | * A list of tags used by the specification with additional metadata. 66 | * The order of the tags can be used to reflect on their order by the parsing tools. 67 | * Not all tags that are used by the 68 | * {@link https://swagger.io/specification/#operationObject | Operation Object} 69 | * must be declared. The tags that are not declared MAY be organized randomly 70 | * or based on the tools' logic. Each tag name in the list MUST be unique. 71 | * 72 | * TODO describe and implement support of tags 73 | */ 74 | tags: any[]; 75 | 76 | /** 77 | * Additional external documentation. 78 | * @see https://swagger.io/specification/#externalDocumentationObject 79 | * 80 | * TODO describe and implement support of externalDocs 81 | */ 82 | externalDocs?: ExternalDocument; 83 | } 84 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/parameter-style.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Style of parameter serialization. 3 | * @see https://swagger.io/docs/specification/serialization/ 4 | */ 5 | export enum ParameterStyle { 6 | Simple = 'simple', 7 | Label = 'label', 8 | Matrix = 'matrix', 9 | Form = 'form', 10 | SpaceDelimited = 'spaceDelimited', 11 | PipeDelimited = 'pipeDelimited', 12 | DeepObject = 'deepObject' 13 | } 14 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/parameter-target.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see Parameter.in 3 | */ 4 | export enum ParameterTarget { 5 | Path = 'path', 6 | Header = 'header', 7 | Query = 'query', 8 | Cookie = 'cookie', 9 | } 10 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/parameter.ts: -------------------------------------------------------------------------------- 1 | import { HasRef, HasExample } from '@codegena/definitions/aspects'; 2 | import { AbstractParameter } from './abstract-parameter'; 3 | import { ParameterTarget } from './parameter-target'; 4 | 5 | /** 6 | * Describes a single operation parameter. 7 | * A unique parameter is defined by a combination of a 8 | * {@link https://swagger.io/specification/#parameterName | name} 9 | * and 10 | * {@link https://swagger.io/specification/#parameterIn | location}. 11 | * 12 | * @see https://swagger.io/specification/#parameterObject 13 | * @see https://swagger.io/docs/specification/describing-parameters/ 14 | */ 15 | export interface Parameter extends HasRef, HasExample, AbstractParameter { 16 | 17 | /** 18 | * REQUIRED. The location of the parameter. Possible values are: 19 | * - "query", 20 | * - "header" 21 | * - "path" 22 | * - "cookie" 23 | */ 24 | in: ParameterTarget; 25 | 26 | /** 27 | * REQUIRED. The name of the parameter. Parameter names are case sensitive. 28 | * 29 | * @see https://swagger.io/specification/#parameterObject 30 | */ 31 | name: string; 32 | 33 | /** 34 | * @deprecated 35 | * Not in {@link https://swagger.io/specification/#parameterObject | Open API specification }. 36 | * Makes extracted schema of params supporting `readonly` params. 37 | */ 38 | readOnly?: boolean; 39 | } 40 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/path-item.ts: -------------------------------------------------------------------------------- 1 | import { HasRef } from '@codegena/definitions/aspects'; 2 | import { Operation } from './operation'; 3 | import { Parameter } from './parameter'; 4 | 5 | /** 6 | * Describes the operations available on a single path. A Path Item MAY be empty, 7 | * due to {@link https://swagger.io/specification/#securityFiltering | ACL constraints}. 8 | * The path itself is still exposed to the documentation 9 | * viewer but they will not know which operations and parameters are available. 10 | * 11 | * @see https://swagger.io/specification/#pathItemObject 12 | */ 13 | export interface PathItem extends HasRef { 14 | /** 15 | * An optional, string summary, intended to apply 16 | * to all operations in this path. 17 | * TODO support common summary in path. now is not 18 | */ 19 | summary?: string; 20 | 21 | /** 22 | * An optional, string description, intended to apply to all 23 | * operations in this path. CommonMark syntax MAY be used 24 | * for rich text representation. 25 | * TODO support common description in path. now is not 26 | */ 27 | description?: string; 28 | 29 | /** 30 | * A list of parameters that are applicable for all the operations described 31 | * under this path. These parameters can be overridden at the operation level, 32 | * but cannot be removed there. The list MUST NOT include duplicated parameters. 33 | * A unique parameter is defined by a combination of a name and location. 34 | * The list can use the Reference Object to link to parameters that are 35 | * defined at the OpenAPI Object's schema/parameters. 36 | * TODO support common parameters in path. now is not 37 | */ 38 | parameters?: Parameter[]; 39 | 40 | // Methods: 41 | 42 | delete?: Operation; 43 | get?: Operation; 44 | head?: Operation; 45 | options?: Operation; 46 | patch?: Operation; 47 | post?: Operation; 48 | put?: Operation; 49 | trace?: Operation; 50 | } 51 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/paths.ts: -------------------------------------------------------------------------------- 1 | import { PathItem } from './path-item'; 2 | 3 | /** 4 | * Holds the relative paths to the individual endpoints and their operations. 5 | * The path is appended to the URL from the Server Object in order to construct 6 | * the full URL. The Paths MAY be empty, due to 7 | * {@link https://swagger.io/specification/#securityFiltering | ACL constraints}. 8 | * 9 | * @see https://swagger.io/specification/#pathsObject 10 | */ 11 | export interface Paths { 12 | /** 13 | * Field Pattern: /{path} 14 | */ 15 | [path: string]: PathItem; 16 | } 17 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/request.ts: -------------------------------------------------------------------------------- 1 | import { HasRef } from '@codegena/definitions/aspects'; 2 | import { HasContent } from './has-content'; 3 | 4 | /** 5 | * Request Body Object. Describes a single request body. 6 | * @see https://swagger.io/specification/#requestBodyObject 7 | */ 8 | export interface Request extends HasRef, HasContent { 9 | /** 10 | * A brief description of the request body. This could contain examples of 11 | * use. CommonMark syntax MAY be used for rich text representation. 12 | */ 13 | description?: string; 14 | 15 | /** 16 | * Determines if the request body is required in the request. Defaults to `false`. 17 | * TODO support request required. now is not 18 | */ 19 | required?: boolean; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/response.ts: -------------------------------------------------------------------------------- 1 | import { HasRef } from '@codegena/definitions/aspects'; 2 | import { Schema } from '@codegena/definitions/json-schema'; 3 | import { HasContent } from './has-content'; 4 | import { ExternalDocument } from './external-document'; 5 | import { Headers } from './headers'; 6 | 7 | /** 8 | * Describes a single response from an API Operation, including design-time, 9 | * static `links` to operations based on the response. 10 | * 11 | * @see @link https://swagger.io/specification/#responseObject 12 | * @see HasContent 13 | */ 14 | export interface Response extends HasRef, HasContent { 15 | 16 | /** 17 | * REQUIRED. A short description of the response. CommonMark syntax MAY be 18 | * used for rich text representation. 19 | */ 20 | description: string; 21 | 22 | /** 23 | * Additional external documentation for this operation. 24 | * 25 | * TODO support operation externalDocs. now is not 26 | */ 27 | externalDocs?: ExternalDocument; 28 | 29 | /** 30 | * Maps a header name to its definition. RFC7230 states header names are case 31 | * insensitive. If a response header is defined with the name "Content-Type", 32 | * it SHALL be ignored. 33 | * 34 | * TODO describe and support headers in response. now is not. Important! 35 | */ 36 | headers: Headers; 37 | 38 | /** 39 | * A map of operations links that can be followed from the response. 40 | * The key of the map is a short name for the link, following the naming 41 | * constraints of the names for 42 | * {@link https://swagger.io/specification/#componentsObject | Component Objects}. 43 | * 44 | * @see OApiReusableComponents 45 | */ 46 | links: { 47 | [key: string]: any; 48 | }; 49 | 50 | /** 51 | * @deprecated Not OAS3: in order to support OAS2 52 | */ 53 | schema: Schema; 54 | } 55 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/reusable-components.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from '@codegena/definitions/json-schema'; 2 | import { Headers } from './headers'; 3 | import { Parameter } from './parameter'; 4 | import { Request } from './request'; 5 | import { Response } from './response'; 6 | 7 | /** 8 | * Holds a set of reusable objects for different aspects of the OAS. All objects 9 | * defined within the schema object will have no effect on the API unless 10 | * they are explicitly referenced from properties outside the schema object. 11 | * 12 | * @see https://swagger.io/specification/#componentsObject 13 | */ 14 | export interface ReusableComponents { 15 | /** 16 | * An object to hold reusable 17 | * {@link https://swagger.io/specification/#callbackObject | Callback Objects}. 18 | * 19 | * TODO describe and support component callbacks. now is not 20 | */ 21 | callbacks: { 22 | [callbacksObjectName: string]: any; 23 | }; 24 | 25 | /** 26 | * An object to hold reusable 27 | * {@link https://swagger.io/specification/#exampleObject | Example Objects}. 28 | * TODO describe and support component examples. now is not 29 | */ 30 | examples: { 31 | [exampleObjectName: string]: any; 32 | }; 33 | 34 | /** 35 | * An object to hold reusable 36 | * {https://swagger.io/specification/#headerObject | Header Objects}. 37 | */ 38 | headers: Headers; 39 | 40 | /** 41 | * An object to hold reusable 42 | * {https://swagger.io/specification/#linkObject | Link Objects}. 43 | * TODO describe and support component links. now is not 44 | */ 45 | links: { 46 | [key: string]: any; 47 | }; 48 | 49 | /** 50 | * An object to hold reusable 51 | * {@link https://swagger.io/specification/#parameterObject | Parameter Objects }. 52 | */ 53 | parameters: { 54 | [paramterObjectName: string]: Parameter; 55 | }; 56 | 57 | /** 58 | * An object to hold reusable 59 | * {@link https://swagger.io/specification/#requestBodyObject | Request Body Objects }. 60 | */ 61 | requestBodies: { 62 | [requestObjectName: string]: Request; 63 | }; 64 | 65 | /** 66 | * An object to hold reusable 67 | * {@link https://swagger.io/specification/#responseObject | Response Objects}. 68 | */ 69 | responses: { 70 | [responseObjectName: string]: Response; 71 | }; 72 | 73 | /** 74 | * An object to hold reusable 75 | * {@link https://swagger.io/specification/#securitySchemeObject | Security Scheme Objects}. 76 | * TODO describe and support component security schemes. now is not 77 | */ 78 | securitySchemes: { 79 | [key: string]: any; 80 | }; 81 | 82 | /** 83 | * An object to hold reusable Schema Objects. 84 | */ 85 | schemas: { 86 | [schemaObjectName: string]: Schema; 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/server-variable.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://swagger.io/specification/#server-variable-object 3 | */ 4 | export interface ServerVariable { 5 | /** 6 | * REQUIRED. The default value to use for substitution, 7 | * which SHALL be sent if an alternate value is not supplied. 8 | * Note this behavior is different than the Schema Object's treatment 9 | * of default values, because in those cases parameter values are 10 | * optional. 11 | * If the enum is defined, the value SHOULD exist in the enum's values. 12 | */ 13 | default: string; 14 | 15 | /** 16 | * An enumeration of string values to be used if the substitution options 17 | * are from a limited set. The array SHOULD NOT be empty. 18 | */ 19 | enum?: string[]; 20 | 21 | /** 22 | * An optional description for the server variable. 23 | * CommonMark syntax MAY be used for rich text representation. 24 | */ 25 | description?: string; 26 | } 27 | -------------------------------------------------------------------------------- /libs/definitions/oas3/src/types/server.ts: -------------------------------------------------------------------------------- 1 | import { ServerVariable } from './server-variable'; 2 | 3 | /** 4 | * @see https://swagger.io/specification/#serverObject 5 | */ 6 | export interface Server { 7 | /** 8 | * An optional string describing the host designated by the URL. 9 | * CommonMark syntax MAY be used for rich text representation. 10 | */ 11 | description?: string; 12 | 13 | /** 14 | * Extended non-standard option which describes what the 15 | * type of environment should be associated with this server 16 | */ 17 | environment?: string; 18 | 19 | /** 20 | * REQUIRED. A URL to the target host. This URL supports Server Variables and MAY be relative, 21 | * to indicate that the host location is relative to the location where the OpenAPI document is 22 | * being served. Variable substitutions will be made when a variable is named in {brackets}. 23 | */ 24 | url: string; 25 | 26 | /** 27 | * A map between a variable name and its value. 28 | * The value is used for substitution in the server's URL template. 29 | * 30 | * TODO support variables in server. now is not 31 | * @see https://swagger.io/specification/#serverVariableObject 32 | */ 33 | variables?: Record; 34 | } 35 | -------------------------------------------------------------------------------- /libs/definitions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/definitions", 3 | "version": "0.1.0-alpha.3", 4 | "devDependencies": { 5 | "jest-preset-angular": "8.3.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /libs/definitions/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/definitions/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /libs/definitions/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/definitions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "references": [ 4 | { 5 | "path": "./tsconfig.spec.json" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /libs/definitions/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declarationMap": true, 6 | "target": "es2015", 7 | "declaration": true, 8 | "inlineSources": true 9 | }, 10 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"], 11 | "include": ["**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /libs/definitions/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compilerOptions": { 4 | "declarationMap": false 5 | }, 6 | "extends": "./tsconfig.lib.json" 7 | } 8 | -------------------------------------------------------------------------------- /libs/definitions/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "suppressExcessPropertyErrors": false 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": ["**/*.spec.ts", "**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /libs/definitions/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [true, "attribute", "codegena", "camelCase"], 5 | "component-selector": [true, "element", "codegena", "kebab-case"] 6 | }, 7 | "linterOptions": { 8 | "exclude": ["!**/*"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/ng-http-tools/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.0.0-alpha.4 (2021-06-20) 7 | 8 | 9 | ### Features 10 | 11 | * **ng-http-tools:** make `nullable` option of Ajv enabled by default ([b88b00f](https://github.com/koshevy/codegena/commit/b88b00f956feebbdb1b34953282f3dcf0a19fc3a)) 12 | 13 | 14 | 15 | 16 | 17 | # 1.0.0-alpha.3 (2021-06-13) 18 | 19 | **Note:** Version bump only for package @codegena/ng-http-tools 20 | 21 | 22 | 23 | 24 | 25 | # [1.0.0-alpha.2](https://github.com/koshevy/codegena/compare/@codegena/ng-http-tools@1.0.0-alpha.1...@codegena/ng-http-tools@1.0.0-alpha.2) (2021-06-10) 26 | 27 | 28 | ### Features 29 | 30 | * **ng-http-tools:** add VALIDATION_ERROR_STREAM dependency for logging validation errors ([e9f217d](https://github.com/koshevy/codegena/commit/e9f217d919cee15873eb3f2d19231fe04d7e0d1a)) 31 | 32 | 33 | 34 | 35 | 36 | # [1.0.0-alpha.1](https://github.com/koshevy/codegena/compare/@codegena/ng-http-tools@1.0.0-alpha.0...@codegena/ng-http-tools@1.0.0-alpha.1) (2021-06-09) 37 | 38 | 39 | ### Features 40 | 41 | * remove unused npm dependencies ([01b8090](https://github.com/koshevy/codegena/commit/01b8090273656e65d8dcb7d861356aa16279b3bc)) 42 | 43 | 44 | 45 | 46 | 47 | # 1.0.0-alpha.0 (2021-06-09) 48 | 49 | 50 | ### Features 51 | 52 | * **ng-http-tools:** EntrypointAbstract.createUrl can create url with query params (see serializeParams) ([dd93f8e](https://github.com/koshevy/codegena/commit/dd93f8e7dc3b7fe5f749bb07b26969443476a9a7)) 53 | * **ng-http-tools:** provide EntrypointAbstract solution for autogenerated services ([17e9118](https://github.com/koshevy/codegena/commit/17e91184c682c4d1ae7ab8866bedb6ba0d59571b)) 54 | * **ng-http-tools:** provide new pickResponses rx-operator ([07568ef](https://github.com/koshevy/codegena/commit/07568ef81c028d4c3ce53c2141bbf0911b9c1c0b)) 55 | * **ng-http-tools:** support server variables and different environments ([267100c](https://github.com/koshevy/codegena/commit/267100c5c20b3527a48a50b0fd62428293e35fbc)) 56 | 57 | 58 | ### BREAKING CHANGES 59 | 60 | * **ng-http-tools:** signature of `EntrypointAbstract` changed 61 | -------------------------------------------------------------------------------- /libs/ng-http-tools/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'ng-http-tools', 3 | preset: '../../jest.preset.js', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | stringifyContentPathRegex: '\\.(html|svg)$', 8 | astTransformers: { 9 | before: [ 10 | 'jest-preset-angular/build/InlineFilesTransformer', 11 | 'jest-preset-angular/build/StripStylesTransformer', 12 | ], 13 | }, 14 | tsconfig: '/tsconfig.spec.json', 15 | }, 16 | }, 17 | coverageDirectory: '../../coverage/libs/ng-http-tools', 18 | snapshotSerializers: [ 19 | 'jest-preset-angular/build/serializers/no-ng-attributes', 20 | 'jest-preset-angular/build/serializers/ng-snapshot', 21 | 'jest-preset-angular/build/serializers/html-comment', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /libs/ng-http-tools/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/ng-http-tools", 4 | "lib": { 5 | "entryFile": "src/index.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "@codegena/definitions" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /libs/ng-http-tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/ng-http-tools", 3 | "version": "1.0.0-alpha.4", 4 | "peerDependencies": { 5 | "@angular/common": ">= 8", 6 | "@angular/core": ">= 8", 7 | "ajv": ">= 6.0.0", 8 | "lodash": ">= 4", 9 | "rxjs": ">= 5.0.0" 10 | }, 11 | "dependencies": { 12 | "@codegena/definitions": "0.1.0-alpha.3" 13 | }, 14 | "devDependencies": { 15 | "jest-preset-angular": "^8.3.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libs/ng-http-tools/rx-operators/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/public_api.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/ng-http-tools/rx-operators/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/ng-http-tools/rx-operators/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/pick-responses'; 2 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/ng-http-tools.module'; 2 | export * from './lib/ng-http-tools.module'; 3 | export * from './lib/entrypoint-abstract/entrypoint-abstract'; 4 | export * from './lib/entrypoint-abstract/entrypoint-response'; 5 | export * from './lib/entrypoint-abstract/http-method'; 6 | export * from './lib/entrypoint-abstract/request-options'; 7 | export * from './lib/entrypoint-abstract/validation/entrypoint-validation.service'; 8 | export * from './lib/entrypoint-abstract/validation/ajv-wrapper.service'; 9 | export * from './lib/entrypoint-abstract/validation/validation-error'; 10 | export * from './lib/entrypoint-abstract/validation/validation-error-stream'; 11 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/entrypoint-response.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from "rxjs"; 2 | import { HttpEvent, HttpResponse, HttpErrorResponse } from "@angular/common/http"; 3 | 4 | export type EntrypointResponse = Observable< 5 | HttpEvent | HttpErrorResponse 6 | >; 7 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/http-method.ts: -------------------------------------------------------------------------------- 1 | export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; 2 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/request-options.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; 2 | import { ServerEnvironment } from './server-environment'; 3 | 4 | /** 5 | * Type of `options` parameter in {@link HttpClient.request} 6 | */ 7 | type HttpClientsRequestParameters = Parameters['2']; 8 | 9 | /** 10 | * Expected options for {@link HttpClient.request} 11 | */ 12 | export type RequestOptionsRaw = HttpClientsRequestParameters & { 13 | headers?: HttpHeaders; 14 | serverEnvironment?: ServerEnvironment, 15 | } 16 | 17 | export interface RequestOptions { 18 | body: FormData | TRequestBody | string | ArrayBuffer; 19 | params: HttpParams; 20 | headers: HttpHeaders; 21 | /** 22 | * `Observe` is always 'response' because response 23 | * required for validation and scenario understanding. 24 | */ 25 | observe: 'response', 26 | } 27 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/server-environment.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export interface ServerEnvironment { 4 | serverParams?: Record; 5 | environment?: string, 6 | } 7 | 8 | export const SERVER_ENVIRONMENT = new InjectionToken( 9 | 'ServerEnvironment', 10 | ); 11 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-url'; 2 | export * from './parse-request-arguments'; 3 | export * from './prepare-request-options'; 4 | export * from './serialize-form-data'; 5 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/utils/parse-request-arguments.ts: -------------------------------------------------------------------------------- 1 | import { HttpMethod } from "../http-method"; 2 | 3 | export function parseRequestArguments< 4 | TParameters extends object, 5 | TRequestBody, 6 | TResponse 7 | >(method: HttpMethod, ...args): { 8 | parameters?: TParameters, 9 | requestBody?: TRequestBody, 10 | response?: TResponse, 11 | } { 12 | if (method === 'GET') { 13 | return { parameters: args[0] } 14 | } 15 | 16 | if (args.length > 1) { 17 | return { 18 | parameters: args[0], 19 | requestBody: args[1] 20 | } 21 | } 22 | 23 | return { requestBody: args[0] } 24 | } 25 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/utils/prepare-request-options.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient, HttpHeaders } from "@angular/common/http"; 2 | import { flow, pick } from 'lodash'; 3 | import { serializeFormData } from './serialize-form-data'; 4 | import { 5 | RequestOptionsRaw, 6 | RequestOptions, 7 | } from '../request-options'; 8 | 9 | export const defaultContentType = 'application/json'; 10 | export const shouldBeSerializedContentTypes = [ 11 | 'application/x-www-form-urlencoded', 12 | 'multipart/form-data', 13 | ]; 14 | 15 | /** 16 | * Prepares options for {@link HttpClient.request} 17 | */ 18 | export function prepareRequestOptions( 19 | url: string, 20 | parameters: object | null, 21 | requestBody: any, 22 | queryParameters: string[], 23 | rawOptions: RequestOptionsRaw, 24 | ): RequestOptions { 25 | const contentType = getContentType(rawOptions); 26 | const actualizeOptions = flow([ 27 | options => actualizeContentType(options, contentType), 28 | options => actualizeParameters(options, parameters, queryParameters), 29 | options => actualizeRequestBody(options, requestBody, contentType), 30 | options => addRequiredParameters(options), 31 | ]); 32 | 33 | return actualizeOptions(rawOptions); 34 | } 35 | 36 | function getContentType(options: RequestOptionsRaw): string { 37 | return options.headers?.get('content-type') || defaultContentType; 38 | } 39 | 40 | function actualizeContentType( 41 | options: RequestOptionsRaw, 42 | contentType: string, 43 | ): RequestOptionsRaw { 44 | const headers = options.headers || new HttpHeaders(); 45 | 46 | return { 47 | ...options, 48 | headers: headers.set('content-type', contentType), 49 | }; 50 | } 51 | 52 | function actualizeParameters( 53 | options: RequestOptionsRaw, 54 | parameters: object | null, 55 | queryParameters: string[], 56 | ): RequestOptionsRaw { 57 | if (!queryParameters?.length) { 58 | return options; 59 | } 60 | 61 | const serializedParameters = serializeFormData( 62 | pick(parameters, queryParameters), 63 | ); 64 | 65 | return {...options, params: serializedParameters || {}}; 66 | } 67 | 68 | function actualizeRequestBody( 69 | options: RequestOptionsRaw, 70 | rawRequestBody: any, 71 | contentType: string, 72 | ): RequestOptionsRaw { 73 | if (!rawRequestBody) { 74 | return options; 75 | } 76 | 77 | let requestBody; 78 | if (shouldBeSerializedContentTypes.includes(contentType) 79 | && !(rawRequestBody instanceof FormData)) { 80 | 81 | requestBody = serializeFormData(rawRequestBody); 82 | } else { 83 | requestBody = rawRequestBody; 84 | } 85 | 86 | return {...options, body: requestBody} 87 | } 88 | 89 | function addRequiredParameters(options: RequestOptionsRaw): RequestOptionsRaw { 90 | return { 91 | ...options, 92 | // observe is always 'response' because response 93 | // required for validation 94 | observe: 'response', 95 | }; 96 | } 97 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/utils/serialize-form-data.ts: -------------------------------------------------------------------------------- 1 | import { 2 | HttpParams, 3 | HttpParameterCodec, 4 | HttpUrlEncodingCodec 5 | } from '@angular/common/http'; 6 | import { isObjectLike } from 'lodash'; 7 | 8 | const defaultEncoder = new HttpUrlEncodingCodec(); 9 | 10 | export function serializeFormData( 11 | dataToBeSerialized: any, 12 | encoder: HttpParameterCodec = defaultEncoder, 13 | ): HttpParams | null { 14 | const fromSource = isObjectLike(dataToBeSerialized) 15 | ? { fromObject: dataToBeSerialized } 16 | : { fromString: dataToBeSerialized.toString() }; 17 | 18 | return new HttpParams({ encoder, ...fromSource }); 19 | } 20 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/validation/ajv-wrapper.service.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter, Injectable } from '@angular/core'; 2 | import { Schema } from '@codegena/definitions/json-schema'; 3 | import * as Ajv from 'ajv'; 4 | import { ValidationError } from './validation-error'; 5 | 6 | type SchemaWithId = Schema & {$id?: string}; 7 | type AjvCompiler = Ajv.Ajv; 8 | 9 | @Injectable() 10 | export class AjvWrapperService { 11 | protected ajvs: WeakMap = new WeakMap(); 12 | protected validators: Record = {}; 13 | 14 | constructor( 15 | private validationErrorStream: EventEmitter | null = null, 16 | private shouldThrowOnFails: boolean = true, 17 | private formats: Record = {}, 18 | private unknownFormats: string[] = [], 19 | private ajvOptions: Ajv.Options = {}, 20 | ) {} 21 | 22 | /** 23 | * @throws ValidationError if fails and `shouldThrowOnFails` is true 24 | * @param value value should be validated 25 | * @param schema schema should be used for validation 26 | * @param domainSchemas Library of schemas used for that business domain 27 | */ 28 | public validate(value: unknown, schema: SchemaWithId, domainSchemas: object): void { 29 | const validate = this.getValidator(schema, domainSchemas); 30 | 31 | if (validate(value)) { 32 | return; 33 | } 34 | 35 | const validationError = new ValidationError( 36 | `Validation failed, schema id: ${schema.$id}`, 37 | value, 38 | schema, 39 | validate.errors || null, 40 | ); 41 | 42 | if (this.validationErrorStream) { 43 | this.validationErrorStream.emit(validationError); 44 | } 45 | 46 | if (this.shouldThrowOnFails) { 47 | throw validationError; 48 | } 49 | } 50 | 51 | private getValidator(schema: SchemaWithId, domainSchemas: object): Ajv.ValidateFunction { 52 | if (schema.$id && this.validators[schema.$id]) { 53 | return this.validators[schema.$id]; 54 | } 55 | 56 | const compiler = this.getCompiler(domainSchemas); 57 | const validator = compiler?.compile(schema); 58 | 59 | if (!validator) { 60 | throw new Error(`Can't compile validator!`); 61 | } 62 | 63 | if (schema.$id) { 64 | this.validators[schema.$id] = validator; 65 | } 66 | 67 | return validator; 68 | } 69 | 70 | private getCompiler(domainSchemas: object): AjvCompiler | null { 71 | if (!this.ajvs.has(domainSchemas)) { 72 | this.ajvs.set(domainSchemas, this.createCompiler(domainSchemas)); 73 | } 74 | 75 | return this.ajvs.get(domainSchemas) || null; 76 | } 77 | 78 | private createCompiler(domainSchemas: object): AjvCompiler { 79 | return new Ajv({ 80 | allErrors: true, 81 | coerceTypes: false, 82 | errorDataPath: 'property', 83 | formats: this.formats, 84 | jsonPointers: false, 85 | ownProperties: true, 86 | removeAdditional: true, 87 | schemas: [domainSchemas], 88 | unknownFormats: this.unknownFormats, 89 | useDefaults: true, 90 | verbose: true, 91 | nullable: true, 92 | ...this.ajvOptions, 93 | }); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/validation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ajv-wrapper.service'; 2 | export * from './entrypoint-validation.service'; 3 | export * from './validation-error'; 4 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/validation/validation-error-stream.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter, InjectionToken } from '@angular/core'; 2 | import { ValidationError } from './validation-error'; 3 | 4 | export const VALIDATION_ERROR_STREAM = new InjectionToken< 5 | EventEmitter | null 6 | >( 7 | 'Validation error stream', 8 | { 9 | factory: () => null, 10 | }, 11 | ); 12 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/entrypoint-abstract/validation/validation-error.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from '@codegena/definitions/json-schema'; 2 | import { 3 | ValidationError as AjvValidationError, 4 | ErrorObject as AjvErrorObject, 5 | } from 'ajv'; 6 | 7 | export class ValidationError { 8 | constructor( 9 | public readonly message: string, 10 | public readonly value: unknown, 11 | public readonly schema: Schema, 12 | public readonly errors: (AjvValidationError | AjvErrorObject)[] | null, 13 | ) {} 14 | } 15 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/lib/ng-http-tools.module.ts: -------------------------------------------------------------------------------- 1 | import { inject, NgModule, ModuleWithProviders } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { Options as AjvOptions } from 'ajv'; 4 | import { 5 | VALIDATION_ERROR_STREAM, 6 | } from './entrypoint-abstract/validation/validation-error-stream'; 7 | import { 8 | AjvWrapperService, 9 | } from './entrypoint-abstract/validation/ajv-wrapper.service'; 10 | import { 11 | EntrypointValidationService, 12 | } from './entrypoint-abstract/validation/entrypoint-validation.service'; 13 | import { 14 | SERVER_ENVIRONMENT, 15 | ServerEnvironment, 16 | } from './entrypoint-abstract/server-environment'; 17 | 18 | @NgModule({ 19 | imports: [ 20 | CommonModule, 21 | ], 22 | }) 23 | export class NgHttpToolsModule { 24 | public static forModule(options: { 25 | shouldThrowOnFails?: boolean, 26 | formats?: Record, 27 | unknownFormats?: string[], 28 | serverEnvironment?: ServerEnvironment, 29 | ajvOptions?: AjvOptions, 30 | }): ModuleWithProviders { 31 | return { 32 | ngModule: NgHttpToolsModule, 33 | providers: [ 34 | { 35 | provide: AjvWrapperService, 36 | useFactory: () => new AjvWrapperService( 37 | inject(VALIDATION_ERROR_STREAM), 38 | options.shouldThrowOnFails ?? true, 39 | options.formats ?? {}, 40 | options.unknownFormats ?? [], 41 | options.ajvOptions ?? {}, 42 | ), 43 | }, 44 | { 45 | provide: SERVER_ENVIRONMENT, 46 | useValue: options.serverEnvironment ?? {}, 47 | }, 48 | EntrypointValidationService, 49 | ], 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /libs/ng-http-tools/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/ng-http-tools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "references": [ 4 | { 5 | "path": "./tsconfig.spec.json" 6 | }, 7 | { 8 | "path": "./tsconfig.lib.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /libs/ng-http-tools/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declarationMap": true, 6 | "target": "es2015", 7 | "declaration": true, 8 | "inlineSources": true, 9 | "strictNullChecks": true 10 | }, 11 | "angularCompilerOptions": { 12 | "enableIvy": false 13 | }, 14 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"], 15 | "include": ["**/*.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/ng-http-tools/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compilerOptions": { 4 | "declarationMap": false 5 | }, 6 | "extends": "./tsconfig.lib.json" 7 | } 8 | -------------------------------------------------------------------------------- /libs/ng-http-tools/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/ng-http-tools/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [true, "attribute", "ngHttpTools", "camelCase"], 5 | "component-selector": [true, "element", "ng-http-tools", "kebab-case"] 6 | }, 7 | "linterOptions": { 8 | "exclude": ["!**/*"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/public_api.ts" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './public_api'; 2 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/lib/facade.ts: -------------------------------------------------------------------------------- 1 | import { Oas3Specification } from '@codegena/definitions/oas3'; 2 | import { Operation } from './operation'; 3 | import { DependencyCollection } from './source'; 4 | 5 | export interface Facade extends DependencyCollection { 6 | operations: Operation[]; 7 | specification: Oas3Specification 8 | 9 | commit(): void; 10 | } 11 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/lib/file-saving-strategy.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "typescript"; 2 | 3 | export interface FileSavingStrategy { 4 | getDependencyFullPath(modelName: string, operationName: string): string; 5 | getCommonDependencyFullPath(modelName: string): string; 6 | getRelativePath(from: string, to: string): string; 7 | commit(source: SourceFile): void; 8 | } 9 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/lib/operation.ts: -------------------------------------------------------------------------------- 1 | import { HasContentType, HasResponses } from '@codegena/definitions/aspects'; 2 | import { 3 | Oas3Operation, 4 | Oas3Server, 5 | } from '@codegena/definitions/oas3'; 6 | import { Schema as JsonSchema } from '@codegena/definitions/json-schema'; 7 | import { 8 | Dependency, 9 | DependencyCollection, 10 | } from './source'; 11 | 12 | export interface Response extends Dependency { 13 | schema: HasResponses>; 14 | } 15 | 16 | export interface Request extends Dependency { 17 | schema: HasContentType; 18 | } 19 | 20 | export interface Parameters extends Dependency { 21 | schema: JsonSchema; 22 | } 23 | 24 | export interface Operation extends DependencyCollection { 25 | dependencies: Dependency[]; 26 | method: string; 27 | oas3Operation: Oas3Operation; 28 | oas3OperationJsonPath: string[]; 29 | path: string; 30 | parameters: Parameters, 31 | request: Request; 32 | response: Response; 33 | servers: Oas3Server[]; 34 | queryParameters: string[] | null; 35 | } 36 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/lib/source.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "typescript"; 2 | import { Schema as JsonSchema, Generic } from '@codegena/definitions/json-schema'; 3 | 4 | export interface Dependency { 5 | source: SourceFile; 6 | dependencies?: Dependency []; 7 | schema: JsonSchema | Generic; 8 | } 9 | 10 | export interface DependencyCollection { 11 | allDependencies: Dependency[]; 12 | commonDependencies: Dependency[]; 13 | } 14 | -------------------------------------------------------------------------------- /libs/oapi3ts/contract/src/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/facade'; 2 | export * from './lib/file-saving-strategy'; 3 | export * from './lib/operation'; 4 | export * from './lib/source'; 5 | -------------------------------------------------------------------------------- /libs/oapi3ts/index.ts: -------------------------------------------------------------------------------- 1 | // This file is necessary for correct working 2 | // of code hints in WebStorm 3 | export * from './src'; 4 | -------------------------------------------------------------------------------- /libs/oapi3ts/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | coverageDirectory: '../../coverage/libs/oapi3ts', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | stringifyContentPathRegex: '\\.(html|svg)$', 8 | astTransformers: { 9 | before: [ 10 | 'jest-preset-angular/build/InlineFilesTransformer', 11 | 'jest-preset-angular/build/StripStylesTransformer', 12 | ], 13 | }, 14 | tsconfig: '/tsconfig.spec.json', 15 | }, 16 | }, 17 | displayName: 'oapi3ts', 18 | }; 19 | -------------------------------------------------------------------------------- /libs/oapi3ts/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/oapi3ts", 4 | "lib": { 5 | "entryFile": "src/index.ts", 6 | "umdModuleIds": { 7 | "lodash" : "_" 8 | } 9 | }, 10 | "whitelistedNonPeerDependencies": [ 11 | "@codegena/oapi3ts", 12 | "@codegena/definitions", 13 | "@types/lodash", 14 | "@types/node", 15 | "ajv", 16 | "json-pointer", 17 | "lodash", 18 | "prettier", 19 | "typescript" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/oapi3ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/oapi3ts", 3 | "version": "3.0.0-alpha.4", 4 | "description": "Codegeneration from OAS3 to TypeScript", 5 | "author": "koshevy@gmail.com", 6 | "keywords": [ 7 | "swagger", 8 | "oas", 9 | "oas3", 10 | "oas 3", 11 | "openapi", 12 | "openapi3", 13 | "open-api", 14 | "open api", 15 | "codegeneration", 16 | "code generation", 17 | "typescript" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/koshevy/codegena.git" 22 | }, 23 | "license": "MIT", 24 | "scripts": { 25 | "build": "ng build oapi3ts" 26 | }, 27 | "dependencies": { 28 | "@codegena/definitions": "0.1.0-alpha.3", 29 | "json-pointer": "^0.6.0" 30 | }, 31 | "peerDependencies": { 32 | "ajv": ">= 6", 33 | "lodash": ">= 4", 34 | "prettier": ">= 1", 35 | "typescript": ">= 3.9.0" 36 | }, 37 | "devDependencies": { 38 | "@types/lodash": ">= 4", 39 | "@types/node": ">= 8", 40 | "jest-preset-angular": "8.3.1" 41 | }, 42 | "optionalDependencies": { 43 | "@microsoft/typescript-etw": "*" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/facade.spec.ts: -------------------------------------------------------------------------------- 1 | import { Facade } from './facade'; 2 | import { DummyFileSavingStrategy } from './stubs/dummy-file-saving-strategy'; 3 | const complexOAS3Specification = require('./schemas/complex.json'); 4 | 5 | describe('Facade', () => { 6 | it('should be created', () => { 7 | const strategy = new DummyFileSavingStrategy(); 8 | const facade = new Facade(complexOAS3Specification, strategy); 9 | facade.commit(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './legacy/core/parsing-problems'; 2 | export * from './facade'; 3 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/any.ts: -------------------------------------------------------------------------------- 1 | // todo оптимизировать файлову структуру и типизацию 2 | import { BaseConvertor } from '../../../core'; 3 | import { DataTypeDescriptor } from '../../../core/data-type-descriptor'; 4 | import { AbstractTypeScriptDescriptor } from './abstract'; 5 | 6 | export class AnyTypeScriptDescriptor 7 | extends AbstractTypeScriptDescriptor 8 | implements DataTypeDescriptor { 9 | 10 | constructor( 11 | 12 | public schema: any, 13 | 14 | /** 15 | * Родительский конвертор, который используется 16 | * чтобы создавать вложенные дескрипторы. 17 | */ 18 | convertor: BaseConvertor, 19 | 20 | /** 21 | * Рабочий контекст 22 | */ 23 | public context: {[name: string]: DataTypeDescriptor}, 24 | 25 | /** 26 | * Название этой модели (может быть string 27 | * или null). 28 | */ 29 | public modelName: string, 30 | 31 | /* 32 | * Предлагаемое имя для типа данных: может 33 | * применяться, если тип данных анонимный, но 34 | * необходимо вынести его за пределы родительской 35 | * модели по-ситуации (например, в случае с Enum). 36 | */ 37 | public readonly suggestedModelName: string, 38 | 39 | /** 40 | * Путь до оригинальной схемы, на основе 41 | * которой было создано описание этого типа данных. 42 | */ 43 | public originalSchemaPath: string 44 | 45 | ) { 46 | super( 47 | schema, 48 | convertor, 49 | context, 50 | modelName, 51 | suggestedModelName, 52 | originalSchemaPath 53 | ); 54 | } 55 | 56 | /** 57 | * Рендер типа данных в строку. 58 | * 59 | * @param childrenDependencies 60 | * Immutable-массив, в который складываются все зависимости 61 | * типов-потомков (если такие есть). 62 | * @param rootLevel 63 | * Говорит о том, что это рендер "корневого" 64 | * уровня — то есть, не в составе другого типа, 65 | * а самостоятельно. 66 | * 67 | */ 68 | public render( 69 | childrenDependencies: DataTypeDescriptor[], 70 | rootLevel: boolean = true 71 | ): string { 72 | const comment = this.getComments(); 73 | 74 | return `${rootLevel ? `${comment}export type ${this.modelName} = ` : ''}any`; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/boolean.ts: -------------------------------------------------------------------------------- 1 | // todo оптимизировать файлову структуру и типизацию 2 | import { BaseConvertor } from '../../../core'; 3 | import { DataTypeDescriptor } from '../../../core/data-type-descriptor'; 4 | import { AbstractTypeScriptDescriptor } from './abstract'; 5 | 6 | export class BooleanTypeScriptDescriptor 7 | extends AbstractTypeScriptDescriptor 8 | implements DataTypeDescriptor { 9 | 10 | constructor( 11 | 12 | public schema: any, 13 | 14 | /** 15 | * Родительский конвертор, который используется 16 | * чтобы создавать вложенные дескрипторы. 17 | */ 18 | convertor: BaseConvertor, 19 | 20 | /** 21 | * Рабочий контекст 22 | */ 23 | public context: {[name: string]: DataTypeDescriptor}, 24 | 25 | /** 26 | * Название этой модели (может быть string 27 | * или null). 28 | */ 29 | public modelName: string, 30 | 31 | /* 32 | * Предлагаемое имя для типа данных: может 33 | * применяться, если тип данных анонимный, но 34 | * необходимо вынести его за пределы родительской 35 | * модели по-ситуации (например, в случае с Enum). 36 | */ 37 | public readonly suggestedModelName: string, 38 | 39 | /** 40 | * Путь до оригинальной схемы, на основе 41 | * которой было создано описание этого типа данных. 42 | */ 43 | public originalSchemaPath: string 44 | 45 | ) { 46 | super( 47 | schema, 48 | convertor, 49 | context, 50 | modelName, 51 | suggestedModelName, 52 | originalSchemaPath 53 | ); 54 | } 55 | 56 | /** 57 | * Рендер типа данных в строку. 58 | * 59 | * @param childrenDependencies 60 | * Immutable-массив, в который складываются все зависимости 61 | * типов-потомков (если такие есть). 62 | * @param rootLevel 63 | * Говорит о том, что это рендер "корневого" 64 | * уровня — то есть, не в составе другого типа, 65 | * а самостоятельно. 66 | * 67 | */ 68 | public render( 69 | childrenDependencies: DataTypeDescriptor[], 70 | rootLevel: boolean = true 71 | ): string { 72 | const comment = this.getComments(); 73 | 74 | return `${rootLevel ? `${comment}export type ${this.modelName} = ` : ''}boolean`; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/instanceof.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DataTypeDescriptor, 3 | DataTypeContainer 4 | } from '../../../core/data-type-descriptor'; 5 | 6 | import { BaseConvertor } from '../../../core'; 7 | import { AbstractTypeScriptDescriptor } from './abstract'; 8 | 9 | export class InstanceofDescriptior extends AbstractTypeScriptDescriptor { 10 | 11 | protected instanceOf: string; 12 | protected genericOf: DataTypeContainer | DataTypeDescriptor; 13 | 14 | constructor( 15 | public schema: any, 16 | 17 | /** 18 | * Родительский конвертор, который используется 19 | * чтобы создавать вложенные дескрипторы. 20 | */ 21 | protected convertor: BaseConvertor, 22 | 23 | /** 24 | * Рабочий контекст 25 | */ 26 | public readonly context: {[name: string]: DataTypeDescriptor}, 27 | 28 | /** 29 | * Название этой модели (может быть string 30 | * или null). 31 | */ 32 | public readonly modelName: string, 33 | 34 | /* 35 | * Предлагаемое имя для типа данных: может 36 | * применяться, если тип данных анонимный, но 37 | * необходимо вынести его за пределы родительской 38 | * модели по-ситуации (например, в случае с Enum). 39 | */ 40 | public readonly suggestedModelName: string, 41 | 42 | /** 43 | * Путь до оригинальной схемы, на основе 44 | * которой было создано описание этого типа данных. 45 | */ 46 | public readonly originalSchemaPath: string 47 | 48 | ) { 49 | super( 50 | schema, 51 | convertor, 52 | context, 53 | modelName, 54 | suggestedModelName, 55 | originalSchemaPath 56 | ); 57 | 58 | this.instanceOf = schema['instanceof']; 59 | 60 | if (schema['x-generic']) { 61 | this.genericOf = convertor.convert( 62 | schema['x-generic'], 63 | context, 64 | null, 65 | (modelName || suggestedModelName) 66 | ? `${(modelName || suggestedModelName)}FormDataFormat` 67 | : null 68 | ); 69 | } 70 | } 71 | 72 | /** 73 | * Рендер типа данных в строку. 74 | * 75 | * @param childrenDependencies 76 | * Immutable-массив, в который складываются все зависимости 77 | * типов-потомков (если такие есть). 78 | * @param rootLevel 79 | * Говорит о том, что это рендер "корневого" 80 | * уровня — то есть, не в составе другого типа, 81 | * а самостоятельно. 82 | * 83 | */ 84 | public render( 85 | childrenDependencies: DataTypeDescriptor[], 86 | rootLevel: boolean = true 87 | ): string { 88 | const comment = this.getComments(); 89 | 90 | return `${rootLevel ? `${comment}export type ${this.modelName} ${ 91 | this.genericOf 92 | ? `<${this.genericOf}>` 93 | : '' 94 | } = ` : ''}${ this.instanceOf }`; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/null.ts: -------------------------------------------------------------------------------- 1 | // todo оптимизировать файлову структуру и типизацию 2 | import { BaseConvertor } from '../../../core'; 3 | import { DataTypeDescriptor } from '../../../core/data-type-descriptor'; 4 | import { AbstractTypeScriptDescriptor } from './abstract'; 5 | 6 | export class NullTypeScriptDescriptor 7 | extends AbstractTypeScriptDescriptor 8 | implements DataTypeDescriptor { 9 | 10 | constructor( 11 | 12 | public schema: any, 13 | 14 | /** 15 | * Родительский конвертор, который используется 16 | * чтобы создавать вложенные дескрипторы. 17 | */ 18 | convertor: BaseConvertor, 19 | 20 | /** 21 | * Рабочий контекст 22 | */ 23 | public context: {[name: string]: DataTypeDescriptor}, 24 | 25 | /** 26 | * Название этой модели (может быть string 27 | * или null). 28 | */ 29 | public modelName: string, 30 | 31 | /* 32 | * Предлагаемое имя для типа данных: может 33 | * применяться, если тип данных анонимный, но 34 | * необходимо вынести его за пределы родительской 35 | * модели по-ситуации (например, в случае с Enum). 36 | */ 37 | public readonly suggestedModelName: string, 38 | 39 | /** 40 | * Путь до оригинальной схемы, на основе 41 | * которой было создано описание этого типа данных. 42 | */ 43 | public originalSchemaPath: string 44 | 45 | ) { 46 | super( 47 | schema, 48 | convertor, 49 | context, 50 | modelName, 51 | suggestedModelName, 52 | originalSchemaPath 53 | ); 54 | } 55 | 56 | /** 57 | * Рендер типа данных в строку. 58 | * 59 | * @param childrenDependencies 60 | * Immutable-массив, в который складываются все зависимости 61 | * типов-потомков (если такие есть). 62 | * @param rootLevel 63 | * Говорит о том, что это рендер "корневого" 64 | * уровня — то есть, не в составе другого типа, 65 | * а самостоятельно. 66 | * 67 | */ 68 | public render( 69 | childrenDependencies: DataTypeDescriptor[], 70 | rootLevel: boolean = true 71 | ): string { 72 | const comment = this.getComments(); 73 | 74 | return `${rootLevel ? `${comment}export type ${this.modelName} = ` : ''}null`; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/number.ts: -------------------------------------------------------------------------------- 1 | // todo оптимизировать файлову структуру и типизацию 2 | import { BaseConvertor } from '../../../core'; 3 | import { 4 | DataTypeDescriptor 5 | } from '../../../core/data-type-descriptor'; 6 | import { AbstractTypeScriptDescriptor } from './abstract'; 7 | 8 | export class NumberTypeScriptDescriptor 9 | extends AbstractTypeScriptDescriptor 10 | implements DataTypeDescriptor { 11 | 12 | constructor( 13 | 14 | public schema: any, 15 | 16 | /** 17 | * Родительский конвертор, который используется 18 | * чтобы создавать вложенные дескрипторы. 19 | */ 20 | convertor: BaseConvertor, 21 | 22 | /** 23 | * Рабочий контекст 24 | */ 25 | public context: {[name: string]: DataTypeDescriptor}, 26 | 27 | /** 28 | * Название этой модели (может быть string 29 | * или null). 30 | */ 31 | public modelName: string, 32 | 33 | /* 34 | * Предлагаемое имя для типа данных: может 35 | * применяться, если тип данных анонимный, но 36 | * необходимо вынести его за пределы родительской 37 | * модели по-ситуации (например, в случае с Enum). 38 | */ 39 | public readonly suggestedModelName: string, 40 | 41 | /** 42 | * Путь до оригинальной схемы, на основе 43 | * которой было создано описание этого типа данных. 44 | */ 45 | public originalSchemaPath: string 46 | 47 | ) { 48 | super( 49 | schema, 50 | convertor, 51 | context, 52 | modelName, 53 | suggestedModelName, 54 | originalSchemaPath 55 | ); 56 | } 57 | 58 | /** 59 | * Рендер типа данных в строку. 60 | * 61 | * @param childrenDependencies 62 | * Immutable-массив, в который складываются все зависимости 63 | * типов-потомков (если такие есть). 64 | * @param rootLevel 65 | * Говорит о том, что это рендер "корневого" 66 | * уровня — то есть, не в составе другого типа, 67 | * а самостоятельно. 68 | * 69 | */ 70 | public render( 71 | childrenDependencies: DataTypeDescriptor[], 72 | rootLevel: boolean = true 73 | ): string { 74 | const comment = this.getComments(); 75 | if (rootLevel && !(this.modelName || this.suggestedModelName)) { 76 | throw new Error( 77 | 'Type can\'t be rendered as root! Should have `modelName` or `suggestedModelName`' 78 | ); 79 | } 80 | 81 | return `${rootLevel ? `${comment}export type ${ 82 | this.modelName || this.suggestedModelName 83 | } = ` : ''}number`; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/descriptors/string.ts: -------------------------------------------------------------------------------- 1 | 2 | // todo оптимизировать файлову структуру и типизацию 3 | import { BaseConvertor } from '../../../core'; 4 | import { DataTypeDescriptor } from '../../../core/data-type-descriptor'; 5 | import { AbstractTypeScriptDescriptor } from './abstract'; 6 | 7 | export class StringTypeScriptDescriptor extends AbstractTypeScriptDescriptor { 8 | 9 | constructor( 10 | 11 | public schema: any, 12 | 13 | /** 14 | * Родительский конвертор, который используется 15 | * чтобы создавать вложенные дескрипторы. 16 | */ 17 | convertor: BaseConvertor, 18 | 19 | /** 20 | * Рабочий контекст 21 | */ 22 | public context: {[name: string]: DataTypeDescriptor}, 23 | 24 | /** 25 | * Название этой модели (может быть string 26 | * или null). 27 | */ 28 | public modelName: string, 29 | 30 | /* 31 | * Предлагаемое имя для типа данных: может 32 | * применяться, если тип данных анонимный, но 33 | * необходимо вынести его за пределы родительской 34 | * модели по-ситуации (например, в случае с Enum). 35 | */ 36 | public readonly suggestedModelName: string, 37 | 38 | /** 39 | * Путь до оригинальной схемы, на основе 40 | * которой было создано описание этого типа данных. 41 | */ 42 | public originalSchemaPath: string 43 | 44 | ) { 45 | super( 46 | schema, 47 | convertor, 48 | context, 49 | modelName, 50 | suggestedModelName, 51 | originalSchemaPath 52 | ); 53 | } 54 | 55 | /** 56 | * Рендер типа данных в строку. 57 | * 58 | * @param childrenDependencies 59 | * Immutable-массив, в который складываются все зависимости 60 | * типов-потомков (если такие есть). 61 | * @param rootLevel 62 | * Говорит о том, что это рендер "корневого" 63 | * уровня — то есть, не в составе другого типа, 64 | * а самостоятельно. 65 | * 66 | */ 67 | public render( 68 | childrenDependencies: DataTypeDescriptor[], 69 | rootLevel: boolean = true 70 | ): string { 71 | const comment = this.getComments(); 72 | 73 | return `${ 74 | rootLevel 75 | ? `${comment}export type ${this.modelName} = ` 76 | : '' 77 | }string`; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/adapters/typescript/index.ts: -------------------------------------------------------------------------------- 1 | export * from './convertor'; 2 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/core/api-meta-info.ts: -------------------------------------------------------------------------------- 1 | import { HasContentType, HasResponses } from '@codegena/definitions/aspects'; 2 | import { Oas3Server } from '@codegena/definitions/oas3'; 3 | import { Schema } from '@codegena/definitions/json-schema'; 4 | 5 | /** 6 | * Meta-information about of API method. 7 | */ 8 | export interface ApiMetaInfo { 9 | /** 10 | * Base file file name (without `.json`) that used as a storage. 11 | * `apiSchemaFile` will be appended to external refs as a `$id`. 12 | * 13 | * By default — `domain-api-schema` 14 | */ 15 | apiSchemaFile: string; 16 | 17 | baseTypeName: string; 18 | 19 | /** 20 | * JSON Schema of body request. 21 | */ 22 | headersSchema: HasContentType | null; 23 | 24 | headersModelName: string; 25 | 26 | /** 27 | * Mock data, extracted from examples. 28 | */ 29 | mockData: any; 30 | 31 | method: 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'; 32 | 33 | paramsModelName: string; 34 | 35 | /** 36 | * Schema of params (params in `query` and params in `paths`). 37 | */ 38 | paramsSchema: any; 39 | 40 | /** 41 | * Absolute URL of method without domain name 42 | * and protocol. 43 | */ 44 | path: string; 45 | 46 | /** 47 | * Parameters of method, should get from query. 48 | */ 49 | queryParams: string[]; 50 | 51 | /** 52 | * Flag to inform an autogenerated service the request is required. 53 | * TODO to do support in ng-api-service 54 | */ 55 | requestIsRequired: boolean; 56 | 57 | requestModelName: string; 58 | 59 | /** 60 | * JSON Schema of body request. 61 | */ 62 | requestSchema: HasContentType | null; 63 | 64 | responseModelName: string; 65 | 66 | /** 67 | * JSON Schema of body response. 68 | * 69 | * Combined schema with sub-schema for every status code, or `default`, 70 | * and one more nested level of sub-scheme with content-types of `default`. 71 | */ 72 | responseSchema: HasResponses> | null; 73 | 74 | /** 75 | * Name of related data types, such be included to file with API Service. 76 | * Usually, related data types returns in result of {@link Convertor.getOAPI3EntryPoints}. 77 | */ 78 | typingsDependencies: string[]; 79 | 80 | /** 81 | * Directory, where files with {@link typingsDependencies} should be stored. 82 | */ 83 | typingsDirectory: string; 84 | 85 | servers: Oas3Server[]; 86 | } 87 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/core/config.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable triple-equals */ 2 | import _ from 'lodash'; 3 | import { Oas3Server } from '@codegena/definitions/oas3'; 4 | import { DataTypeDescriptor } from './data-type-descriptor'; 5 | 6 | export interface ConvertorConfig { 7 | 8 | /** 9 | * Regex which is using for extract JSON Path parts. 10 | */ 11 | jsonPathRegex: RegExp; 12 | 13 | /** 14 | * Mode when models that refer to any models via `$ref` 15 | * replacing implicitly even firsts have names. 16 | * 17 | * For example, in this case: 18 | * ```yml 19 | * schema: 20 | * schema: 21 | * FistModel: 22 | * $ref: SecondModel 23 | * SecondModel: 24 | * type: object 25 | * properties: 26 | * exampleProperty: 27 | * type: string 28 | * ``` 29 | * 30 | * `FirstModel` will be replaced by `SecondModel` in every 31 | * place when `implicitTypesRefReplacement=true` but otherwise 32 | * `SecondModel` will be rendered as interface such extends `FistModel`. 33 | * 34 | */ 35 | implicitTypesRefReplacement: boolean; 36 | parametersModelName: (baseTypeName) => string; 37 | headersModelName: (baseTypeName, code, contentType?) => string; 38 | requestModelName: (baseTypeName, contentType?) => string; 39 | responseModelName: (baseTypeName, code, contentType?) => string; 40 | typingsDirectory: string; 41 | mocksDirectory: string; 42 | excludeFromComparison: string[]; 43 | defaultServerInfo: Oas3Server[]; 44 | } 45 | 46 | export const defaultConfig: ConvertorConfig = { 47 | jsonPathRegex: /([\w:\/\\\.]+)?#(\/?[\w+\/?]+)/, 48 | implicitTypesRefReplacement: false, 49 | parametersModelName: (baseTypeName) => `${baseTypeName}Parameters`, 50 | headersModelName: (baseTypeName, code) => 51 | `${baseTypeName}HeadersResponse${code}`, 52 | requestModelName: (baseTypeName) => 53 | `${baseTypeName}Request`, 54 | responseModelName: (baseTypeName, code, contentTypeKey = null) => 55 | `${baseTypeName}${_.capitalize(contentTypeKey)}Response${code}`, 56 | typingsDirectory: './typings', 57 | mocksDirectory: './mocks', 58 | excludeFromComparison: [ 59 | 'description', 60 | 'title', 61 | 'example', 62 | 'default', 63 | 'readonly', 64 | ], 65 | defaultServerInfo: [ 66 | { 67 | url: 'http://localhost' 68 | } 69 | ] 70 | }; 71 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/core/data-type-descriptor.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Schema, 3 | Generic as SchemaGeneric, 4 | } from '@codegena/definitions/json-schema'; 5 | 6 | export type DataTypeContainer = DataTypeDescriptor[]; 7 | 8 | export interface DescriptorContext { 9 | [name: string]: DataTypeDescriptor; 10 | } 11 | 12 | /** 13 | * Описание определенного типа данных. 14 | */ 15 | export interface DataTypeDescriptor { 16 | 17 | /** 18 | * Access to src schema. 19 | */ 20 | schema: Schema | SchemaGeneric; 21 | 22 | /** 23 | * Название этой модели (может быть string 24 | * или null). 25 | */ 26 | modelName?: string; 27 | 28 | /* 29 | * Предлагаемое имя для типа данных: может 30 | * применяться, если тип данных анонимный, но 31 | * необходимо вынести его за пределы родительской 32 | * модели по-ситуации (например, в случае с Enum). 33 | */ 34 | suggestedModelName?: string; 35 | 36 | /** 37 | * Путь до оригинальной схемы, на основе 38 | * которой было создано описание этого типа данных. 39 | */ 40 | originalSchemaPath?: string; 41 | 42 | /** 43 | * Родительсткие модели. 44 | */ 45 | ancestors?: DataTypeDescriptor[]; 46 | 47 | /** 48 | * Рендер типа данных в строку. 49 | * 50 | * @param childrenDependencies 51 | * Immutable-массив, в который складываются все зависимости 52 | * типов-потомков (если такие есть). 53 | * @param rootLevel 54 | * Говорит о том, что это рендер "корневого" 55 | * уровня — то есть, не в составе другого типа, 56 | * а самостоятельно. 57 | * 58 | */ 59 | render( 60 | childrenDependencies: DataTypeDescriptor[], 61 | rootLevel: boolean 62 | ): string; 63 | 64 | /** 65 | * Получение комментариев для этого дескриптора. 66 | */ 67 | getComments(): string; 68 | } 69 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api-meta-info'; 2 | export * from './config'; 3 | export * from './convertor'; 4 | export * from './data-type-descriptor'; 5 | export * from './parsing-problems'; 6 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/legacy/core/parsing-problems.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Generic as SchemaGeneric, 3 | Schema, 4 | } from '@codegena/definitions/json-schema'; 5 | import { Oas3Specification } from '@codegena/definitions/oas3'; 6 | import { 7 | DataTypeDescriptor, 8 | DescriptorContext 9 | } from './data-type-descriptor'; 10 | 11 | export interface ParsingProblemMeta { 12 | context?: DescriptorContext, 13 | descriptors?: DataTypeDescriptor | DataTypeDescriptor[], 14 | oasStructure?: Oas3Specification, 15 | schema?: Schema | SchemaGeneric, 16 | /** 17 | * Path of place in {@link oasStructure} was in parsing when the error occurred. 18 | * Using format [RFC-6901](https://tools.ietf.org/html/rfc6901). 19 | */ 20 | jsonPath?: string, 21 | /** 22 | * JSON Schema `$ref` was trying to parse or related with parsed descriptor 23 | * in moment when error occurred. 24 | */ 25 | relatedRef?: string, 26 | originalError?: any 27 | } 28 | 29 | export class ParsingProblems { 30 | public static throwErrorOnWarning = false; 31 | public static onWarnings: ( 32 | message: string, 33 | meta?: ParsingProblemMeta 34 | ) => void; 35 | 36 | public static parsingWarning( 37 | message: string, 38 | meta?: ParsingProblemMeta 39 | ): void { 40 | if (this.throwErrorOnWarning) { 41 | throw new ParsingError(message, meta); 42 | } 43 | 44 | if (this.onWarnings) { 45 | this.onWarnings(message, meta); 46 | } 47 | 48 | console.warn( 49 | `WARNING: ${message}\n${ 50 | (meta && meta.jsonPath) 51 | ? `JSON Path of problem place: ${meta.jsonPath}` 52 | : 'No json path attached.' 53 | }` 54 | ); 55 | } 56 | } 57 | 58 | export class ParsingError implements Error { 59 | public readonly stack: string; 60 | public readonly name = 'OAS3 Parsing Error'; 61 | 62 | constructor( 63 | public readonly message: string, 64 | public readonly meta?: ParsingProblemMeta 65 | ) {} 66 | } 67 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/stubs/dummy-file-saving-strategy.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "typescript"; 2 | import { join, parse, relative } from 'path'; 3 | import { kebabCase } from 'lodash'; 4 | // tslint:disable:no-implicit-dependencies 5 | import { 6 | FileSavingStrategy, 7 | } from '@codegena/oapi3ts/contract'; 8 | // tslint:enable:no-implicit-dependencies 9 | 10 | export class DummyFileSavingStrategy implements FileSavingStrategy { 11 | private _committedFiles: Record = {}; 12 | 13 | getDependencyFullPath(modelName: string, operationName: string): string { 14 | return join( 15 | '/', 16 | kebabCase(operationName), 17 | `${kebabCase(modelName)}.ts`, 18 | ); 19 | } 20 | 21 | getCommonDependencyFullPath(modelName: string): string { 22 | return join( 23 | '/', 24 | 'common', 25 | `${kebabCase(modelName)}.ts`, 26 | ); 27 | } 28 | 29 | getRelativePath(from: string, to: string): string { 30 | const { base, dir } = parse(to); 31 | const fromDir = parse(from).dir; 32 | const path = join(relative(fromDir, dir), base); 33 | 34 | return /^\./.test(path) ? path : `./${path}`; 35 | } 36 | 37 | commit(source: SourceFile): void { 38 | this._committedFiles[source.fileName] = source; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/utils/extract-common-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { flatten, intersectionBy } from 'lodash'; 2 | // tslint:disable:no-implicit-dependencies 3 | import { Dependency, DependencyCollection } from '@codegena/oapi3ts/contract'; 4 | // tslint:enable:no-implicit-dependencies 5 | import { uniqDependencies } from './uniq-dependencies'; 6 | 7 | /** 8 | * Mutates arrays! 9 | */ 10 | export function extractCommonDependencies( 11 | ...dependencySets: Dependency[][] 12 | ): DependencyCollection { 13 | const allIntersections = []; 14 | let allDependencies; 15 | 16 | if (dependencySets.length === 1) { 17 | [allDependencies] = dependencySets; 18 | 19 | return { 20 | allDependencies, 21 | commonDependencies: allDependencies, 22 | }; 23 | } 24 | 25 | for (let i = 0; i < dependencySets.length - 1; i++) { 26 | for (let ii = i + 1; ii < dependencySets.length; ii++) { 27 | const firstSet = dependencySets[i]; 28 | const secondSet = dependencySets[ii]; 29 | 30 | const intersections = intersectionBy( 31 | firstSet, 32 | secondSet, 33 | dependency => dependency.source.fileName, 34 | ); 35 | 36 | if (intersections.length) { 37 | allIntersections.push(...intersections); 38 | intersections.forEach(intersection => { 39 | replaceDependencyBy(firstSet, intersection); 40 | replaceDependencyBy(secondSet, intersection); 41 | }); 42 | } 43 | } 44 | } 45 | 46 | const commonDependencies = uniqDependencies(allIntersections); 47 | allDependencies = uniqDependencies(flatten(dependencySets)); 48 | 49 | return { 50 | allDependencies, 51 | commonDependencies, 52 | }; 53 | } 54 | 55 | /** 56 | * mutates array 57 | */ 58 | function replaceDependencyBy(collection: Dependency[], claimToBeSame: Dependency): void { 59 | const foundIndex = collection.findIndex( 60 | item => item.source.text === claimToBeSame.source.text, 61 | ); 62 | 63 | if (foundIndex !== -1) { 64 | collection[foundIndex] = claimToBeSame; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './extract-common-dependencies'; 2 | export * from './uniq-dependencies'; 3 | -------------------------------------------------------------------------------- /libs/oapi3ts/src/utils/uniq-dependencies.ts: -------------------------------------------------------------------------------- 1 | import { uniqBy } from 'lodash'; 2 | // tslint:disable:no-implicit-dependencies 3 | import { Dependency } from '@codegena/oapi3ts/contract'; 4 | // tslint:enable:no-implicit-dependencies 5 | 6 | export function uniqDependencies(dependencies: Dependency[]): Dependency[] { 7 | return uniqBy(dependencies, dependency => dependency.source.text); 8 | } 9 | -------------------------------------------------------------------------------- /libs/oapi3ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "esModuleInterop": true, 5 | "lib": ["dom", "es2018"], 6 | "types": ["node", "lodash", "jest"], 7 | "typeRoots": ["node_modules/@types", "../../node_modules/@types"] 8 | }, 9 | "extends": "../../tsconfig.base.json" 10 | } 11 | -------------------------------------------------------------------------------- /libs/oapi3ts/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true 8 | }, 9 | "exclude": ["node_modules", "src/test-setup.ts", "**/*.spec.ts"], 10 | "angularCompilerOptions": { 11 | "enableIvy": false 12 | }, 13 | "include": ["**/*.ts"] 14 | } 15 | -------------------------------------------------------------------------------- /libs/oapi3ts/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": ["**/*.spec.ts", "**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /libs/oapi3ts/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "component-selector": [true, "element", "codegena", "kebab-case"], 5 | "directive-selector": [true, "attribute", "codegena", "camelCase"], 6 | "deprecation": false, 7 | "no-implicit-dependencies": [true, "dev", "optional"] 8 | }, 9 | "linterOptions": { 10 | "exclude": ["!**/*", "!**/*"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /libs/schematics-example/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [1.0.0-alpha.7](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.6...@codegena/schematics-example@1.0.0-alpha.7) (2022-05-11) 7 | 8 | **Note:** Version bump only for package @codegena/schematics-example 9 | 10 | 11 | 12 | 13 | 14 | # [1.0.0-alpha.6](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.5...@codegena/schematics-example@1.0.0-alpha.6) (2021-06-20) 15 | 16 | **Note:** Version bump only for package @codegena/schematics-example 17 | 18 | 19 | 20 | 21 | 22 | # [1.0.0-alpha.5](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.4...@codegena/schematics-example@1.0.0-alpha.5) (2021-06-13) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * **schematics-example:** add export of created ng-module to generated `index.ts` file ([f02e30b](https://github.com/koshevy/codegena/commit/f02e30b8c51e81d49dd9711e8421083e22cdc9fe)) 28 | 29 | 30 | 31 | 32 | 33 | # [1.0.0-alpha.4](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.3...@codegena/schematics-example@1.0.0-alpha.4) (2021-06-13) 34 | 35 | 36 | ### Features 37 | 38 | * **schematics-example:** domain schema will be created with a secondary entrypoint ([a81f516](https://github.com/koshevy/codegena/commit/a81f516895826022b1f696e1d109b9af011ee14f)) 39 | 40 | 41 | 42 | 43 | 44 | # [1.0.0-alpha.3](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.2...@codegena/schematics-example@1.0.0-alpha.3) (2021-06-10) 45 | 46 | 47 | ### Features 48 | 49 | * add `createSubdir` option for ng g `@codegena/schematics-example:backend-services` schematic ([acfa6e3](https://github.com/koshevy/codegena/commit/acfa6e32115967631e01fb24798ac5aa4a5ab85b)) 50 | 51 | 52 | 53 | 54 | 55 | # [1.0.0-alpha.2](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.1...@codegena/schematics-example@1.0.0-alpha.2) (2021-06-10) 56 | 57 | **Note:** Version bump only for package @codegena/schematics-example 58 | 59 | 60 | 61 | 62 | 63 | # [1.0.0-alpha.1](https://github.com/koshevy/codegena/compare/@codegena/schematics-example@1.0.0-alpha.0...@codegena/schematics-example@1.0.0-alpha.1) (2021-06-09) 64 | 65 | 66 | ### Features 67 | 68 | * remove unused npm dependencies ([01b8090](https://github.com/koshevy/codegena/commit/01b8090273656e65d8dcb7d861356aa16279b3bc)) 69 | 70 | 71 | 72 | 73 | 74 | # 1.0.0-alpha.0 (2021-06-09) 75 | 76 | 77 | ### Features 78 | 79 | * **schematics-example:** add actual example of using oapi3ts in schematics ([39c13e1](https://github.com/koshevy/codegena/commit/39c13e1c9f0e5c13361a75e56e1ba6e2562fa882)) 80 | * **schematics-example:** support server variables and environments in `@codegena/ng-http-tools` ([93f196c](https://github.com/koshevy/codegena/commit/93f196c174f1b2cec14212b91e044d49b5f6adc8)) 81 | 82 | 83 | ### BREAKING CHANGES 84 | 85 | * **schematics-example:** now used support of `Oas3Server` in `@codegena/oapi3ts` 86 | * **schematics-example:** now used support of `Oas3Server` in `@codegena/ng-http-tools` 87 | -------------------------------------------------------------------------------- /libs/schematics-example/README.md: -------------------------------------------------------------------------------- 1 | # schematics-example 2 | 3 | ## Development 4 | 5 | How to build and use schematic: 6 | 7 | **Step 1:** Build `schematics-example` library (from repo root): 8 | ``` 9 | nx build schematics-example --with-deps 10 | ``` 11 | 12 | **Step 2:** Build schematic of `schematics-example` library (from repo root): 13 | ``` 14 | npm run --prefix libs/schematics-example build 15 | ``` 16 | 17 | **Step 3:** Link just created schematic and buit deps (from repo root): 18 | ``` 19 | npm run --prefix libs/schematics-example link:libs:built 20 | ``` 21 | 22 | **Step 4:** Use schematic as if it was already in `node_modules`. 23 | 24 | ## Using schematic 25 | 26 | ``` 27 | ng g @codegena/schematics-example:backend-services 28 | ``` 29 | 30 | ## Revert workspace 31 | 32 | After developing of schematics revert correct workspace: 33 | 34 | ``` 35 | npm i 36 | ``` 37 | 38 | ## Complete example 39 | 40 | Run command from repository root: 41 | 42 | ``` 43 | npm run todo-app-contract:update 44 | ``` 45 | -------------------------------------------------------------------------------- /libs/schematics-example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | setupFilesAfterEnv: ['/src/test-setup.ts'], 4 | globals: { 5 | 'ts-jest': { 6 | stringifyContentPathRegex: '\\.(html|svg)$', 7 | astTransformers: { 8 | before: [ 9 | 'jest-preset-angular/build/InlineFilesTransformer', 10 | 'jest-preset-angular/build/StripStylesTransformer', 11 | ], 12 | }, 13 | tsconfig: '/tsconfig.spec.json', 14 | }, 15 | }, 16 | coverageDirectory: '../../coverage/libs/schematics-example', 17 | 18 | displayName: 'schematics-example', 19 | snapshotSerializers: [ 20 | 'jest-preset-angular/build/serializers/no-ng-attributes', 21 | 'jest-preset-angular/build/serializers/ng-snapshot', 22 | 'jest-preset-angular/build/serializers/html-comment', 23 | ], 24 | }; 25 | -------------------------------------------------------------------------------- /libs/schematics-example/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/schematics-example", 4 | "lib": { 5 | "entryFile": "src/index.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "@codegena/definitions", 9 | "@codegena/ng-http-tools", 10 | "@codegena/oapi3ts", 11 | "@codegena/schematics-tools", 12 | "fs-extra", 13 | "nanoid" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /libs/schematics-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/schematics-example", 3 | "version": "1.0.0-alpha.7", 4 | "description": "Examples of using oapi3ts in schematics", 5 | "author": "koshevy@gmail.com", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/koshevy/codegena.git" 9 | }, 10 | "license": "MIT", 11 | "dependencies": { 12 | "@codegena/definitions": "0.1.0-alpha.3", 13 | "@codegena/ng-http-tools": "1.0.0-alpha.4", 14 | "@codegena/oapi3ts": "3.0.0-alpha.4", 15 | "@codegena/schematics-tools": "0.1.0-alpha.4", 16 | "fs-extra": ">= 4", 17 | "nanoid": "^3.1.16" 18 | }, 19 | "peerDependencies": { 20 | "@angular-devkit/core": ">=8", 21 | "@angular-devkit/schematics": ">=8", 22 | "@angular/common": ">= 8", 23 | "@angular/core": ">= 8", 24 | "lodash": ">= 4", 25 | "rxjs": ">= 6", 26 | "typescript": ">= 3.9.0" 27 | }, 28 | "devDependencies": { 29 | "copyfiles": ">= 2", 30 | "faker": "^5.1.0", 31 | "jest-preset-angular": "^8.3.1" 32 | }, 33 | "scripts": { 34 | "build": "../../node_modules/.bin/tsc -p tsconfig.schematics.json", 35 | "copy:schemas": "copyfiles schematics/**/schema.json ../../dist/schematics-example", 36 | "copy:files": "copyfiles schematics/**/files/** ../../dist/schematics-example", 37 | "copy:collection": "cp schematics/collection.json ../../dist/schematics-example/schematics/collection.json", 38 | "postbuild": "npm run copy:schemas && npm run copy:files && npm run copy:collection", 39 | "link:definitions:built": "rm -rf ../../node_modules/@codegena/definitions && mkdir -p ../../node_modules/@codegena && ln -sf $(pwd)/../../dist/definitions ../../node_modules/@codegena/definitions", 40 | "link:oapi3ts:built": "rm -rf ../../node_modules/@codegena/oapi3ts && mkdir -p ../../node_modules/@codegena && ln -sf $(pwd)/../../dist/oapi3ts ../../node_modules/@codegena/oapi3ts", 41 | "link:schematics-tools:built": "rm -rf ../../node_modules/@codegena/schematics-tools && mkdir -p ../../node_modules/@codegena && ln -sf $(pwd)/../../dist/schematics-tools ../../node_modules/@codegena/schematics-tools", 42 | "link:schematics-example:built": "rm -rf ../../node_modules/@codegena/schematics-example && mkdir -p ../../node_modules/@codegena && ln -sf $(pwd)/../../dist/schematics-example ../../node_modules/@codegena/schematics-example", 43 | "link:libs:built": "npm run link:definitions:built && npm run link:oapi3ts:built && npm run link:schematics-tools:built && npm run link:schematics-example:built" 44 | }, 45 | "schematics": "./schematics/collection.json" 46 | } 47 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/files/__moduleName@dasherize__.module.ts.template: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgHttpToolsModule } from '@codegena/ng-http-tools'; 4 | // Backend services 5 | <%= 6 | operationIds.map(operationId => 7 | `import { ${classify(operationId)}BackendService } from './${dasherize(operationId)}/${dasherize(operationId)}-backend.service';` 8 | ).join('\n') 9 | %> 10 | 11 | @NgModule({ 12 | imports: [ 13 | CommonModule, 14 | NgHttpToolsModule, 15 | ], 16 | providers: [ 17 | <%= operationIds.map(operationId => `${classify(operationId)}BackendService`).join(',\n') %> 18 | ], 19 | }) 20 | export class <%= classify(moduleName) %>Module {} 21 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/files/__operationId@dasherize__-backend.service.ts.template: -------------------------------------------------------------------------------- 1 | import { from, Observable } from "rxjs"; 2 | import { Injectable } from '@angular/core'; 3 | import { HasContentType, HasResponses } from '@codegena/definitions/aspects'; 4 | import { Schema as JsonSchema } from '@codegena/definitions/json-schema'; 5 | import { Oas3Server } from '@codegena/definitions/oas3'; 6 | import { EntrypointAbstract, HttpMethod } from '@codegena/ng-http-tools'; 7 | <% if (parametersModelName) { %> 8 | import { <%= parametersModelName %> } from './<%= dasherize(parametersModelName) %>';<% 9 | } %><% 10 | if (requestBodyModelName) {%> 11 | import { <%= requestBodyModelName %> } from './<%= dasherize(requestBodyModelName) %>';<% 12 | } %><% 13 | if (responseModelName) { %> 14 | import { <%= responseModelName %> } from './<%= dasherize(responseModelName) %>';<% 15 | } %> 16 | 17 | @Injectable() 18 | export class <%= classify(operationId) %>BackendService extends EntrypointAbstract< 19 | <%= JSON.stringify(method) %>, 20 | <%= parametersModelName || 'never' %>, 21 | <%= requestBodyModelName || 'never' %>, 22 | <%= responseModelName || 'never' %> 23 | > { 24 | protected getMethod(): HttpMethod { 25 | return <%= JSON.stringify(method) %>; 26 | } 27 | 28 | protected getPathTemplate(): string { 29 | return <%= JSON.stringify(pathTemplate) %>; 30 | } 31 | 32 | protected getQueryParameters(): string[] { 33 | return <%= JSON.stringify(queryParameters) %>; 34 | } 35 | 36 | protected getServers(): Oas3Server[] { 37 | return <%= JSON.stringify(servers) %>; 38 | } 39 | 40 | protected getDomainSchema(): Observable { 41 | return from( 42 | import('<%= libraryName %>/domain-schema').then(({domainSchema}) => domainSchema), 43 | ); 44 | } 45 | 46 | protected getRequestBodySchema(): HasContentType | null { 47 | return <%= serializeSchema(requestBodySchema, [operationId, 'request'].join('_')) %>; 48 | } 49 | 50 | protected getParametersSchema(): JsonSchema | null { 51 | return <%= serializeSchema(parametersSchema, [operationId, 'parameters'].join('_'), true) %>; 52 | } 53 | 54 | protected getResponseValidationSchema(): HasResponses> | null { 55 | return <%= serializeSchema(responseSchema, [operationId, 'response'].join('_')) %>; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/files/index.ts.template: -------------------------------------------------------------------------------- 1 | // Backend Services 2 | <%= 3 | operationIds.map(operationId => 4 | `export * from './${dasherize(operationId)}/${dasherize(operationId)}-backend.service';` 5 | ).join('\n') 6 | %> 7 | // Typings 8 | <%= typingFiles.map(typingFile => `export * from '.${typingFile.replace(/\.ts$/, '')}';`).join('\n') %> 9 | 10 | export * from './<%= dasherize(moduleName) %>.module'; 11 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "id": "SchematicsBackendServices", 4 | "title": "Schema for argument of BackendServices schematics", 5 | "type": "object", 6 | "properties": { 7 | "uri": { 8 | "x-prompt": "URL of path (with `file://` protocol) to your OpenAPI source file", 9 | "type": "string" 10 | }, 11 | "domain": { 12 | "x-prompt": "Business-domain (i.e. `shop`)", 13 | "description": "Business-domain using as a name of grouping directory and Ng-module", 14 | "type": "string" 15 | }, 16 | "project": { 17 | "x-prompt": "Name of project in Angular workspace", 18 | "type": "string" 19 | }, 20 | "secondaryEntrypoint": { 21 | "x-prompt": "Secondary entrypoint in a project directory (only for libraries!)", 22 | "type": "string" 23 | }, 24 | "createSubdir": { 25 | "x-prompt": "Whether should schematic create subdirectory (with `domain` name)", 26 | "type": "boolean" 27 | }, 28 | "moduleName": { 29 | "x-prompt": "Name o main module (i.e. 'shop')", 30 | "type": "string" 31 | }, 32 | "hostModule": { 33 | "x-prompt": "Path of existing Ng-module has to import generated services", 34 | "type": "string" 35 | } 36 | }, 37 | "required": [ 38 | "uri", 39 | "domain", 40 | "project" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/schema.ts: -------------------------------------------------------------------------------- 1 | import { Oas3Specification } from '@codegena/definitions/oas3'; 2 | 3 | export interface Schema { 4 | domain: string; 5 | hostModule?: string; 6 | project: string; 7 | secondaryEntrypoint?: string; 8 | uri: string; 9 | moduleName: string; 10 | createSubdir: boolean; 11 | } 12 | 13 | export interface PreparedSchema { 14 | domain: string; 15 | hostModule?: string; 16 | libraryName: string; 17 | moduleName: string; 18 | oas3Specification: Oas3Specification; 19 | path: string; 20 | projectRoot: string; 21 | } 22 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/backend-services/utilities/get-prepared-options.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | import { SchematicsException, Tree } from '@angular-devkit/schematics'; 3 | import { workspaces } from '@angular-devkit/core'; 4 | import { readJson } from 'fs-extra'; 5 | import { PreparedSchema, Schema } from '../schema'; 6 | 7 | type WorkspaceSchema = workspaces.WorkspaceDefinition; 8 | 9 | export function getPreparedOptions(tree: Tree, rawOptions: Schema): Promise { 10 | const workspaceFile = tree.read('/angular.json'); 11 | const { createSubdir, domain, hostModule, moduleName } = rawOptions; 12 | 13 | if (!workspaceFile) { 14 | throw new SchematicsException(`Can't find Angular workspace file!`); 15 | } 16 | 17 | const workspace: WorkspaceSchema = JSON.parse( 18 | workspaceFile.toString('utf-8'), 19 | ); 20 | const project = workspace.projects[rawOptions.project]; 21 | const packageJsonPath = join(project.root, 'package.json'); 22 | const packageJson = JSON.parse(tree.read(packageJsonPath)?.toString() ?? '{}'); 23 | const libraryName = packageJson?.['name'] ?? rawOptions.project; 24 | 25 | let rawPath; 26 | 27 | if (project.projectType !== 'library') { 28 | throw new SchematicsException( 29 | 'Project should be library!', 30 | ); 31 | } 32 | 33 | if (rawOptions.secondaryEntrypoint) { 34 | rawPath = join( 35 | project.root, 36 | rawOptions.secondaryEntrypoint, 37 | 'src/lib', 38 | ) 39 | } else { 40 | rawPath = join( 41 | project.sourceRoot || join(project.root, 'src'), 42 | 'lib', 43 | ); 44 | } 45 | 46 | const rootPathLength = tree.getDir('/').path.length; 47 | const path = (createSubdir ? join(rawPath, domain) : rawPath) 48 | .substr(rootPathLength ? rootPathLength - 1 : 0); 49 | 50 | return readJson(rawOptions.uri) 51 | .then(oas3Specification => ({ 52 | domain, 53 | hostModule, 54 | libraryName, 55 | moduleName, 56 | oas3Specification, 57 | path, 58 | projectRoot: project.root, 59 | })); 60 | } 61 | -------------------------------------------------------------------------------- /libs/schematics-example/schematics/collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", 3 | "schematics": { 4 | "backend-services": { 5 | "description": "Example of schematic for backend service", 6 | "factory": "./backend-services/index#backendServices", 7 | "schema": "./backend-services/schema.json" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/schematics-example/src/index.ts: -------------------------------------------------------------------------------- 1 | export const _default = {}; 2 | -------------------------------------------------------------------------------- /libs/schematics-example/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/schematics-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json" 3 | } 4 | -------------------------------------------------------------------------------- /libs/schematics-example/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true 8 | }, 9 | "angularCompilerOptions": { 10 | "enableIvy": false 11 | }, 12 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"], 13 | "include": ["**/*.ts"] 14 | } 15 | -------------------------------------------------------------------------------- /libs/schematics-example/tsconfig.schematics.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "outDir": "../../dist/schematics-example/schematics", 8 | "rootDir": "schematics", 9 | "strictNullChecks": true 10 | }, 11 | "include": [ 12 | "schematics/**/*" 13 | ], 14 | "exclude": [ 15 | "schematics/*/files/**/*" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /libs/schematics-example/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/schematics-example/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [true, "attribute", "codegena", "camelCase"], 5 | "component-selector": [true, "element", "codegena", "kebab-case"] 6 | }, 7 | "linterOptions": { 8 | "exclude": ["!**/*"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/schematics-tools/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [0.1.0-alpha.4](https://github.com/koshevy/codegena/compare/@codegena/schematics-tools@0.1.0-alpha.3...@codegena/schematics-tools@0.1.0-alpha.4) (2022-05-11) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * throws error when object schema has required, but without properties ([fa33f2c](https://github.com/koshevy/codegena/commit/fa33f2c5d2d594cfd5e44f4e98dc35e8db5375f5)), closes [#71](https://github.com/koshevy/codegena/issues/71) 12 | 13 | 14 | 15 | 16 | 17 | # 0.1.0-alpha.3 (2021-06-20) 18 | 19 | **Note:** Version bump only for package @codegena/schematics-tools 20 | 21 | 22 | 23 | 24 | 25 | # 0.1.0-alpha.2 (2021-06-13) 26 | 27 | **Note:** Version bump only for package @codegena/schematics-tools 28 | 29 | 30 | 31 | 32 | 33 | # [0.1.0-alpha.1](https://github.com/koshevy/codegena/compare/@codegena/schematics-tools@0.1.0-alpha.0...@codegena/schematics-tools@0.1.0-alpha.1) (2021-06-09) 34 | 35 | 36 | ### Features 37 | 38 | * remove unused npm dependencies ([01b8090](https://github.com/koshevy/codegena/commit/01b8090273656e65d8dcb7d861356aa16279b3bc)) 39 | 40 | 41 | 42 | 43 | 44 | # 0.1.0-alpha.0 (2021-06-09) 45 | 46 | 47 | ### Features 48 | 49 | * **schematics-tools:** provide new SchematicHostSavingStrategy ([8a19ec5](https://github.com/koshevy/codegena/commit/8a19ec5afd575bed08d46b340d8aa7fb117e01c1)) 50 | -------------------------------------------------------------------------------- /libs/schematics-tools/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | setupFilesAfterEnv: ['/src/test-setup.ts'], 4 | globals: { 5 | 'ts-jest': { 6 | stringifyContentPathRegex: '\\.(html|svg)$', 7 | astTransformers: { 8 | before: [ 9 | 'jest-preset-angular/build/InlineFilesTransformer', 10 | 'jest-preset-angular/build/StripStylesTransformer', 11 | ], 12 | }, 13 | tsconfig: '/tsconfig.spec.json', 14 | }, 15 | }, 16 | coverageDirectory: '../../coverage/libs/schematics-example', 17 | 18 | displayName: 'schematics-example', 19 | snapshotSerializers: [ 20 | 'jest-preset-angular/build/serializers/no-ng-attributes', 21 | 'jest-preset-angular/build/serializers/ng-snapshot', 22 | 'jest-preset-angular/build/serializers/html-comment', 23 | ], 24 | }; 25 | -------------------------------------------------------------------------------- /libs/schematics-tools/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/schematics-tools", 4 | "lib": { 5 | "entryFile": "src/index.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "@codegena/definitions", 9 | "@codegena/oapi3ts", 10 | "fs-extra" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /libs/schematics-tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/schematics-tools", 3 | "version": "0.1.0-alpha.4", 4 | "description": "Examples of using oapi3ts in schematics", 5 | "author": "koshevy@gmail.com", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/koshevy/codegena.git" 9 | }, 10 | "license": "MIT", 11 | "dependencies": { 12 | "@codegena/definitions": "0.1.0-alpha.3", 13 | "@codegena/oapi3ts": "3.0.0-alpha.4", 14 | "fs-extra": ">= 4" 15 | }, 16 | "peerDependencies": { 17 | "@angular-devkit/schematics": ">= 8, < 13", 18 | "@angular/common": ">= 8, < 13", 19 | "lodash": ">= 4", 20 | "rxjs": ">= 6", 21 | "typescript": ">= 3.9.0" 22 | }, 23 | "devDependencies": { 24 | "jest-preset-angular": "^8.3.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libs/schematics-tools/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/schematic-host-saving.strategy'; 2 | -------------------------------------------------------------------------------- /libs/schematics-tools/src/lib/schematic-host-saving.strategy.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from 'typescript'; 2 | import { join, parse, relative } from 'path'; 3 | import { kebabCase, trim } from 'lodash'; 4 | import { DirEntry, SchematicsException, Tree } from '@angular-devkit/schematics'; 5 | import { FileSavingStrategy } from '@codegena/oapi3ts/contract'; 6 | 7 | export class SchematicHostSavingStrategy implements FileSavingStrategy { 8 | private targetDirectory: DirEntry; 9 | 10 | constructor(private tree: Tree, targetDirectoryPath: string) { 11 | this.targetDirectory = tree.getDir(targetDirectoryPath); 12 | 13 | if (!this.targetDirectory) { 14 | tree.create(join(targetDirectoryPath, '.gitkeep'), ''); 15 | this.targetDirectory = tree.getDir(targetDirectoryPath); 16 | 17 | if (!this.targetDirectory) { 18 | throw new SchematicsException( 19 | `Can't resolve working directory: ${targetDirectoryPath}!`, 20 | ); 21 | } 22 | } 23 | } 24 | 25 | getDependencyFullPath(modelName: string, operationName: string): string { 26 | return join( 27 | '/', 28 | kebabCase(operationName), 29 | `${kebabCase(modelName)}.ts`, 30 | ); 31 | } 32 | 33 | getCommonDependencyFullPath(modelName: string): string { 34 | return join( 35 | '/', 36 | 'common', 37 | `${kebabCase(modelName)}.ts`, 38 | ); 39 | } 40 | 41 | getRelativePath(from: string, to: string): string { 42 | const { base, dir } = parse(to); 43 | const fromDir = parse(from).dir; 44 | const path = join(relative(fromDir, dir), base); 45 | 46 | return /^\./.test(path) ? path : `./${path}`; 47 | } 48 | 49 | commit(source: SourceFile): void { 50 | const pathInTree = join( 51 | this.targetDirectory.path, 52 | trim(source.fileName, '/'), 53 | ); 54 | this.tree.create(pathInTree, source.text); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /libs/schematics-tools/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/schematics-tools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json" 3 | } 4 | -------------------------------------------------------------------------------- /libs/schematics-tools/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true 8 | }, 9 | "angularCompilerOptions": { 10 | "enableIvy": false 11 | }, 12 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"], 13 | "include": ["**/*.ts"] 14 | } 15 | -------------------------------------------------------------------------------- /libs/schematics-tools/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/schematics-tools/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [true, "attribute", "codegena", "camelCase"], 5 | "component-selector": [true, "element", "codegena", "kebab-case"] 6 | }, 7 | "linterOptions": { 8 | "exclude": ["!**/*"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [0.1.0-alpha.5](https://github.com/koshevy/codegena/compare/@codegena/todo-app-contract@0.1.0-alpha.4...@codegena/todo-app-contract@0.1.0-alpha.5) (2021-06-20) 7 | 8 | **Note:** Version bump only for package @codegena/todo-app-contract 9 | 10 | 11 | 12 | 13 | 14 | # [0.1.0-alpha.4](https://github.com/koshevy/codegena/compare/@codegena/todo-app-contract@0.1.0-alpha.3...@codegena/todo-app-contract@0.1.0-alpha.4) (2021-06-13) 15 | 16 | **Note:** Version bump only for package @codegena/todo-app-contract 17 | 18 | 19 | 20 | 21 | 22 | # 0.1.0-alpha.3 (2021-06-13) 23 | 24 | **Note:** Version bump only for package @codegena/todo-app-contract 25 | 26 | 27 | 28 | 29 | 30 | # [0.1.0-alpha.2](https://github.com/koshevy/codegena/compare/@codegena/todo-app-contract@0.1.0-alpha.1...@codegena/todo-app-contract@0.1.0-alpha.2) (2021-06-10) 31 | 32 | **Note:** Version bump only for package @codegena/todo-app-contract 33 | 34 | 35 | 36 | 37 | 38 | # [0.1.0-alpha.1](https://github.com/koshevy/codegena/compare/@codegena/todo-app-contract@0.1.0-alpha.0...@codegena/todo-app-contract@0.1.0-alpha.1) (2021-06-09) 39 | 40 | **Note:** Version bump only for package @codegena/todo-app-contract 41 | 42 | 43 | 44 | 45 | 46 | # 0.1.0-alpha.0 (2021-06-09) 47 | 48 | 49 | ### Features 50 | 51 | * **todo-app-contract:** demo with server variables support ([a6ec64e](https://github.com/koshevy/codegena/commit/a6ec64eb7d4cafaadece9cb8f2ba544a300b1cab)) 52 | -------------------------------------------------------------------------------- /libs/todo-app-contract/domain-schema/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib": { 3 | "entryFile": "src/index.ts" 4 | } 5 | } -------------------------------------------------------------------------------- /libs/todo-app-contract/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'todo-app-contract', 3 | preset: '../../jest.preset.js', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | stringifyContentPathRegex: '\\.(html|svg)$', 8 | astTransformers: { 9 | before: [ 10 | 'jest-preset-angular/build/InlineFilesTransformer', 11 | 'jest-preset-angular/build/StripStylesTransformer', 12 | ], 13 | }, 14 | tsconfig: '/tsconfig.spec.json', 15 | }, 16 | }, 17 | coverageDirectory: '../../coverage/libs/todo-app-contract', 18 | snapshotSerializers: [ 19 | 'jest-preset-angular/build/serializers/no-ng-attributes', 20 | 'jest-preset-angular/build/serializers/ng-snapshot', 21 | 'jest-preset-angular/build/serializers/html-comment', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /libs/todo-app-contract/jest.config.prod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'todo-app-contract', 3 | preset: '../../jest.preset.js', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | stringifyContentPathRegex: '\\.(html|svg)$', 8 | astTransformers: { 9 | before: [ 10 | 'jest-preset-angular/build/InlineFilesTransformer', 11 | 'jest-preset-angular/build/StripStylesTransformer', 12 | ], 13 | }, 14 | tsconfig: '/tsconfig.spec.prod.json', 15 | }, 16 | }, 17 | coverageDirectory: '../../coverage/libs/todo-app-contract', 18 | snapshotSerializers: [ 19 | 'jest-preset-angular/build/serializers/no-ng-attributes', 20 | 'jest-preset-angular/build/serializers/ng-snapshot', 21 | 'jest-preset-angular/build/serializers/html-comment', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /libs/todo-app-contract/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/todo-app-contract", 4 | "lib": { 5 | "entryFile": "src/index.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "@codegena/definitions", 9 | "@codegena/ng-http-tools" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codegena/todo-app-contract", 3 | "private": true, 4 | "version": "0.1.0-alpha.5", 5 | "peerDependencies": { 6 | "@angular/common": ">=8", 7 | "@angular/core": ">=8", 8 | "rxjs": ">=6" 9 | }, 10 | "dependencies": { 11 | "@codegena/definitions": "0.1.0-alpha.3", 12 | "@codegena/ng-http-tools": "1.0.0-alpha.4", 13 | "tslib": "^2.0.0" 14 | }, 15 | "devDependencies": { 16 | "@types/faker": "5.1.0", 17 | "faker": "^5.1.0", 18 | "jest-preset-angular": "^8.3.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/todo-app/todo-app.module'; 2 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/attachment-meta-document.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Meta data of document attached to task 3 | */ 4 | export interface AttachmentMetaDocument { 5 | /** 6 | * An unique id of document. Metadata with unique get from server in return of 7 | * uploaded image file. 8 | */ 9 | docId: string; 10 | /** 11 | * Marks attachment as an document 12 | */ 13 | type: 'document'; 14 | /** 15 | * Url of uploaded document 16 | */ 17 | url: string; 18 | /** 19 | * Format of document 20 | */ 21 | format: 'doc' | 'docx' | 'pdf' | 'rtf' | 'xls' | 'xlsx' | 'txt'; 22 | /** 23 | * File size 24 | */ 25 | size: number; 26 | } 27 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/attachment-meta-image.ts: -------------------------------------------------------------------------------- 1 | import { ImageOptions } from './image-options'; 2 | 3 | /** 4 | * Meta data of image attached to task 5 | */ 6 | export interface AttachmentMetaImage { 7 | /** 8 | * An unique id of media. Metadata with unique get from server in return of 9 | * uploaded image file. 10 | */ 11 | mediaId: string; 12 | /** 13 | * Marks attachment as an image 14 | */ 15 | type: 'image'; 16 | /** 17 | * Url of uploaded image 18 | */ 19 | url: string; 20 | /** 21 | * Possible thumbnails of uploaded image 22 | */ 23 | thumbs?: { 24 | [key: string]: null | { 25 | /** 26 | * Url of cached thumb 27 | */ 28 | url?: string; 29 | /** 30 | * Information of image 31 | */ 32 | imageOptions?: null | ImageOptions; 33 | }; 34 | }; 35 | /** 36 | * Format of uploaded image 37 | */ 38 | format: 'png' | 'jpeg' | 'gif' | 'svg' | 'tiff'; 39 | /** 40 | * Url of cached thumb 41 | */ 42 | imageOptions: ImageOptions; 43 | } 44 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/http-error-bad-request.ts: -------------------------------------------------------------------------------- 1 | import { JsonError } from './json-error'; 2 | 3 | export interface HttpErrorBadRequest { 4 | message: string; 5 | type?: 'syntax' | 'semantic'; 6 | errors?: Array; 7 | } 8 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/http-error-conflict.ts: -------------------------------------------------------------------------------- 1 | export interface HttpErrorConflict { 2 | message: string; 3 | } 4 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/http-error-not-found.ts: -------------------------------------------------------------------------------- 1 | export interface HttpErrorNotFound { 2 | message: string; 3 | } 4 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/http-error-server.ts: -------------------------------------------------------------------------------- 1 | export interface HttpErrorServer { 2 | description?: string; 3 | message: string; 4 | } 5 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/image-options.ts: -------------------------------------------------------------------------------- 1 | export interface ImageOptions { 2 | width: number; 3 | height: number; 4 | size: number; 5 | } 6 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/json-error.ts: -------------------------------------------------------------------------------- 1 | export interface JsonError { 2 | originalMessage: string; 3 | message?: null | string; 4 | jsonPointer: string; 5 | } 6 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/to-do-group-blank.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTaskBlank } from './to-do-task-blank'; 2 | 3 | /** 4 | * ## Base part of data of group 5 | * Data needed for group creation 6 | */ 7 | export interface ToDoGroupBlank { 8 | /** 9 | * Title of a group 10 | */ 11 | title: string; 12 | /** 13 | * Detailed description of a group in one/two sequences. 14 | */ 15 | description?: string; 16 | items?: Array; 17 | /** 18 | * Whether all tasks in group are complete 19 | */ 20 | isComplete?: boolean | null; 21 | } 22 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/to-do-group-extended-data.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from './to-do-task'; 2 | 3 | /** 4 | * ## Extended data of group 5 | * Extended data has to be obtained after first save 6 | */ 7 | export interface ToDoGroupExtendedData { 8 | /** 9 | * An unique id of task 10 | */ 11 | uid: string; 12 | /** 13 | * Date/time (ISO) when task was created 14 | */ 15 | dateCreated: string; 16 | /** 17 | * Date/time (ISO) when task was changed last time 18 | */ 19 | dateChanged: string; 20 | items: Array; 21 | } 22 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/to-do-group.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroupBlank } from './to-do-group-blank'; 2 | import { ToDoGroupExtendedData } from './to-do-group-extended-data'; 3 | 4 | export type ToDoGroup = ToDoGroupBlank & // Data needed for group creation 5 | ToDoGroupExtendedData; // Extended data has to be obtained after first save 6 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/to-do-task-blank.ts: -------------------------------------------------------------------------------- 1 | import { AttachmentMetaImage } from './attachment-meta-image'; 2 | import { AttachmentMetaDocument } from './attachment-meta-document'; 3 | 4 | /** 5 | * ## Base part of data of item in todo's group 6 | * Data about group item needed for creation of it 7 | */ 8 | export interface ToDoTaskBlank { 9 | /** 10 | * An unique id of group that item belongs to 11 | */ 12 | groupUid?: string; 13 | /** 14 | * Short brief of task to be done 15 | */ 16 | title: string; 17 | /** 18 | * Detailed description and context of the task. Allowed using of Common Markdown. 19 | */ 20 | description?: any; 21 | /** 22 | * Status of task: is done or not 23 | */ 24 | isDone: boolean; 25 | /** 26 | * Position of a task in group. Allows to track changing of state of a concrete 27 | * item, including changing od position. 28 | */ 29 | position?: null | number; 30 | /** 31 | * Any material attached to the task: may be screenshots, photos, pdf- or doc- 32 | * documents on something else 33 | */ 34 | attachments?: null | Array< 35 | | AttachmentMetaImage // Meta data of image attached to task 36 | | AttachmentMetaDocument // Meta data of document attached to task 37 | | string // Link to any external resource 38 | >; 39 | } 40 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/common/to-do-task.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTaskBlank } from './to-do-task-blank'; 2 | import { AttachmentMetaImage } from './attachment-meta-image'; 3 | import { AttachmentMetaDocument } from './attachment-meta-document'; 4 | 5 | /** 6 | * ## Item in todo's group 7 | * Describe data structure of an item in group of tasks 8 | */ 9 | export interface ToDoTask extends ToDoTaskBlank { 10 | /** 11 | * An unique id of task 12 | */ 13 | readonly uid: string; 14 | /** 15 | * Date/time (ISO) when task was created 16 | */ 17 | readonly dateCreated: string; 18 | /** 19 | * Date/time (ISO) when task was changed last time 20 | */ 21 | readonly dateChanged: string; 22 | /** 23 | * Position of a task in group. Allows to track changing of state of a concrete 24 | * item, including changing od position. 25 | */ 26 | position: null | number; 27 | /** 28 | * An unique id of group that item belongs to 29 | */ 30 | groupUid?: string; 31 | /** 32 | * Short brief of task to be done 33 | */ 34 | title: string; 35 | /** 36 | * Detailed description and context of the task. Allowed using of Common Markdown. 37 | */ 38 | description?: any; 39 | /** 40 | * Status of task: is done or not 41 | */ 42 | isDone: boolean; 43 | /** 44 | * Any material attached to the task: may be screenshots, photos, pdf- or doc- 45 | * documents on something else 46 | */ 47 | attachments?: null | Array< 48 | | AttachmentMetaImage // Meta data of image attached to task 49 | | AttachmentMetaDocument // Meta data of document attached to task 50 | | string // Link to any external resource 51 | >; 52 | } 53 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group-item/create-group-item-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}/item` 3 | */ 4 | export interface CreateGroupItemParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Force save group despite conflicts 11 | */ 12 | forceSave?: any; 13 | } 14 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group-item/create-group-item-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTaskBlank } from '../common/to-do-task-blank'; 2 | 3 | export type CreateGroupItemRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * ## Base part of data of item in todo's group 8 | * Data about group item needed for creation of it 9 | */ 10 | ToDoTaskBlank 11 | : any; 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group-item/create-group-item-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type CreateGroupItemResponse< 8 | TCode extends 201 | 400 | 404 | 409 | 500 = 201 | 400 | 404 | 409 | 500, 9 | TContentType extends 'application/json' = 'application/json' 10 | > = TCode extends 201 11 | ? TContentType extends 'application/json' 12 | ? /** 13 | * ## Item in todo's group 14 | * Describe data structure of an item in group of tasks 15 | */ 16 | ToDoTask 17 | : any 18 | : TCode extends 400 19 | ? TContentType extends 'application/json' 20 | ? HttpErrorBadRequest 21 | : any 22 | : TCode extends 404 23 | ? TContentType extends 'application/json' 24 | ? HttpErrorNotFound 25 | : any 26 | : TCode extends 409 27 | ? TContentType extends 'application/json' 28 | ? HttpErrorConflict 29 | : any 30 | : TCode extends 500 31 | ? TContentType extends 'application/json' 32 | ? HttpErrorServer 33 | : any 34 | : any; 35 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group/create-group-backend.service.ts: -------------------------------------------------------------------------------- 1 | import { from, Observable } from 'rxjs'; 2 | import { Injectable } from '@angular/core'; 3 | import { HasContentType, HasResponses } from '@codegena/definitions/aspects'; 4 | import { Schema as JsonSchema } from '@codegena/definitions/json-schema'; 5 | import { Oas3Server } from '@codegena/definitions/oas3'; 6 | import { EntrypointAbstract, HttpMethod } from '@codegena/ng-http-tools'; 7 | 8 | import { CreateGroupRequest } from './create-group-request'; 9 | import { CreateGroupResponse } from './create-group-response'; 10 | 11 | @Injectable() 12 | export class CreateGroupBackendService extends EntrypointAbstract< 13 | 'POST', 14 | never, 15 | CreateGroupRequest, 16 | CreateGroupResponse 17 | > { 18 | protected getMethod(): HttpMethod { 19 | return 'POST'; 20 | } 21 | 22 | protected getPathTemplate(): string { 23 | return '/group'; 24 | } 25 | 26 | protected getQueryParameters(): string[] { 27 | return []; 28 | } 29 | 30 | protected getServers(): Oas3Server[] { 31 | return [ 32 | { 33 | environment: 'local', 34 | description: 'Base local server', 35 | url: 'https://local.todo-codegena-example.com', 36 | }, 37 | { 38 | environment: 'dev', 39 | description: 'Development server', 40 | url: 'https://dev.todo-codegena-example.com', 41 | }, 42 | { 43 | environment: 'prod', 44 | description: 'Development server', 45 | url: 'https://todo-codegena-example.com', 46 | }, 47 | ]; 48 | } 49 | 50 | protected getDomainSchema(): Observable { 51 | return from( 52 | import('@codegena/todo-app-contract/domain-schema').then( 53 | ({ domainSchema }) => domainSchema 54 | ) 55 | ); 56 | } 57 | 58 | protected getRequestBodySchema(): HasContentType | null { 59 | return { 60 | 'application/json': { 61 | $ref: 'todo-app#/components/schemas/ToDoGroupBlank', 62 | $id: 'createGroup_request_application_json', 63 | }, 64 | }; 65 | } 66 | 67 | protected getParametersSchema(): JsonSchema | null { 68 | return { 69 | $id: 'createGroup_parameters', 70 | }; 71 | } 72 | 73 | protected getResponseValidationSchema(): HasResponses< 74 | HasContentType 75 | > | null { 76 | return { 77 | '201': { 78 | 'application/json': { 79 | $ref: 'todo-app#/components/schemas/ToDoGroup', 80 | $id: 'createGroup_response_application_json', 81 | }, 82 | }, 83 | '400': { 84 | 'application/json': { 85 | $ref: 'todo-app#/components/schemas/HttpErrorBadRequest', 86 | $id: 'createGroup_response_application_json', 87 | }, 88 | }, 89 | '500': { 90 | 'application/json': { 91 | $ref: 'todo-app#/components/schemas/HttpErrorServer', 92 | $id: 'createGroup_response_application_json', 93 | }, 94 | }, 95 | }; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group/create-group-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroupBlank } from '../common/to-do-group-blank'; 2 | 3 | export type CreateGroupRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * ## Base part of data of group 8 | * Data needed for group creation 9 | */ 10 | ToDoGroupBlank 11 | : any; 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/create-group/create-group-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroup } from '../common/to-do-group'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorServer } from '../common/http-error-server'; 4 | 5 | export type CreateGroupResponse< 6 | TCode extends 201 | 400 | 500 = 201 | 400 | 500, 7 | TContentType extends 'application/json' = 'application/json' 8 | > = TCode extends 201 9 | ? TContentType extends 'application/json' 10 | ? ToDoGroup 11 | : any 12 | : TCode extends 400 13 | ? TContentType extends 'application/json' 14 | ? HttpErrorBadRequest 15 | : any 16 | : TCode extends 500 17 | ? TContentType extends 'application/json' 18 | ? HttpErrorServer 19 | : any 20 | : any; 21 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/delete-group/delete-group-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}` 3 | */ 4 | export interface DeleteGroupParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | } 10 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/delete-group/delete-group-response.ts: -------------------------------------------------------------------------------- 1 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 2 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 3 | import { HttpErrorConflict } from '../common/http-error-conflict'; 4 | import { HttpErrorServer } from '../common/http-error-server'; 5 | 6 | export type DeleteGroupResponse< 7 | TCode extends 202 | 400 | 404 | 409 | 500 = 202 | 400 | 404 | 409 | 500, 8 | TContentType extends 'application/json' = 'application/json' 9 | > = TCode extends 202 10 | ? TContentType extends 'application/json' 11 | ? /** 12 | * Todo group deleted 13 | */ 14 | null 15 | : any 16 | : TCode extends 400 17 | ? TContentType extends 'application/json' 18 | ? HttpErrorBadRequest 19 | : any 20 | : TCode extends 404 21 | ? TContentType extends 'application/json' 22 | ? HttpErrorNotFound 23 | : any 24 | : TCode extends 409 25 | ? TContentType extends 'application/json' 26 | ? HttpErrorConflict 27 | : any 28 | : TCode extends 500 29 | ? TContentType extends 'application/json' 30 | ? HttpErrorServer 31 | : any 32 | : any; 33 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-group-items/get-group-items-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}/item` 3 | */ 4 | export interface GetGroupItemsParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Filter groups by `complete` status 11 | */ 12 | isComplete?: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-group-items/get-group-items-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorServer } from '../common/http-error-server'; 5 | 6 | export type GetGroupItemsResponse< 7 | TCode extends 200 | 400 | 404 | 500 = 200 | 400 | 404 | 500, 8 | TContentType extends 'application/json' = 'application/json' 9 | > = TCode extends 200 10 | ? TContentType extends 'application/json' 11 | ? /** 12 | * Items of specified TODO's group 13 | */ 14 | Array 15 | : any 16 | : TCode extends 400 17 | ? TContentType extends 'application/json' 18 | ? HttpErrorBadRequest 19 | : any 20 | : TCode extends 404 21 | ? TContentType extends 'application/json' 22 | ? HttpErrorNotFound 23 | : any 24 | : TCode extends 500 25 | ? TContentType extends 'application/json' 26 | ? HttpErrorServer 27 | : any 28 | : any; 29 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-group/get-group-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}` 3 | */ 4 | export interface GetGroupParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | } 10 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-group/get-group-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroup } from '../common/to-do-group'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorServer } from '../common/http-error-server'; 5 | 6 | export type GetGroupResponse< 7 | TCode extends 200 | 400 | 404 | 500 = 200 | 400 | 404 | 500, 8 | TContentType extends 'application/json' = 'application/json' 9 | > = TCode extends 200 10 | ? TContentType extends 'application/json' 11 | ? ToDoGroup 12 | : any 13 | : TCode extends 400 14 | ? TContentType extends 'application/json' 15 | ? HttpErrorBadRequest 16 | : any 17 | : TCode extends 404 18 | ? TContentType extends 'application/json' 19 | ? HttpErrorNotFound 20 | : any 21 | : TCode extends 500 22 | ? TContentType extends 'application/json' 23 | ? HttpErrorServer 24 | : any 25 | : any; 26 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-groups/get-groups-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group` 3 | */ 4 | export interface GetGroupsParameters { 5 | /** 6 | * Filter groups by `complete` status 7 | */ 8 | isComplete?: boolean; 9 | /** 10 | * Set it `true` if you want to get all group items with group. Always returns 11 | * empty `items` array when it's `false`. 12 | */ 13 | withItems?: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/get-groups/get-groups-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroup } from '../common/to-do-group'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorServer } from '../common/http-error-server'; 4 | 5 | export type GetGroupsResponse< 6 | TCode extends 200 | 400 | 500 = 200 | 400 | 500, 7 | TContentType extends 'application/json' = 'application/json' 8 | > = TCode extends 200 9 | ? TContentType extends 'application/json' 10 | ? /** 11 | * TODO's groups 12 | */ 13 | Array 14 | : any 15 | : TCode extends 400 16 | ? TContentType extends 'application/json' 17 | ? HttpErrorBadRequest 18 | : any 19 | : TCode extends 500 20 | ? TContentType extends 'application/json' 21 | ? HttpErrorServer 22 | : any 23 | : any; 24 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/index.ts: -------------------------------------------------------------------------------- 1 | // Backend Services 2 | export * from './get-groups/get-groups-backend.service'; 3 | export * from './create-group/create-group-backend.service'; 4 | export * from './delete-group/delete-group-backend.service'; 5 | export * from './get-group/get-group-backend.service'; 6 | export * from './update-group/update-group-backend.service'; 7 | export * from './rewrite-group/rewrite-group-backend.service'; 8 | export * from './get-group-items/get-group-items-backend.service'; 9 | export * from './create-group-item/create-group-item-backend.service'; 10 | export * from './update-group-item/update-group-item-backend.service'; 11 | export * from './rewrite-group-item/rewrite-group-item-backend.service'; 12 | export * from './update-few-items/update-few-items-backend.service'; 13 | // Typings 14 | export * from './common/attachment-meta-document'; 15 | export * from './common/attachment-meta-image'; 16 | export * from './common/http-error-bad-request'; 17 | export * from './common/http-error-conflict'; 18 | export * from './common/http-error-not-found'; 19 | export * from './common/http-error-server'; 20 | export * from './common/image-options'; 21 | export * from './common/json-error'; 22 | export * from './common/to-do-group-blank'; 23 | export * from './common/to-do-group-extended-data'; 24 | export * from './common/to-do-group'; 25 | export * from './common/to-do-task-blank'; 26 | export * from './common/to-do-task'; 27 | export * from './create-group-item/create-group-item-parameters'; 28 | export * from './create-group-item/create-group-item-request'; 29 | export * from './create-group-item/create-group-item-response'; 30 | export * from './create-group/create-group-request'; 31 | export * from './create-group/create-group-response'; 32 | export * from './delete-group/delete-group-parameters'; 33 | export * from './delete-group/delete-group-response'; 34 | export * from './get-group-items/get-group-items-parameters'; 35 | export * from './get-group-items/get-group-items-response'; 36 | export * from './get-group/get-group-parameters'; 37 | export * from './get-group/get-group-response'; 38 | export * from './get-groups/get-groups-parameters'; 39 | export * from './get-groups/get-groups-response'; 40 | export * from './rewrite-group-item/rewrite-group-item-parameters'; 41 | export * from './rewrite-group-item/rewrite-group-item-request'; 42 | export * from './rewrite-group-item/rewrite-group-item-response'; 43 | export * from './rewrite-group/rewrite-group-parameters'; 44 | export * from './rewrite-group/rewrite-group-request'; 45 | export * from './rewrite-group/rewrite-group-response'; 46 | export * from './update-few-items/update-few-items-parameters'; 47 | export * from './update-few-items/update-few-items-request'; 48 | export * from './update-few-items/update-few-items-response'; 49 | export * from './update-group-item/update-group-item-parameters'; 50 | export * from './update-group-item/update-group-item-request'; 51 | export * from './update-group-item/update-group-item-response'; 52 | export * from './update-group/update-group-parameters'; 53 | export * from './update-group/update-group-request'; 54 | export * from './update-group/update-group-response'; 55 | 56 | export * from './todo-app.module'; 57 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group-item/rewrite-group-item-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}/item/{itemId}` 3 | */ 4 | export interface RewriteGroupItemParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Uid of TODO group item 11 | */ 12 | itemId: string; 13 | /** 14 | * Force save group despite conflicts 15 | */ 16 | forceSave?: any; 17 | } 18 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group-item/rewrite-group-item-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTaskBlank } from '../common/to-do-task-blank'; 2 | 3 | export type RewriteGroupItemRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * ## Base part of data of item in todo's group 8 | * Data about group item needed for creation of it 9 | */ 10 | ToDoTaskBlank 11 | : any; 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group-item/rewrite-group-item-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type RewriteGroupItemResponse< 8 | TCode extends 200 | 400 | 404 | 409 | 500 = 200 | 400 | 404 | 409 | 500, 9 | TContentType extends 'application/json' = 'application/json' 10 | > = TCode extends 200 11 | ? TContentType extends 'application/json' 12 | ? /** 13 | * ## Item in todo's group 14 | * Describe data structure of an item in group of tasks 15 | */ 16 | ToDoTask 17 | : any 18 | : TCode extends 400 19 | ? TContentType extends 'application/json' 20 | ? HttpErrorBadRequest 21 | : any 22 | : TCode extends 404 23 | ? TContentType extends 'application/json' 24 | ? HttpErrorNotFound 25 | : any 26 | : TCode extends 409 27 | ? TContentType extends 'application/json' 28 | ? HttpErrorConflict 29 | : any 30 | : TCode extends 500 31 | ? TContentType extends 'application/json' 32 | ? HttpErrorServer 33 | : any 34 | : any; 35 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group/rewrite-group-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}` 3 | */ 4 | export interface RewriteGroupParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Force save group despite conflicts 11 | */ 12 | forceSave?: any; 13 | } 14 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group/rewrite-group-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroupBlank } from '../common/to-do-group-blank'; 2 | 3 | export type RewriteGroupRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * ## Base part of data of group 8 | * Data needed for group creation 9 | */ 10 | ToDoGroupBlank 11 | : any; 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/rewrite-group/rewrite-group-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroup } from '../common/to-do-group'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type RewriteGroupResponse< 8 | TCode extends 200 | 204 | 400 | 404 | 409 | 500 = 9 | | 200 10 | | 204 11 | | 400 12 | | 404 13 | | 409 14 | | 500, 15 | TContentType extends 'application/json' = 'application/json' 16 | > = TCode extends 200 17 | ? TContentType extends 'application/json' 18 | ? ToDoGroup 19 | : any 20 | : TCode extends 204 21 | ? TContentType extends 'application/json' 22 | ? /** 23 | * No changes. Should no have a response! 24 | */ 25 | null 26 | : any 27 | : TCode extends 400 28 | ? TContentType extends 'application/json' 29 | ? HttpErrorBadRequest 30 | : any 31 | : TCode extends 404 32 | ? TContentType extends 'application/json' 33 | ? HttpErrorNotFound 34 | : any 35 | : TCode extends 409 36 | ? TContentType extends 'application/json' 37 | ? HttpErrorConflict 38 | : any 39 | : TCode extends 500 40 | ? TContentType extends 'application/json' 41 | ? HttpErrorServer 42 | : any 43 | : any; 44 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/todo-app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgHttpToolsModule } from '@codegena/ng-http-tools'; 4 | // Backend services 5 | import { GetGroupsBackendService } from './get-groups/get-groups-backend.service'; 6 | import { CreateGroupBackendService } from './create-group/create-group-backend.service'; 7 | import { DeleteGroupBackendService } from './delete-group/delete-group-backend.service'; 8 | import { GetGroupBackendService } from './get-group/get-group-backend.service'; 9 | import { UpdateGroupBackendService } from './update-group/update-group-backend.service'; 10 | import { RewriteGroupBackendService } from './rewrite-group/rewrite-group-backend.service'; 11 | import { GetGroupItemsBackendService } from './get-group-items/get-group-items-backend.service'; 12 | import { CreateGroupItemBackendService } from './create-group-item/create-group-item-backend.service'; 13 | import { UpdateGroupItemBackendService } from './update-group-item/update-group-item-backend.service'; 14 | import { RewriteGroupItemBackendService } from './rewrite-group-item/rewrite-group-item-backend.service'; 15 | import { UpdateFewItemsBackendService } from './update-few-items/update-few-items-backend.service'; 16 | 17 | @NgModule({ 18 | imports: [CommonModule, NgHttpToolsModule], 19 | providers: [ 20 | GetGroupsBackendService, 21 | CreateGroupBackendService, 22 | DeleteGroupBackendService, 23 | GetGroupBackendService, 24 | UpdateGroupBackendService, 25 | RewriteGroupBackendService, 26 | GetGroupItemsBackendService, 27 | CreateGroupItemBackendService, 28 | UpdateGroupItemBackendService, 29 | RewriteGroupItemBackendService, 30 | UpdateFewItemsBackendService, 31 | ], 32 | }) 33 | export class TodoAppModule {} 34 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-few-items/update-few-items-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/items` 3 | */ 4 | export interface UpdateFewItemsParameters { 5 | /** 6 | * Force save group despite conflicts 7 | */ 8 | forceSave?: any; 9 | } 10 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-few-items/update-few-items-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | 3 | export type UpdateFewItemsRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * Collection of `ToDoTask` items. Tasks should be with UID's and should be exists. 8 | */ 9 | Array 10 | : any; 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-few-items/update-few-items-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type UpdateFewItemsResponse< 8 | TCode extends 200 | 400 | 404 | 409 | 500 = 200 | 400 | 404 | 409 | 500, 9 | TContentType extends 'application/json' = 'application/json' 10 | > = TCode extends 200 11 | ? TContentType extends 'application/json' 12 | ? /** 13 | * All items are updated 14 | */ 15 | Array 16 | : any 17 | : TCode extends 400 18 | ? TContentType extends 'application/json' 19 | ? HttpErrorBadRequest 20 | : any 21 | : TCode extends 404 22 | ? TContentType extends 'application/json' 23 | ? HttpErrorNotFound 24 | : any 25 | : TCode extends 409 26 | ? TContentType extends 'application/json' 27 | ? HttpErrorConflict 28 | : any 29 | : TCode extends 500 30 | ? TContentType extends 'application/json' 31 | ? HttpErrorServer 32 | : any 33 | : any; 34 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group-item/update-group-item-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}/item/{itemId}` 3 | */ 4 | export interface UpdateGroupItemParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Uid of TODO group item 11 | */ 12 | itemId: string; 13 | /** 14 | * Force save group despite conflicts 15 | */ 16 | forceSave?: any; 17 | } 18 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group-item/update-group-item-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTaskBlank } from '../common/to-do-task-blank'; 2 | 3 | export type UpdateGroupItemRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * ## Base part of data of item in todo's group 8 | * Data about group item needed for creation of it 9 | */ 10 | ToDoTaskBlank 11 | : any; 12 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group-item/update-group-item-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoTask } from '../common/to-do-task'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type UpdateGroupItemResponse< 8 | TCode extends 200 | 400 | 404 | 409 | 500 = 200 | 400 | 404 | 409 | 500, 9 | TContentType extends 'application/json' = 'application/json' 10 | > = TCode extends 200 11 | ? TContentType extends 'application/json' 12 | ? /** 13 | * ## Item in todo's group 14 | * Describe data structure of an item in group of tasks 15 | */ 16 | ToDoTask 17 | : any 18 | : TCode extends 400 19 | ? TContentType extends 'application/json' 20 | ? HttpErrorBadRequest 21 | : any 22 | : TCode extends 404 23 | ? TContentType extends 'application/json' 24 | ? HttpErrorNotFound 25 | : any 26 | : TCode extends 409 27 | ? TContentType extends 'application/json' 28 | ? HttpErrorConflict 29 | : any 30 | : TCode extends 500 31 | ? TContentType extends 'application/json' 32 | ? HttpErrorServer 33 | : any 34 | : any; 35 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group/update-group-parameters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Model of parameters for API `/group/{groupId}` 3 | */ 4 | export interface UpdateGroupParameters { 5 | /** 6 | * Uid of TODO group 7 | */ 8 | groupId: string; 9 | /** 10 | * Force save group despite conflicts 11 | */ 12 | forceSave?: any; 13 | } 14 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group/update-group-request.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroupBlank } from '../common/to-do-group-blank'; 2 | 3 | export type UpdateGroupRequest< 4 | TCode extends 'application/json' = 'application/json' 5 | > = TCode extends 'application/json' 6 | ? /** 7 | * Required request body 8 | */ 9 | ToDoGroupBlank // Data needed for group creation 10 | : any; 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/lib/todo-app/update-group/update-group-response.ts: -------------------------------------------------------------------------------- 1 | import { ToDoGroup } from '../common/to-do-group'; 2 | import { HttpErrorBadRequest } from '../common/http-error-bad-request'; 3 | import { HttpErrorNotFound } from '../common/http-error-not-found'; 4 | import { HttpErrorConflict } from '../common/http-error-conflict'; 5 | import { HttpErrorServer } from '../common/http-error-server'; 6 | 7 | export type UpdateGroupResponse< 8 | TCode extends 200 | 400 | 404 | 409 | 500 = 200 | 400 | 404 | 409 | 500, 9 | TContentType extends 'application/json' = 'application/json' 10 | > = TCode extends 200 11 | ? TContentType extends 'application/json' 12 | ? ToDoGroup 13 | : any 14 | : TCode extends 400 15 | ? TContentType extends 'application/json' 16 | ? HttpErrorBadRequest 17 | : any 18 | : TCode extends 404 19 | ? TContentType extends 'application/json' 20 | ? HttpErrorNotFound 21 | : any 22 | : TCode extends 409 23 | ? TContentType extends 'application/json' 24 | ? HttpErrorConflict 25 | : any 26 | : TCode extends 500 27 | ? TContentType extends 'application/json' 28 | ? HttpErrorServer 29 | : any 30 | : any; 31 | -------------------------------------------------------------------------------- /libs/todo-app-contract/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest'; 2 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "references": [ 4 | { 5 | "path": "./tsconfig.spec.json" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declarationMap": true, 6 | "target": "es2015", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSources": true, 10 | "strictNullChecks": true 11 | }, 12 | "angularCompilerOptions": { 13 | "enableIvy": false 14 | }, 15 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"], 16 | "include": ["**/*.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "enableIvy": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tsconfig.spec.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.prod.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/todo-app-contract/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [true, "attribute", "codegena", "camelCase"], 5 | "component-selector": [true, "element", "codegena", "kebab-case"], 6 | "no-implicit-dependencies": [true, "dev", ["@codegena/todo-app-contract"]] 7 | }, 8 | "linterOptions": { 9 | "exclude": ["!**/*"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmScope": "codegena", 3 | "implicitDependencies": { 4 | "angular.json": "*", 5 | "package.json": "*", 6 | "tslint.json": "*", 7 | "nx.json": "*", 8 | "tsconfig.base.json": "*" 9 | }, 10 | "projects": { 11 | "oapi3ts": { 12 | "tags": [] 13 | }, 14 | "definitions": { 15 | "tags": [] 16 | }, 17 | "schematics-example": { 18 | "tags": [] 19 | }, 20 | "schematics-tools": { 21 | "tags": [] 22 | }, 23 | "ng-http-tools": { 24 | "tags": [] 25 | }, 26 | "todo-app-contract": { 27 | "tags": [] 28 | } 29 | }, 30 | "tasksRunnerOptions": { 31 | "default": { 32 | "runner": "@nrwl/workspace/tasks-runners/default", 33 | "options": { 34 | "cacheableOperations": ["build", "lint", "test", "e2e"] 35 | } 36 | } 37 | }, 38 | "affected": { 39 | "defaultBase": "master" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codegena", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "nx", 7 | "nx": "nx", 8 | "start": "ng serve", 9 | "build": "ng build", 10 | "//": "Prebuilt libs help to control and test result of building before publication, but not usuable when you developing", 11 | "build:all-libs": "node build-all-libs.js", 12 | "clear:prebuilt-libs": "rm -rf dist/*", 13 | "lint": "nx workspace-lint && ng lint", 14 | "e2e": "ng e2e", 15 | "build-and-publish": "./build-and-publish.sh", 16 | "todo-app-contract:update": "npm run build:all-libs && npm run schematics-example:build-schematics:dev && npm run schematics-example:link-dist && npm run todo-app-contract:clear-result && npm run todo-app-contract:generate && npm run todo-app-contract:prettier", 17 | "todo-app-contract:clear-result": "rm -rf ./libs/todo-app-contract/src/lib/todo-app", 18 | "schematics-example:build-schematics:dev": "npm run --prefix libs/schematics-example build", 19 | "schematics-example:link-dist": "npm run --prefix libs/schematics-example link:libs:built", 20 | "todo-app-contract:generate": "ng g @codegena/schematics-example:backend-services --uri=$(pwd)/libs/todo-app-contract/src/oas/app-demo.json --domain=todo-app --project=todo-app-contract --secondaryEntrypoint=\"\" --hostModule=\"\" --moduleName=\"todo-app\" --createSubdir=true", 21 | "todo-app-contract:prettier": "./node_modules/.bin/prettier --write libs/todo-app-contract/src/lib/todo-app" 22 | }, 23 | "private": true, 24 | "dependencies": { 25 | "@angular/animations": "12.0.4", 26 | "@angular/common": "12.0.4", 27 | "@angular/compiler": "12.0.4", 28 | "@angular/core": "12.0.4", 29 | "@angular/forms": "12.0.4", 30 | "@angular/platform-browser": "12.0.4", 31 | "@angular/platform-browser-dynamic": "12.0.4", 32 | "@angular/router": "12.0.4", 33 | "@codegena/oapi3ts": "file:dist/oapi3ts", 34 | "@nrwl/angular": "12.3.6", 35 | "ajv": "^6.10.2", 36 | "core-js": "^2.5.4", 37 | "lerna": "^3.20.2", 38 | "lodash": "^4.17.15", 39 | "reflect-metadata": "^0.1.13", 40 | "rxjs": "6.6.2", 41 | "tslib": "^2.0.0", 42 | "zone.js": "~0.11.4" 43 | }, 44 | "devDependencies": { 45 | "@angular-devkit/build-angular": "12.0.4", 46 | "@angular/cli": "12.0.4", 47 | "@angular/compiler-cli": "12.0.4", 48 | "@angular/language-service": "12.0.4", 49 | "@nestjs/schematics": "^7.0.0", 50 | "@nestjs/testing": "^7.0.0", 51 | "@nrwl/cli": "12.3.6", 52 | "@nrwl/cypress": "12.3.6", 53 | "@nrwl/jest": "12.3.6", 54 | "@nrwl/nest": "12.3.6", 55 | "@nrwl/node": "12.3.6", 56 | "@nrwl/tao": "12.3.6", 57 | "@nrwl/workspace": "12.3.6", 58 | "@types/jest": "26.0.8", 59 | "@types/node": "14.14.33", 60 | "codelyzer": "^6.0.0", 61 | "dotenv": "8.2.0", 62 | "eslint": "^7.7.0", 63 | "eslint-plugin-cypress": "^2.10.3", 64 | "jest": "26.2.2", 65 | "jest-preset-angular": "8.4.0", 66 | "ng-packagr": "12.0.5", 67 | "prettier": "2.2.1", 68 | "ts-jest": "26.5.5", 69 | "ts-node": "9.1.1", 70 | "tsickle": "^0.40.0", 71 | "tslint": "6.1.3", 72 | "typescript": "4.2.4" 73 | }, 74 | "workspaces": [ 75 | "libs/*" 76 | ], 77 | "engines": { 78 | "node": ">= 10", 79 | "npm": ">= 7" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tools/generators/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koshevy/codegena/2e7933721ff64c48deb97fbf985ac7aba87ac26f/tools/generators/.gitkeep -------------------------------------------------------------------------------- /tools/tsconfig.tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc/tools", 5 | "rootDir": ".", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": ["node"] 9 | }, 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "importHelpers": true, 12 | "target": "es2015", 13 | "module": "esnext", 14 | "typeRoots": ["node_modules/@types"], 15 | "lib": ["es5", "es2017", "dom"], 16 | "types": ["node"], 17 | "skipLibCheck": true, 18 | "skipDefaultLibCheck": true, 19 | "baseUrl": ".", 20 | "paths": { 21 | "@codegena/oapi3ts": [ 22 | "libs/oapi3ts/src/index.ts" 23 | ], 24 | "@codegena/oapi3ts/contract": [ 25 | "libs/oapi3ts/contract/src/index.ts" 26 | ], 27 | "@codegena/oapi3ts/schematic-tools": [ 28 | "libs/oapi3ts/schematic-tools/src/index.ts" 29 | ], 30 | "@codegena/definitions": [ 31 | "libs/definitions/src/index.ts" 32 | ], 33 | "@codegena/definitions/aspects": [ 34 | "libs/definitions/aspects/src/index.ts" 35 | ], 36 | "@codegena/definitions/json-schema": [ 37 | "libs/definitions/json-schema/src/index.ts" 38 | ], 39 | "@codegena/definitions/oas3": [ 40 | "libs/definitions/oas3/src/index.ts" 41 | ], 42 | "@codegena/schematics-example": [ 43 | "libs/schematics-example/src/index.ts" 44 | ], 45 | "@codegena/schematics-tools": [ 46 | "libs/schematics-tools/src/index.ts" 47 | ], 48 | "@codegena/ng-http-tools": [ 49 | "libs/ng-http-tools/src/index.ts" 50 | ], 51 | "@codegena/ng-http-tools/rx-operators": [ 52 | "libs/ng-http-tools/rx-operators/src/index.ts" 53 | ], 54 | "@codegena/todo-app-contract": [ 55 | "libs/todo-app-contract/src/index.ts" 56 | ], 57 | "@codegena/todo-app-contract/domain-schema": [ 58 | "libs/todo-app-contract/domain-schema/src/index.ts" 59 | ] 60 | } 61 | }, 62 | "exclude": ["node_modules", "tmp"], 63 | "angularCompilerOptions": { 64 | "skipTemplateCodegen": true, 65 | "strictMetadataEmit": false, 66 | "enableResourceInlining": true, 67 | "enableIvy": false 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "paths": { 5 | "@codegena/oapi3ts": [ 6 | "dist/oapi3ts" 7 | ], 8 | "@codegena/oapi3ts/contract": [ 9 | "dist/oapi3ts/contract" 10 | ], 11 | "@codegena/oapi3ts/schematic-tools": [ 12 | "dist/oapi3ts/schematic-tools" 13 | ], 14 | "@codegena/definitions": [ 15 | "dist/definitions" 16 | ], 17 | "@codegena/definitions/aspects": [ 18 | "dist/definitions/aspects" 19 | ], 20 | "@codegena/definitions/json-schema": [ 21 | "dist/definitions/json-schema" 22 | ], 23 | "@codegena/definitions/oas3": [ 24 | "dist/definitions/oas3" 25 | ], 26 | "@codegena/schematics-example": [ 27 | "dist/schematics-example" 28 | ], 29 | "@codegena/schematics-tools": [ 30 | "dist/schematics-tools" 31 | ], 32 | "@codegena/ng-http-tools": [ 33 | "dist/ng-http-tools" 34 | ], 35 | "@codegena/ng-http-tools/rx-operators": [ 36 | "dist/ng-http-tools/rx-operators" 37 | ], 38 | "@codegena/todo-app-contract": [ 39 | "dist/todo-app-contract" 40 | ], 41 | "@codegena/todo-app-contract/domain-schema": [ 42 | "dist/todo-app-contract/domain-schema" 43 | ] 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/@nrwl/workspace/src/tslint", 4 | "node_modules/codelyzer" 5 | ], 6 | "rules": { 7 | "arrow-return-shorthand": true, 8 | "callable-types": true, 9 | "class-name": true, 10 | "deprecation": { 11 | "severity": "warn" 12 | }, 13 | "forin": true, 14 | "import-blacklist": [true, "rxjs/Rx"], 15 | "interface-over-type-literal": true, 16 | "member-access": false, 17 | "member-ordering": [ 18 | true, 19 | { 20 | "order": [ 21 | "static-field", 22 | "instance-field", 23 | "static-method", 24 | "instance-method" 25 | ] 26 | } 27 | ], 28 | "no-arg": true, 29 | "no-bitwise": true, 30 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], 31 | "no-construct": true, 32 | "no-debugger": true, 33 | "no-duplicate-super": true, 34 | "no-empty": false, 35 | "no-empty-interface": true, 36 | "no-eval": true, 37 | "no-inferrable-types": false, 38 | "no-misused-new": true, 39 | "no-non-null-assertion": true, 40 | "no-shadowed-variable": true, 41 | "no-string-literal": false, 42 | "no-string-throw": true, 43 | "no-switch-case-fall-through": false, 44 | "no-unnecessary-initializer": true, 45 | "no-unused-expression": true, 46 | "no-var-keyword": true, 47 | "object-literal-sort-keys": false, 48 | "prefer-const": true, 49 | "radix": true, 50 | "triple-equals": [true, "allow-null-check"], 51 | "unified-signatures": true, 52 | "variable-name": false, 53 | "nx-enforce-module-boundaries": [ 54 | true, 55 | { 56 | "allow": [], 57 | "depConstraints": [ 58 | { 59 | "sourceTag": "*", 60 | "onlyDependOnLibsWithTags": ["*"] 61 | } 62 | ] 63 | } 64 | ], 65 | "directive-selector": [true, "attribute", "app", "camelCase"], 66 | "component-selector": [true, "element", "app", "kebab-case"], 67 | "no-conflicting-lifecycle": true, 68 | "no-host-metadata-property": true, 69 | "no-input-rename": true, 70 | "no-inputs-metadata-property": true, 71 | "no-output-native": true, 72 | "no-output-on-prefix": true, 73 | "no-output-rename": true, 74 | "no-outputs-metadata-property": true, 75 | "template-banana-in-box": true, 76 | "template-no-negated-async": true, 77 | "use-lifecycle-interface": true, 78 | "use-pipe-transform-interface": true, 79 | "no-implicit-dependencies": [true, "dev"], 80 | "nx-enforce-module-boundaries": false 81 | } 82 | } 83 | --------------------------------------------------------------------------------