├── .e2e-micro.env ├── .e2e.env ├── .editorconfig ├── .env ├── .eslintignore ├── .eslintrc.base.json ├── .eslintrc.json ├── .github ├── actions │ ├── action.yml │ ├── bump-version-save.yml │ └── publish.yml └── workflows │ ├── build.yml │ ├── bump-version.yml │ ├── compute-projects.yml │ ├── e2e-test.yml │ ├── new-release.yml │ ├── pr.yml │ ├── publish.yml │ ├── test.yml │ └── upload-badge.yml ├── .gitignore ├── .nxignore ├── .prettierignore ├── .prettierrc ├── .test.env ├── .verdaccio └── config.yml ├── .vscode └── extensions.json ├── README.md ├── apps ├── json-api-front │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── project.json │ ├── proxy.conf.json │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ ├── app.config.ts │ │ │ └── nx-welcome.component.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── styles.css │ │ └── test-setup.ts │ ├── tsconfig.app.json │ ├── tsconfig.editor.json │ ├── tsconfig.json │ └── tsconfig.spec.json ├── json-api-server-e2e │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── project.json │ ├── src │ │ ├── json-api │ │ │ ├── json-api-sdk │ │ │ │ ├── atomic-sdk.spec.ts │ │ │ │ ├── check-common-decorator.spec.ts │ │ │ │ ├── check-othe-call.spec.ts │ │ │ │ ├── get-method.spec.ts │ │ │ │ ├── patch-methode.spec.ts │ │ │ │ └── post-method.spec.ts │ │ │ ├── json-rpc │ │ │ │ ├── run-json-rpc.spec.ts │ │ │ │ └── run-ws-json-rpc.spec.ts │ │ │ └── utils │ │ │ │ ├── data-utils.ts │ │ │ │ └── run-application.ts │ │ └── support │ │ │ ├── global-setup.ts │ │ │ ├── global-teardown.ts │ │ │ └── test-setup.ts │ ├── tsconfig.json │ └── tsconfig.spec.json └── json-api-server │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── project.json │ ├── src │ ├── app │ │ ├── app.module.ts │ │ ├── resources │ │ │ ├── micro-orm │ │ │ │ ├── controllers │ │ │ │ │ ├── extend-book-list │ │ │ │ │ │ └── extend-book-list.controller.ts │ │ │ │ │ └── extend-user │ │ │ │ │ │ └── extend-user.controller.ts │ │ │ │ ├── resources-micro.module.ts │ │ │ │ └── service │ │ │ │ │ ├── atomic.interceptor.ts │ │ │ │ │ ├── controller.interceptor.ts │ │ │ │ │ ├── example.pipe.ts │ │ │ │ │ ├── example.service.ts │ │ │ │ │ ├── guard.service.ts │ │ │ │ │ ├── http-exception.filter.ts │ │ │ │ │ └── method.interceptor.ts │ │ │ └── type-orm │ │ │ │ ├── controllers │ │ │ │ ├── extend-book-list │ │ │ │ │ └── extend-book-list.controller.ts │ │ │ │ └── extend-user │ │ │ │ │ └── extend-user.controller.ts │ │ │ │ ├── resources-type.module.ts │ │ │ │ └── service │ │ │ │ ├── atomic.interceptor.ts │ │ │ │ ├── controller.interceptor.ts │ │ │ │ ├── example.pipe.ts │ │ │ │ ├── example.service.ts │ │ │ │ ├── guard.service.ts │ │ │ │ ├── http-exception.filter.ts │ │ │ │ └── method.interceptor.ts │ │ └── rpc │ │ │ ├── rpc.module.ts │ │ │ └── service │ │ │ └── rpc.service.ts │ ├── assets │ │ └── .gitkeep │ └── main.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── webpack.config.js ├── docker-compose.yaml ├── jest.config.ts ├── jest.preset.js ├── libs ├── json-api │ ├── json-api-nestjs-microorm │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── constants │ │ │ │ └── index.ts │ │ │ │ ├── factory │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── micro-orm-json-api.module.ts │ │ │ │ ├── mock-utils │ │ │ │ ├── entities │ │ │ │ │ ├── addresses.ts │ │ │ │ │ ├── comments.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── notes.ts │ │ │ │ │ ├── roles.ts │ │ │ │ │ ├── user-groups.ts │ │ │ │ │ └── users.ts │ │ │ │ ├── index.ts │ │ │ │ └── utils │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── init-db.ts │ │ │ │ │ ├── provider-entities.ts │ │ │ │ │ └── pull-data.ts │ │ │ │ ├── orm-helper │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── orm-methods │ │ │ │ ├── delete-one │ │ │ │ │ ├── delete-one.spec.ts │ │ │ │ │ └── delete-one.ts │ │ │ │ ├── delete-relationship │ │ │ │ │ ├── delete-relationship.spec.ts │ │ │ │ │ └── delete-relationship.ts │ │ │ │ ├── get-all │ │ │ │ │ ├── get-all.spec.ts │ │ │ │ │ ├── get-all.ts │ │ │ │ │ ├── get-query-for-count.spec.ts │ │ │ │ │ └── get-query-for-count.ts │ │ │ │ ├── get-one │ │ │ │ │ ├── get-one.spec.ts │ │ │ │ │ └── get-one.ts │ │ │ │ ├── get-relationship │ │ │ │ │ ├── get-relationship.spec.ts │ │ │ │ │ └── get-relationship.ts │ │ │ │ ├── index.ts │ │ │ │ ├── patch-one │ │ │ │ │ ├── patch-one.spec.ts │ │ │ │ │ └── patch-one.ts │ │ │ │ ├── patch-relationship │ │ │ │ │ ├── patch-relationship.spec.ts │ │ │ │ │ └── patch-relationship.ts │ │ │ │ ├── post-one │ │ │ │ │ ├── post-one.spec.ts │ │ │ │ │ └── post-one.ts │ │ │ │ └── post-relationship │ │ │ │ │ ├── post-relationship.spec.ts │ │ │ │ │ └── post-relationship.ts │ │ │ │ ├── service │ │ │ │ ├── index.ts │ │ │ │ ├── micro-orm-util.service.spec.ts │ │ │ │ ├── micro-orm-util.service.ts │ │ │ │ └── microorm-service.ts │ │ │ │ └── type.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json │ ├── json-api-nestjs-sdk │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── lib │ │ │ │ ├── constants │ │ │ │ │ └── index.ts │ │ │ │ ├── json-api-angular.ts │ │ │ │ ├── json-api-js.ts │ │ │ │ ├── service │ │ │ │ │ ├── atomic-operations.service.spec.ts │ │ │ │ │ ├── atomic-operations.service.ts │ │ │ │ │ ├── fetch-inner-client.spec.ts │ │ │ │ │ ├── fetch-inner-client.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── json-api-sdk.service.spec.ts │ │ │ │ │ ├── json-api-sdk.service.ts │ │ │ │ │ ├── json-api-utils.service.spec.ts │ │ │ │ │ └── json-api-utils.service.ts │ │ │ │ ├── token │ │ │ │ │ └── index.ts │ │ │ │ ├── types │ │ │ │ │ ├── atomic-operation.ts │ │ │ │ │ ├── atomic-type.ts │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── filter-operand.ts │ │ │ │ │ ├── http-inner-client.ts │ │ │ │ │ ├── http-request-params.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── promise-json-api-sdk.ts │ │ │ │ │ ├── query-params.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── utils │ │ │ │ │ ├── adapter-for-axios.ts │ │ │ │ │ ├── entity-array.ts │ │ │ │ │ ├── generate-atomic-body.spec.ts │ │ │ │ │ ├── generate-atomic-body.ts │ │ │ │ │ ├── http-params.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils.ts │ │ │ └── ngModule.ts │ │ ├── tsconfig-mjs.lib.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json │ ├── json-api-nestjs-shared │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── constants │ │ │ │ └── index.ts │ │ │ │ ├── types │ │ │ │ ├── entity-type.test-d.ts │ │ │ │ ├── entity-type.ts │ │ │ │ ├── index.ts │ │ │ │ ├── query-type.ts │ │ │ │ ├── response-body.test-d.ts │ │ │ │ └── response-body.ts │ │ │ │ └── utils │ │ │ │ ├── ___test___ │ │ │ │ └── test-classes.helper.ts │ │ │ │ ├── index.ts │ │ │ │ ├── object-utils.spec.ts │ │ │ │ └── object-utils.ts │ │ ├── tsconfig-mjs.lib.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json │ ├── json-api-nestjs-typeorm │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── constants │ │ │ │ └── index.ts │ │ │ │ ├── factory │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mock-utils │ │ │ │ ├── entities │ │ │ │ │ ├── addresses.ts │ │ │ │ │ ├── comments.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── notes.ts │ │ │ │ │ ├── pods.ts │ │ │ │ │ ├── roles.ts │ │ │ │ │ ├── user-groups.ts │ │ │ │ │ └── users.ts │ │ │ │ ├── index.ts │ │ │ │ └── pull-data.ts │ │ │ │ ├── orm-helper │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── orm-methods │ │ │ │ ├── delete-one │ │ │ │ │ ├── delete-one.spec.ts │ │ │ │ │ └── delete-one.ts │ │ │ │ ├── delete-relationship │ │ │ │ │ ├── delete-relationship.spec.ts │ │ │ │ │ └── delete-relationship.ts │ │ │ │ ├── get-all │ │ │ │ │ ├── get-all.spec.ts │ │ │ │ │ └── get-all.ts │ │ │ │ ├── get-one │ │ │ │ │ ├── get-one.spec.ts │ │ │ │ │ └── get-one.ts │ │ │ │ ├── get-relationship │ │ │ │ │ ├── get-relationship.spec.ts │ │ │ │ │ └── get-relationship.ts │ │ │ │ ├── index.ts │ │ │ │ ├── patch-one │ │ │ │ │ ├── patch-one.spec.ts │ │ │ │ │ └── patch-one.ts │ │ │ │ ├── patch-relationship │ │ │ │ │ ├── patch-relationship.spec.ts │ │ │ │ │ └── patch-relationship.ts │ │ │ │ ├── post-one │ │ │ │ │ ├── post-one.spec.ts │ │ │ │ │ └── post-one.ts │ │ │ │ └── post-relationship │ │ │ │ │ ├── post-relationship.spec.ts │ │ │ │ │ └── post-relationship.ts │ │ │ │ ├── service │ │ │ │ ├── index.ts │ │ │ │ ├── type-orm-format.error.service.spec.ts │ │ │ │ ├── type-orm-format.error.service.ts │ │ │ │ ├── type-orm.service.ts │ │ │ │ ├── typeorm-utils.service.spec.ts │ │ │ │ └── typeorm-utils.service.ts │ │ │ │ ├── type-orm-json-api.module.ts │ │ │ │ └── type.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json │ └── json-api-nestjs │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── constants │ │ │ ├── constants.ts │ │ │ ├── default.ts │ │ │ ├── di.ts │ │ │ ├── index.ts │ │ │ └── reflection.ts │ │ │ ├── json-api.module.ts │ │ │ ├── modules │ │ │ ├── atomic-operation │ │ │ │ ├── atomic-operation.module.ts │ │ │ │ ├── constants │ │ │ │ │ └── index.ts │ │ │ │ ├── controllers │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── operation.controller.spec.ts │ │ │ │ │ └── operation.controller.ts │ │ │ │ ├── factory │ │ │ │ │ ├── async-iterator.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── map-controller-entity.ts │ │ │ │ │ ├── map-entity-name-to-entity.ts │ │ │ │ │ └── zod-input-operation.ts │ │ │ │ ├── pipes │ │ │ │ │ ├── input-operation.pipe.spec.ts │ │ │ │ │ └── input-operation.pipe.ts │ │ │ │ ├── service │ │ │ │ │ ├── execute.service.spec.ts │ │ │ │ │ ├── execute.service.ts │ │ │ │ │ ├── explorer.service.spec.ts │ │ │ │ │ ├── explorer.service.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── swagger.service.ts │ │ │ │ ├── types │ │ │ │ │ └── index.ts │ │ │ │ └── utils │ │ │ │ │ ├── index.ts │ │ │ │ │ └── zod │ │ │ │ │ ├── zod-helper.spec.ts │ │ │ │ │ └── zod-helper.ts │ │ │ ├── index.ts │ │ │ └── mixin │ │ │ │ ├── config │ │ │ │ └── bindings.ts │ │ │ │ ├── controllers │ │ │ │ ├── index.ts │ │ │ │ └── json-base.controller.ts │ │ │ │ ├── decorators │ │ │ │ ├── index.ts │ │ │ │ ├── inject-service │ │ │ │ │ ├── inject-service.decorator.spec.ts │ │ │ │ │ └── inject-service.decorator.ts │ │ │ │ └── json-api │ │ │ │ │ ├── json-api.decorator.spec.ts │ │ │ │ │ └── json-api.decorator.ts │ │ │ │ ├── factory │ │ │ │ ├── index.ts │ │ │ │ └── zod-validate.factory.ts │ │ │ │ ├── helpers │ │ │ │ ├── bind-controller.spec.ts │ │ │ │ ├── bind-controller.ts │ │ │ │ ├── create-controller.spec.ts │ │ │ │ ├── create-controller.ts │ │ │ │ ├── index.ts │ │ │ │ ├── utils.spec.ts │ │ │ │ └── utils.ts │ │ │ │ ├── interceptors │ │ │ │ ├── error.interceptors.ts │ │ │ │ ├── index.ts │ │ │ │ └── log-time.interceptors.ts │ │ │ │ ├── mixin.module.ts │ │ │ │ ├── pipe │ │ │ │ ├── check-item-entity │ │ │ │ │ ├── check-item-entity.pipe.spec.ts │ │ │ │ │ ├── check-item-entity.pipe.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.spec.ts │ │ │ │ ├── index.ts │ │ │ │ ├── parse-relationship-name │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── parse-relationship-name.pipe.spec.ts │ │ │ │ │ └── parse-relationship-name.pipe.ts │ │ │ │ ├── patch-input │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── patch-input.pipe.spec.ts │ │ │ │ │ └── patch-input.pipe.ts │ │ │ │ ├── patch-relationship │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── patch-relationship.pipe.spec.ts │ │ │ │ │ └── patch-relationship.pipe.ts │ │ │ │ ├── post-input │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── post-input.pipe.spec.ts │ │ │ │ │ └── post-input.pipe.ts │ │ │ │ ├── post-relationship │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── post-relationship.pipe.spec.ts │ │ │ │ │ └── post-relationship.pipe.ts │ │ │ │ ├── query-check-select-field │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── query-check-select-field.spec.ts │ │ │ │ │ └── query-check-select-field.ts │ │ │ │ ├── query-filed-on-include │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── query-filed-in-include.pipe.spec.ts │ │ │ │ │ └── query-filed-in-include.pipe.ts │ │ │ │ ├── query-input │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── query-input.pipe.spec.ts │ │ │ │ │ └── query-input.pipe.ts │ │ │ │ └── query │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── query.pipe.spec.ts │ │ │ │ │ └── query.pipe.ts │ │ │ │ ├── service │ │ │ │ ├── entity-param-map.service.ts │ │ │ │ ├── error-format.service.ts │ │ │ │ ├── index.ts │ │ │ │ ├── json-api-transformer.service.spec.ts │ │ │ │ └── json-api-transformer.service.ts │ │ │ │ ├── swagger │ │ │ │ ├── filter-operand-model.ts │ │ │ │ ├── index.ts │ │ │ │ ├── method │ │ │ │ │ ├── delete-one.ts │ │ │ │ │ ├── delete-relationship.ts │ │ │ │ │ ├── get-all.ts │ │ │ │ │ ├── get-one.ts │ │ │ │ │ ├── get-relationship.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── patch-one.ts │ │ │ │ │ ├── patch-relationship.ts │ │ │ │ │ ├── post-one.ts │ │ │ │ │ └── post-relationship.ts │ │ │ │ ├── swagger-bind.service.ts │ │ │ │ └── utils.ts │ │ │ │ ├── types │ │ │ │ ├── binding.type.ts │ │ │ │ ├── decorator-options.type.ts │ │ │ │ ├── index.ts │ │ │ │ ├── module.type.ts │ │ │ │ └── orm-service.type.ts │ │ │ │ └── zod │ │ │ │ ├── index.ts │ │ │ │ ├── zod-input-patch-relationship-schema │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── zod-input-patch-schema │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── zod-input-post-relationship-schema │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── zod-input-post-schema │ │ │ │ ├── index.spec.ts │ │ │ │ └── index.ts │ │ │ │ ├── zod-input-query-schema │ │ │ │ ├── fields.spec.ts │ │ │ │ ├── fields.ts │ │ │ │ ├── filter.spec.ts │ │ │ │ ├── filter.test-d.ts │ │ │ │ ├── filter.ts │ │ │ │ ├── include.spec.ts │ │ │ │ ├── include.ts │ │ │ │ ├── index.spec.ts │ │ │ │ ├── index.ts │ │ │ │ ├── sort.spec.ts │ │ │ │ └── sort.ts │ │ │ │ ├── zod-query-schema │ │ │ │ ├── fields.spec.ts │ │ │ │ ├── fields.ts │ │ │ │ ├── filter.spec.ts │ │ │ │ ├── filter.ts │ │ │ │ ├── include.spec.ts │ │ │ │ ├── include.ts │ │ │ │ ├── index.spec.ts │ │ │ │ ├── index.ts │ │ │ │ ├── sort.spec.ts │ │ │ │ └── sort.ts │ │ │ │ ├── zod-share │ │ │ │ ├── attributes.spec.ts │ │ │ │ ├── attributes.test-d.ts │ │ │ │ ├── attributes.ts │ │ │ │ ├── id.spec.ts │ │ │ │ ├── id.ts │ │ │ │ ├── index.ts │ │ │ │ ├── page.spec.ts │ │ │ │ ├── page.ts │ │ │ │ ├── rel-data.spec.ts │ │ │ │ ├── rel-data.ts │ │ │ │ ├── relationships.spec.ts │ │ │ │ ├── relationships.ts │ │ │ │ ├── type.spec.ts │ │ │ │ └── type.ts │ │ │ │ ├── zod-utils.spec.ts │ │ │ │ └── zod-utils.ts │ │ │ ├── types │ │ │ ├── common-type.ts │ │ │ ├── entity-param.test-d.ts │ │ │ ├── entity-param.type.ts │ │ │ ├── error.types.ts │ │ │ ├── index.ts │ │ │ ├── module-options.test-d.ts │ │ │ ├── module-options.types.ts │ │ │ ├── utils-type.test-d.ts │ │ │ └── utils-type.ts │ │ │ └── utils │ │ │ ├── ___test___ │ │ │ ├── test-classes.helper.ts │ │ │ └── test.helper.ts │ │ │ ├── index.ts │ │ │ ├── module-helper.spec.ts │ │ │ └── module-helper.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json ├── json-rpc │ ├── nestjs-json-rpc-sdk │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── ng-package.json │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── lib │ │ │ │ ├── angular │ │ │ │ │ ├── factory.ts │ │ │ │ │ ├── json-rpc-angular.module.ts │ │ │ │ │ └── tokens.ts │ │ │ │ ├── constans │ │ │ │ │ └── index.ts │ │ │ │ ├── factory │ │ │ │ │ ├── axios-transport.factory.ts │ │ │ │ │ ├── fetch-transport.factory.ts │ │ │ │ │ ├── id-request.spec.ts │ │ │ │ │ ├── id-request.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── io-transport.factory.ts │ │ │ │ │ ├── rpc.factory.ts │ │ │ │ │ ├── transport.factory.ts │ │ │ │ │ └── ws-transport.factory.ts │ │ │ │ ├── json-rpc-angular.ts │ │ │ │ ├── types │ │ │ │ │ ├── angular-type.ts │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── rpc-error-object.ts │ │ │ │ │ ├── rpc.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── utils │ │ │ │ │ ├── body.spec.ts │ │ │ │ │ ├── body.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── pipe.ts │ │ │ │ │ ├── rpc-batch.spec.ts │ │ │ │ │ ├── rpc-batch.ts │ │ │ │ │ ├── rpc-proxy.spec.ts │ │ │ │ │ ├── rpc-proxy.ts │ │ │ │ │ ├── wrapper-call.spec.ts │ │ │ │ │ └── wrapper-call.ts │ │ │ └── ngModule.ts │ │ ├── tsconfig-mjs.lib.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json │ └── nestjs-json-rpc │ │ ├── .eslintrc.json │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── constants │ │ │ └── index.ts │ │ │ ├── decorators │ │ │ └── index.ts │ │ │ ├── modules │ │ │ ├── http-transport │ │ │ │ ├── controllers │ │ │ │ │ ├── json-rpc.controller.spec.ts │ │ │ │ │ └── json-rpc.controller.ts │ │ │ │ ├── filter │ │ │ │ │ ├── rpc-error-exception.filter.spec.ts │ │ │ │ │ └── rpc-error-exception.filter.ts │ │ │ │ └── http-transport.module.ts │ │ │ ├── index.ts │ │ │ ├── util │ │ │ │ ├── pipe │ │ │ │ │ ├── input-data.pipe.spec.ts │ │ │ │ │ └── input-data.pipe.ts │ │ │ │ ├── service │ │ │ │ │ ├── explorer.service.spec.ts │ │ │ │ │ ├── explorer.service.ts │ │ │ │ │ ├── handler.service.spec.ts │ │ │ │ │ ├── handler.service.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── util.module.spec.ts │ │ │ │ └── util.module.ts │ │ │ └── ws-socket-transport │ │ │ │ ├── constants │ │ │ │ └── index.ts │ │ │ │ ├── factory │ │ │ │ ├── create-gateway.factory.ts │ │ │ │ └── index.ts │ │ │ │ ├── filter │ │ │ │ ├── rpc-ws-error-exception.filter.spec.ts │ │ │ │ └── rpc-ws-error-exception.filter.ts │ │ │ │ ├── service │ │ │ │ ├── index.ts │ │ │ │ └── web-socket-gateway.service.ts │ │ │ │ └── ws-socket-transport.module.ts │ │ │ ├── nestjs-json-rpc.module.ts │ │ │ ├── providers │ │ │ ├── async-iterator.provider.ts │ │ │ ├── index.ts │ │ │ ├── map-handler-store.provider.ts │ │ │ └── zod-input-data.provider.ts │ │ │ ├── types │ │ │ ├── error-code-type.ts │ │ │ ├── error-payloade.ts │ │ │ ├── index.ts │ │ │ ├── module-options.ts │ │ │ ├── payloade.ts │ │ │ └── utils.ts │ │ │ └── utils │ │ │ ├── error.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.spec.json ├── microorm-database │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── config-cli.ts │ │ │ ├── config.ts │ │ │ ├── entities │ │ │ ├── addresses.ts │ │ │ ├── book-list.ts │ │ │ ├── comments.ts │ │ │ ├── index.ts │ │ │ ├── roles.ts │ │ │ └── users.ts │ │ │ ├── micro-orm-database.module.ts │ │ │ └── migrations │ │ │ ├── .snapshot-microorm-test.json │ │ │ ├── Migration20250123104848_CreateUsersTable.ts │ │ │ ├── Migration20250123105611_CreateAddressesTable.ts │ │ │ ├── Migration20250123110115_CreateRolesTable.ts │ │ │ ├── Migration20250123111042_CreateCommentsTable.ts │ │ │ ├── Migration20250123123708_CreateUsersRolesRelations.ts │ │ │ ├── Migration20250123124745_CreateUsersUsersRelations.ts │ │ │ ├── Migration20250123125941_CreateUsersAddressRelations.ts │ │ │ ├── Migration20250123130345_CreateUsersCommentsRelations.ts │ │ │ ├── Migration20250123131039_CreateBookListTable.ts │ │ │ └── Migration20250123131438_CreateUsersBookListRelations.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json ├── type-for-rpc │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── project.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ └── rpc-service.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json └── typeorm-database │ ├── .eslintrc.json │ ├── README.md │ ├── jest.config.ts │ ├── project.json │ ├── src │ ├── index.ts │ └── lib │ │ ├── config-cli.ts │ │ ├── config.ts │ │ ├── entities-mysql │ │ ├── addresses.ts │ │ ├── book-list.ts │ │ ├── comments.ts │ │ ├── index.ts │ │ ├── roles.ts │ │ └── users.ts │ │ ├── entities │ │ ├── addresses.ts │ │ ├── book-list.ts │ │ ├── comments.ts │ │ ├── index.ts │ │ ├── roles.ts │ │ ├── users-have-roles.ts │ │ └── users.ts │ │ ├── migrations-mysql │ │ └── 1741669072861-test.ts │ │ ├── migrations │ │ ├── 1607701631900-CreateAddressesTable.ts │ │ ├── 1607701632000-CreateUsersTable.ts │ │ ├── 1607701632200-CreateRolesTable.ts │ │ ├── 1607701632300-CreateUsersHaveRolesTable.ts │ │ ├── 1607701632600-CreateCommentsTable.ts │ │ ├── 1665469071344-CreateBookTable.ts │ │ └── 1665719467563-CreateUsersHasBookTable.ts │ │ ├── seeders │ │ ├── factory │ │ │ ├── addresses.factory.ts │ │ │ ├── comments.factory.ts │ │ │ ├── index.ts │ │ │ ├── roles.factory.ts │ │ │ └── user.factory.ts │ │ └── root.seeder.ts │ │ └── type-orm-database.module.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ └── tsconfig.spec.json ├── nx.json ├── package-lock.json ├── package.json ├── project.json ├── tools └── scripts │ ├── preparation-hybrid-npm-package.mjs │ ├── preparation-npm-package.mjs │ ├── prepare-package-json.mjs │ ├── publish.mjs │ └── upload-badge.mjs └── tsconfig.base.json /.e2e-micro.env: -------------------------------------------------------------------------------- 1 | DB_LOGGING=0 2 | ORM_TYPE=microorm 3 | -------------------------------------------------------------------------------- /.e2e.env: -------------------------------------------------------------------------------- 1 | DB_LOGGING=0 2 | ORM_TYPE=typeorm 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | DB_HOST=localhost 2 | DB_LOGGING=1 3 | DB_NAME="json-api-db" 4 | 5 | DB_USERNAME="postgres" 6 | DB_PASSWORD="postgres" 7 | DB_PORT=5432 8 | DB_TYPE=postgres 9 | 10 | #DB_USERNAME="root" 11 | #DB_PASSWORD="mysql" 12 | #DB_PORT=3306 13 | #DB_TYPE=mysql 14 | 15 | 16 | #ORM_TYPE=microorm 17 | ORM_TYPE=typeorm 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.eslintrc.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "ignorePatterns": ["**/*"], 4 | "plugins": ["@nx"], 5 | "overrides": [ 6 | { 7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 8 | "rules": { 9 | "@nx/enforce-module-boundaries": [ 10 | "error", 11 | { 12 | "enforceBuildableLibDependency": true, 13 | "allow": [], 14 | "depConstraints": [ 15 | { 16 | "sourceTag": "*", 17 | "onlyDependOnLibsWithTags": ["*"] 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | }, 24 | { 25 | "files": ["*.ts", "*.tsx"], 26 | "extends": ["plugin:@nx/typescript"], 27 | "rules": {} 28 | }, 29 | { 30 | "files": ["*.js", "*.jsx"], 31 | "extends": ["plugin:@nx/javascript"], 32 | "rules": {} 33 | }, 34 | { 35 | "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], 36 | "env": { 37 | "jest": true 38 | }, 39 | "rules": {} 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /.github/actions/action.yml: -------------------------------------------------------------------------------- 1 | name: Main action for Node.js 2 | description: Setup Node.js 3 | 4 | inputs: 5 | node-version: 6 | description: Node.js version 7 | required: false 8 | default: 20.x 9 | 10 | runs: 11 | using: composite 12 | steps: 13 | - name: Use Node.js ${{ inputs.node-version }} 14 | uses: actions/setup-node@v3 15 | with: 16 | node-version: ${{ inputs.node-version }} 17 | registry-url: 'https://registry.npmjs.org' 18 | cache: npm 19 | 20 | - name: Get npm cache directory 21 | id: npm-cache-dir 22 | shell: pwsh 23 | run: echo "dir=$(npm config get cache)" >> ${env:GITHUB_OUTPUT} 24 | 25 | - name: Cache NPM dependencies 26 | uses: actions/cache@v4 27 | id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true' 28 | with: 29 | path: ${{ steps.npm-cache-dir.outputs.dir }} 30 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 31 | restore-keys: | 32 | ${{ runner.os }}-node- 33 | 34 | - name: Install Dependencies 35 | shell: bash 36 | run: npm ci 37 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: 📝 PR Checks 2 | 3 | on: 4 | [pull_request] 5 | 6 | jobs: 7 | test: 8 | uses: ./.github/workflows/test.yml 9 | secrets: 10 | NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} 11 | 12 | e2e-test: 13 | needs: [test] 14 | uses: ./.github/workflows/e2e-test.yml 15 | secrets: 16 | NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} 17 | 18 | build: 19 | needs: [test, e2e-test] 20 | uses: ./.github/workflows/build.yml 21 | secrets: 22 | NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: ⚙️ Publish 2 | 3 | 4 | on: 5 | workflow_call: 6 | secrets: 7 | NPM_TOKEN: 8 | required: true 9 | 10 | env: 11 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 12 | NPM_CONFIG_PROVENANCE: true 13 | 14 | jobs: 15 | publish: 16 | runs-on: ubuntu-latest 17 | permissions: 18 | contents: "read" 19 | actions: "read" 20 | id-token: "write" # needed for provenance data generation 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 26 | - name: Pull latest changes (from bump-version) 27 | run: | 28 | git config --global user.email "actions@github.com" 29 | git config --global user.name "GitHub Actions" 30 | git pull origin ${{ github.ref_name }} 31 | 32 | - name: Setup Node.js 33 | uses: ./.github/actions 34 | 35 | - name: Build 36 | run: npx nx run-many -t build --parallel=3 --exclude='*,!tag:type:publish' 37 | 38 | - name: Publish packages 39 | run: npx nx release publish 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | dist 5 | tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | 41 | .nx/cache 42 | .nx/workspace-data 43 | .angular 44 | .dev.env 45 | -------------------------------------------------------------------------------- /.nxignore: -------------------------------------------------------------------------------- 1 | libs/**/*.test-d.ts 2 | libs/json-api/**/___test___/ 3 | 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | /dist 3 | /coverage 4 | /.nx/cache 5 | .angular 6 | 7 | /.nx/workspace-data 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /.test.env: -------------------------------------------------------------------------------- 1 | NODE_OPTIONS=--experimental-vm-modules --disable-warning=ExperimentalWarning 2 | DB_LOGGING=0 3 | -------------------------------------------------------------------------------- /.verdaccio/config.yml: -------------------------------------------------------------------------------- 1 | # path to a directory with all packages 2 | storage: ../tmp/local-registry/storage 3 | 4 | # a list of other known repositories we can talk to 5 | uplinks: 6 | npmjs: 7 | url: https://registry.npmjs.org/ 8 | maxage: 60m 9 | 10 | packages: 11 | '**': 12 | # give all users (including non-authenticated users) full access 13 | # because it is a local registry 14 | access: $all 15 | publish: $all 16 | unpublish: $all 17 | 18 | # if package is not available locally, proxy requests to npm registry 19 | proxy: npmjs 20 | 21 | # log settings 22 | log: 23 | type: stdout 24 | format: pretty 25 | level: warn 26 | 27 | publish: 28 | allow_offline: true # set offline to true to allow publish offline 29 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "nrwl.angular-console", 4 | "esbenp.prettier-vscode", 5 | "firsttris.vscode-jest-runner" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /apps/json-api-front/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts"], 7 | "extends": [ 8 | "plugin:@nx/angular", 9 | "plugin:@angular-eslint/template/process-inline-templates" 10 | ], 11 | "rules": { 12 | "@angular-eslint/directive-selector": [ 13 | "error", 14 | { 15 | "type": "attribute", 16 | "prefix": "nestjsJsonApi", 17 | "style": "camelCase" 18 | } 19 | ], 20 | "@angular-eslint/component-selector": [ 21 | "error", 22 | { 23 | "type": "element", 24 | "prefix": "nestjs-json-api", 25 | "style": "kebab-case" 26 | } 27 | ], 28 | "@angular-eslint/prefer-standalone": "off" 29 | } 30 | }, 31 | { 32 | "files": ["*.html"], 33 | "extends": ["plugin:@nx/angular-template"], 34 | "rules": {} 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /apps/json-api-front/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'json-api-front', 4 | preset: '../../jest.preset.js', 5 | setupFilesAfterEnv: ['/src/test-setup.ts'], 6 | coverageDirectory: '../../coverage/apps/json-api-front', 7 | transform: { 8 | '^.+\\.(ts|mjs|js|html)$': [ 9 | 'jest-preset-angular', 10 | { 11 | tsconfig: '/tsconfig.spec.json', 12 | stringifyContentPathRegex: '\\.(html|svg)$', 13 | }, 14 | ], 15 | }, 16 | transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], 17 | snapshotSerializers: [ 18 | 'jest-preset-angular/build/serializers/no-ng-attributes', 19 | 'jest-preset-angular/build/serializers/ng-snapshot', 20 | 'jest-preset-angular/build/serializers/html-comment', 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /apps/json-api-front/proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api": { 3 | "target": "http://localhost:3000", 4 | "secure": false 5 | }, 6 | "/rpc": { 7 | "target": "http://localhost:3000", 8 | "secure": false, 9 | "ws": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/json-api-front/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klerick/nestjs-json-api/3e7b3e6465e9ada4c222fefae6070d20d71de506/apps/json-api-front/src/app/app.component.css -------------------------------------------------------------------------------- /apps/json-api-front/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/json-api-front/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klerick/nestjs-json-api/3e7b3e6465e9ada4c222fefae6070d20d71de506/apps/json-api-front/src/assets/.gitkeep -------------------------------------------------------------------------------- /apps/json-api-front/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klerick/nestjs-json-api/3e7b3e6465e9ada4c222fefae6070d20d71de506/apps/json-api-front/src/favicon.ico -------------------------------------------------------------------------------- /apps/json-api-front/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | json-api-front 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /apps/json-api-front/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig).catch((err) => 6 | console.error(err) 7 | ); 8 | -------------------------------------------------------------------------------- /apps/json-api-front/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /apps/json-api-front/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment 2 | globalThis.ngJest = { 3 | testEnvironmentOptions: { 4 | errorOnUnknownElements: true, 5 | errorOnUnknownProperties: true, 6 | }, 7 | }; 8 | import 'jest-preset-angular/setup-jest'; 9 | -------------------------------------------------------------------------------- /apps/json-api-front/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [] 6 | }, 7 | "files": ["src/main.ts"], 8 | "include": ["src/**/*.d.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/json-api-front/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*.ts"], 4 | "compilerOptions": { 5 | "types": ["jest", "node"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/json-api-front/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "useDefineForClassFields": false, 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true 12 | }, 13 | "files": [], 14 | "include": [], 15 | "references": [ 16 | { 17 | "path": "./tsconfig.app.json" 18 | }, 19 | { 20 | "path": "./tsconfig.spec.json" 21 | }, 22 | { 23 | "path": "./tsconfig.editor.json" 24 | } 25 | ], 26 | "extends": "../../tsconfig.base.json", 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /apps/json-api-front/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2016", 7 | "types": ["jest", "node"] 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": [ 11 | "jest.config.ts", 12 | "src/**/*.test.ts", 13 | "src/**/*.spec.ts", 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-api-server-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "implicitDependencies": [ 5 | "json-api-server" 6 | ], 7 | "projectType": "application", 8 | "targets": { 9 | "e2e": { 10 | "dependsOn":[ { 11 | "dependencies": true, 12 | "target": "build", 13 | "params": "ignore" 14 | }], 15 | "executor": "@nx/jest:jest", 16 | "outputs": [ 17 | "{workspaceRoot}/coverage/{e2eProjectRoot}" 18 | ], 19 | "options": { 20 | "jestConfig": "apps/json-api-server-e2e/jest.config.ts", 21 | "passWithNoTests": true, 22 | "parallel": 1 23 | } 24 | }, 25 | "e2e-micro": { 26 | "dependsOn":[ { 27 | "dependencies": true, 28 | "target": "build", 29 | "params": "ignore" 30 | }], 31 | "executor": "@nx/jest:jest", 32 | "outputs": [ 33 | "{workspaceRoot}/coverage/{e2eProjectRoot}" 34 | ], 35 | "options": { 36 | "jestConfig": "apps/json-api-server-e2e/jest.config.ts", 37 | "passWithNoTests": true, 38 | "parallel": 1 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/src/json-api/utils/data-utils.ts: -------------------------------------------------------------------------------- 1 | import { Users } from '@nestjs-json-api/typeorm-database'; 2 | import { faker } from '@faker-js/faker'; 3 | 4 | export const getUser = () => { 5 | const user = new Users(); 6 | user.firstName = faker.string.alpha(50); 7 | user.lastName = faker.string.alpha(50); 8 | user.login = faker.string.alpha(50); 9 | return user; 10 | }; 11 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/src/support/global-setup.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var __TEARDOWN_MESSAGE__: string; 3 | 4 | module.exports = async function() { 5 | // Start services that that the app needs to run (e.g. database, docker-compose, etc.). 6 | console.log('\nSetting up...\n'); 7 | 8 | // Hint: Use `globalThis` to pass variables to global teardown. 9 | globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n'; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/src/support/global-teardown.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | module.exports = async function() { 4 | // Put clean up logic here (e.g. stopping services, docker-compose, etc.). 5 | // Hint: `globalThis` is shared between setup and teardown. 6 | console.log(globalThis.__TEARDOWN_MESSAGE__); 7 | }; 8 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/src/support/test-setup.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | // import axios from 'axios'; 4 | // 5 | // module.exports = async function() { 6 | // // Configure axios for tests to use. 7 | // const host = process.env.HOST ?? 'localhost'; 8 | // const port = process.env.PORT ?? '3000'; 9 | // axios.defaults.baseURL = `http://${host}:${port}`; 10 | // }; 11 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.spec.json" 8 | } 9 | ], 10 | "compilerOptions": { 11 | "esModuleInterop": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/json-api-server-e2e/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"], 7 | "emitDecoratorMetadata": true, 8 | "target": "es2021", 9 | "strictBindCallApply": true, 10 | "strictNullChecks": true, 11 | "noImplicitAny": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "allowJs": true 15 | }, 16 | "include": [ 17 | "jest.config.ts", 18 | "src/**/*.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /apps/json-api-server/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /apps/json-api-server/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'json-api-server', 4 | preset: '../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }] 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../coverage/apps/json-api-server' 11 | }; 12 | -------------------------------------------------------------------------------- /apps/json-api-server/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-api-server", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "apps/json-api-server/src", 5 | "projectType": "application", 6 | "targets": { 7 | "serve": { 8 | "executor": "@nx/js:node", 9 | "defaultConfiguration": "development", 10 | "options": { 11 | "buildTarget": "json-api-server:build" 12 | }, 13 | "configurations": { 14 | "development": { 15 | "buildTarget": "json-api-server:build:development" 16 | }, 17 | "production": { 18 | "buildTarget": "json-api-server:build:production" 19 | } 20 | } 21 | } 22 | }, 23 | "tags": [], 24 | "implicitDependencies": ["json-api-nestjs-typeorm", "json-api-nestjs-microorm", "json-api-nestjs-sdk"] 25 | } 26 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { LoggerModule } from 'nestjs-pino'; 3 | 4 | import { TypeOrmDatabaseModule } from '@nestjs-json-api/typeorm-database'; 5 | import { MicroOrmDatabaseModule } from '@nestjs-json-api/microorm-database'; 6 | import { ResourcesTypeModule } from './resources/type-orm/resources-type.module'; 7 | import { ResourcesMicroModule } from './resources/micro-orm/resources-micro.module'; 8 | import { RpcModule } from './rpc/rpc.module'; 9 | 10 | const ormModule = 11 | process.env['ORM_TYPE'] === 'typeorm' 12 | ? TypeOrmDatabaseModule 13 | : MicroOrmDatabaseModule; 14 | 15 | const resourceModule = 16 | process.env['ORM_TYPE'] === 'typeorm' 17 | ? ResourcesTypeModule 18 | : ResourcesMicroModule; 19 | 20 | @Module({ 21 | imports: [ 22 | ormModule, 23 | resourceModule, 24 | RpcModule, 25 | LoggerModule.forRoot({ 26 | pinoHttp: { 27 | level: process.env['NODE_ENV'] === 'test' ? 'silent' : 'debug', 28 | }, 29 | }), 30 | ], 31 | controllers: [], 32 | providers: [], 33 | }) 34 | export class AppModule {} 35 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/micro-orm/controllers/extend-book-list/extend-book-list.controller.ts: -------------------------------------------------------------------------------- 1 | import { ParseUUIDPipe } from '@nestjs/common'; 2 | import { JsonApi, JsonBaseController } from '@klerick/json-api-nestjs'; 3 | import { BookList } from '@nestjs-json-api/microorm-database'; 4 | 5 | @JsonApi(BookList, { 6 | pipeForId: ParseUUIDPipe, 7 | overrideRoute: 'override-book-list', 8 | allowMethod: ['getOne', 'postOne', 'deleteOne'], 9 | }) 10 | export class ExtendBookListController extends JsonBaseController< 11 | BookList, 12 | 'id' 13 | > {} 14 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/micro-orm/resources-micro.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { JsonApiModule } from '@klerick/json-api-nestjs'; 3 | import { MicroOrmJsonApiModule } from '@klerick/json-api-nestjs-microorm'; 4 | import { 5 | Users, 6 | Addresses, 7 | Comments, 8 | Roles, 9 | BookList, 10 | } from '@nestjs-json-api/microorm-database'; 11 | 12 | import { ExtendBookListController } from './controllers/extend-book-list/extend-book-list.controller'; 13 | import { ExtendUserController } from './controllers/extend-user/extend-user.controller'; 14 | import { ExampleService } from './service/example.service'; 15 | 16 | @Module({ 17 | imports: [ 18 | JsonApiModule.forRoot(MicroOrmJsonApiModule, { 19 | entities: [Users, Addresses, Comments, Roles, BookList], 20 | controllers: [ExtendBookListController, ExtendUserController], 21 | providers: [ExampleService], 22 | options: { 23 | debug: true, 24 | requiredSelectField: false, 25 | operationUrl: 'operation', 26 | }, 27 | }), 28 | ], 29 | }) 30 | export class ResourcesMicroModule {} 31 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/micro-orm/service/atomic.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CallHandler, 3 | ExecutionContext, 4 | NestInterceptor, 5 | Injectable, 6 | } from '@nestjs/common'; 7 | import { Observable } from 'rxjs'; 8 | 9 | @Injectable() 10 | export class AtomicInterceptor implements NestInterceptor { 11 | intercept(context: ExecutionContext, next: CallHandler): Observable { 12 | const isAtomic = context.getArgByIndex(3); 13 | if (isAtomic) { 14 | console.log('call from atomic operation'); 15 | } 16 | return next.handle(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/micro-orm/service/example.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ArgumentMetadata, 3 | BadRequestException, 4 | PipeTransform, 5 | } from '@nestjs/common'; 6 | 7 | import { Query } from '@klerick/json-api-nestjs'; 8 | import { Users } from '@nestjs-json-api/microorm-database'; 9 | 10 | export class ExamplePipe 11 | implements PipeTransform, Query> 12 | { 13 | transform( 14 | value: Query, 15 | metadata: ArgumentMetadata 16 | ): Query { 17 | if (value.filter.target?.firstName?.eq === 'testCustomPipe') { 18 | const error = { 19 | code: 'invalid_arguments', 20 | message: `Custom query pipe error`, 21 | path: [], 22 | }; 23 | throw new BadRequestException([error]); 24 | } 25 | return value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/micro-orm/service/example.service.ts: -------------------------------------------------------------------------------- 1 | export class ExampleService { 2 | testMethode(id: string): string { 3 | return id; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/type-orm/controllers/extend-book-list/extend-book-list.controller.ts: -------------------------------------------------------------------------------- 1 | import { ParseUUIDPipe } from '@nestjs/common'; 2 | import { JsonApi, JsonBaseController } from '@klerick/json-api-nestjs'; 3 | import { BookList } from '@nestjs-json-api/typeorm-database'; 4 | 5 | @JsonApi(BookList, { 6 | pipeForId: ParseUUIDPipe, 7 | overrideRoute: 'override-book-list', 8 | allowMethod: ['getOne', 'postOne', 'deleteOne'], 9 | }) 10 | export class ExtendBookListController extends JsonBaseController< 11 | BookList, 12 | 'id' 13 | > {} 14 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/type-orm/resources-type.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { JsonApiModule } from '@klerick/json-api-nestjs'; 3 | import { TypeOrmJsonApiModule } from '@klerick/json-api-nestjs-typeorm'; 4 | import { 5 | Users, 6 | Addresses, 7 | Comments, 8 | Roles, 9 | BookList, 10 | } from '@nestjs-json-api/typeorm-database'; 11 | 12 | import { ExtendBookListController } from './controllers/extend-book-list/extend-book-list.controller'; 13 | import { ExtendUserController } from './controllers/extend-user/extend-user.controller'; 14 | import { ExampleService } from './service/example.service'; 15 | 16 | @Module({ 17 | imports: [ 18 | JsonApiModule.forRoot(TypeOrmJsonApiModule, { 19 | entities: [Users, Addresses, Comments, Roles, BookList], 20 | controllers: [ExtendBookListController, ExtendUserController], 21 | providers: [ExampleService], 22 | options: { 23 | debug: true, 24 | requiredSelectField: false, 25 | operationUrl: 'operation', 26 | }, 27 | }), 28 | ], 29 | }) 30 | export class ResourcesTypeModule {} 31 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/type-orm/service/atomic.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CallHandler, 3 | ExecutionContext, 4 | NestInterceptor, 5 | Injectable, 6 | } from '@nestjs/common'; 7 | import { Observable } from 'rxjs'; 8 | 9 | @Injectable() 10 | export class AtomicInterceptor implements NestInterceptor { 11 | intercept(context: ExecutionContext, next: CallHandler): Observable { 12 | const isAtomic = context.getArgByIndex(3); 13 | if (isAtomic) { 14 | console.log('call from atomic operation'); 15 | } 16 | return next.handle(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/type-orm/service/example.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ArgumentMetadata, 3 | BadRequestException, 4 | PipeTransform, 5 | } from '@nestjs/common'; 6 | 7 | import { Query } from '@klerick/json-api-nestjs'; 8 | import { Users } from '@nestjs-json-api/typeorm-database'; 9 | 10 | export class ExamplePipe 11 | implements PipeTransform, Query> 12 | { 13 | transform( 14 | value: Query, 15 | metadata: ArgumentMetadata 16 | ): Query { 17 | if (value.filter.target?.firstName?.eq === 'testCustomPipe') { 18 | const error = { 19 | code: 'invalid_arguments', 20 | message: `Custom query pipe error`, 21 | path: [], 22 | }; 23 | throw new BadRequestException([error]); 24 | } 25 | return value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/resources/type-orm/service/example.service.ts: -------------------------------------------------------------------------------- 1 | export class ExampleService { 2 | testMethode(id: string): string { 3 | return id; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/rpc/rpc.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { NestjsJsonRpcModule, TransportType } from '@klerick/nestjs-json-rpc'; 3 | import { RpcService } from './service/rpc.service'; 4 | 5 | @Module({ 6 | imports: [ 7 | NestjsJsonRpcModule.forRoot({ 8 | path: 'rpc', 9 | transport: TransportType.HTTP, 10 | }), 11 | NestjsJsonRpcModule.forRoot({ 12 | transport: TransportType.WS, 13 | wsConfig: { 14 | path: '/rpc', 15 | cors: { 16 | origin: '*', 17 | }, 18 | }, 19 | }), 20 | ], 21 | providers: [RpcService], 22 | }) 23 | export class RpcModule {} 24 | -------------------------------------------------------------------------------- /apps/json-api-server/src/app/rpc/service/rpc.service.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InputType, 3 | OutputType, 4 | RpcService as IRpcService, 5 | } from '@nestjs-json-api/type-for-rpc'; 6 | 7 | import { 8 | createErrorCustomError, 9 | RpcHandler, 10 | RpcParamsPipe, 11 | } from '@klerick/nestjs-json-rpc'; 12 | import { ParseIntPipe } from '@nestjs/common'; 13 | 14 | @RpcHandler() 15 | export class RpcService implements IRpcService { 16 | methodeWithObjectParams(a: InputType): Promise { 17 | return Promise.resolve({ 18 | d: `${a.a}`, 19 | c: `${a.b}`, 20 | }); 21 | } 22 | 23 | someMethode(@RpcParamsPipe(ParseIntPipe) firstArg: number): Promise { 24 | if (firstArg === 5) throw createErrorCustomError(-32099, 'Custom Error'); 25 | return Promise.resolve(firstArg); 26 | } 27 | 28 | someOtherMethode(firstArg: number, secondArgument: number): Promise { 29 | return Promise.resolve(''); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /apps/json-api-server/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klerick/nestjs-json-api/3e7b3e6465e9ada4c222fefae6070d20d71de506/apps/json-api-server/src/assets/.gitkeep -------------------------------------------------------------------------------- /apps/json-api-server/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": [ 7 | "node" 8 | ], 9 | "emitDecoratorMetadata": true, 10 | "target": "es2021", 11 | "strictBindCallApply": true, 12 | "strictNullChecks": true, 13 | "noImplicitAny": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true 16 | }, 17 | "exclude": [ 18 | "jest.config.ts", 19 | "src/**/*.spec.ts", 20 | "src/**/*.test.ts", 21 | "**/*.test-d.ts" 22 | ], 23 | "include": [ 24 | "src/**/*.ts", 25 | "*.test-d.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /apps/json-api-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.app.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ], 13 | "compilerOptions": { 14 | "esModuleInterop": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/json-api-server/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 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /apps/json-api-server/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const { NxWebpackPlugin } = require('@nx/webpack'); 3 | const { join } = require('path'); 4 | 5 | module.exports = { 6 | output: { 7 | path: join(__dirname, '../../dist/apps/json-api-server'), 8 | }, 9 | plugins: [ 10 | new NxWebpackPlugin({ 11 | target: 'node', 12 | compiler: 'tsc', 13 | main: './src/main.ts', 14 | tsConfig: './tsconfig.app.json', 15 | assets: ["./src/assets"], 16 | optimization: false, 17 | outputHashing: 'none', 18 | }) 19 | ], 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | postgres: 4 | image: postgres:15.1-alpine 5 | restart: always 6 | environment: 7 | - POSTGRES_USER=postgres 8 | - POSTGRES_PASSWORD=postgres 9 | ports: 10 | - '5432:5432' 11 | volumes: 12 | - db:/var/lib/postgresql/data 13 | pgadmin: 14 | container_name: 'pgadmin' 15 | image: 'dpage/pgadmin4:latest' 16 | hostname: pgadmin 17 | depends_on: 18 | - 'postgres' 19 | environment: 20 | - PGADMIN_DEFAULT_PASSWORD=password 21 | - PGADMIN_DEFAULT_EMAIL=pg.admin@email.com 22 | volumes: 23 | - pgadmin:/root/.pgadmin 24 | ports: 25 | - '8000:80' 26 | db: 27 | image: mysql:latest 28 | restart: always 29 | environment: 30 | MYSQL_ROOT_PASSWORD: mysql 31 | ports: 32 | - '3306:3306' 33 | volumes: 34 | - mysql-db:/var/lib/mysql 35 | 36 | volumes: 37 | db: 38 | driver: local 39 | mysql-db: 40 | driver: local 41 | pgadmin: 42 | driver: local 43 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjectsAsync } from '@nx/jest'; 2 | 3 | export default async () => ({ 4 | projects: await getJestProjectsAsync() 5 | }); -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | 2 | const nxPreset = require('@nx/jest/preset').default; 3 | 4 | module.exports = { ...nxPreset } -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": [ 22 | "error", 23 | { 24 | "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] 25 | } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0-beta.4 (2025-05-24) 2 | 3 | ### 🩹 Fixes 4 | 5 | - **json-api-nestjs-microorm:** Remove @mikro-orm/postgresql dependencies in package.json ([277f61c](https://github.com/klerick/nestjs-json-api/commit/277f61c)) 6 | 7 | ### ❤️ Thank You 8 | 9 | - Alex H 10 | 11 | ## 0.1.0-beta.3 (2025-05-23) 12 | 13 | ### 🚀 Features 14 | 15 | - **json-api-nestjs,json-api-nestjs-microorm,json-api-nestjs-sdk,json-api-nestjs-shared,json-api-nestjs-typeorm:** up nestjs ([42b6b82](https://github.com/klerick/nestjs-json-api/commit/42b6b82)) 16 | 17 | ### ❤️ Thank You 18 | 19 | - Alex H 20 | 21 | ## 0.1.0-beta.0 (2025-05-21) 22 | 23 | ### 🚀 Features 24 | 25 | - **json-api-nestjs-microorm:** Adapter for microorm ([cd56636](https://github.com/klerick/nestjs-json-api/commit/cd56636)) 26 | 27 | ### 🩹 Fixes 28 | 29 | - **json-api-nestjs-typeorm, json-api-nestjs-microorm:** Fix mysql like error ([780bbf9](https://github.com/klerick/nestjs-json-api/commit/780bbf9)) 30 | 31 | ### ❤️ Thank You 32 | 33 | - Alex H 34 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'json-api-nestjs-microorm', 3 | preset: '../../../jest.preset.js', 4 | testEnvironment: 'node', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../../coverage/libs/json-api/json-api-nestjs-microorm', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/json-api-nestjs-microorm", 3 | "version": "0.1.0-beta.4", 4 | "type": "commonjs", 5 | "main": "./src/index.js", 6 | "types": "./src/index.d.ts", 7 | "description": "MicroOrm adapter for JsonApi Plugin for NestJs", 8 | "keywords": [ 9 | "nestjs", 10 | "nest", 11 | "jsonapi", 12 | "json-api", 13 | "typeorm", 14 | "microorm", 15 | "CRUD" 16 | ], 17 | "dependencies": { 18 | "tslib": ">2.3.0", 19 | "reflect-metadata": "^0.1.12 || ^0.2.0", 20 | "rxjs": "^7.1.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/micro-orm-json-api.module'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const ENTITY_METADATA_TOKEN = Symbol('ENTITY_METADATA_TOKEN'); 2 | export const DEFAULT_ARRAY_TYPE = ['ArrayType', 'EnumArrayType']; 3 | export const CURRENT_DATA_SOURCE_TOKEN = Symbol('CURRENT_DATA_SOURCE_TOKEN'); 4 | export const CURRENT_ENTITY_REPOSITORY = Symbol('CURRENT_ENTITY_REPOSITORY'); 5 | export const CURRENT_ENTITY_MANAGER_TOKEN = Symbol( 6 | 'CURRENT_ENTITY_MANAGER_TOKEN' 7 | ); 8 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from './micro-orm-json-api.module'; 2 | export * from './type'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/mock-utils/entities/index.ts: -------------------------------------------------------------------------------- 1 | export * from './users'; 2 | export * from './roles'; 3 | export * from './comments'; 4 | export * from './addresses'; 5 | export * from './user-groups'; 6 | export * from './notes'; 7 | 8 | import { Users } from './users'; 9 | import { Roles } from './roles'; 10 | import { Comments } from './comments'; 11 | import { Addresses } from './addresses'; 12 | import { UserGroups } from './user-groups'; 13 | import { Notes } from './notes'; 14 | 15 | export const Entities = [Users, Roles, Comments, Addresses, UserGroups, Notes]; 16 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/mock-utils/entities/notes.ts: -------------------------------------------------------------------------------- 1 | import { PrimaryKey, Property, Entity, ManyToOne } from '@mikro-orm/core'; 2 | 3 | import { Users, IUsers } from './index'; 4 | 5 | @Entity({ 6 | tableName: 'notes', 7 | }) 8 | export class Notes { 9 | @PrimaryKey({ 10 | type: 'uuid', 11 | defaultRaw: 'gen_random_uuid()', 12 | }) 13 | public id!: string; 14 | 15 | @Property({ 16 | type: 'text', 17 | nullable: false, 18 | }) 19 | public text!: string; 20 | 21 | @Property({ 22 | length: 0, 23 | name: 'created_at', 24 | nullable: true, 25 | defaultRaw: 'CURRENT_TIMESTAMP(0)', 26 | columnType: 'timestamp(0) without time zone', 27 | }) 28 | createdAt: Date = new Date(); 29 | 30 | @Property({ 31 | length: 0, 32 | onUpdate: () => new Date(), 33 | name: 'updated_at', 34 | nullable: true, 35 | columnType: 'timestamp(0) without time zone', 36 | defaultRaw: 'CURRENT_TIMESTAMP(0)', 37 | }) 38 | updatedAt: Date = new Date(); 39 | 40 | @ManyToOne(() => Users, { 41 | fieldName: 'created_by', 42 | }) 43 | public createdBy!: IUsers; 44 | } 45 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/mock-utils/entities/user-groups.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryKey, 3 | OneToMany, 4 | Entity, 5 | Property, 6 | Collection, 7 | } from '@mikro-orm/core'; 8 | 9 | import { Users } from './index'; 10 | 11 | @Entity({ 12 | tableName: 'user_groups', 13 | }) 14 | export class UserGroups { 15 | @PrimaryKey({ 16 | autoincrement: true, 17 | }) 18 | public id!: number; 19 | 20 | @Property({ 21 | type: 'string', 22 | length: 50, 23 | unique: true, 24 | columnType: 'varchar', 25 | }) 26 | public label!: string; 27 | 28 | @OneToMany(() => Users, (item) => item.userGroup) 29 | public users = new Collection(this); 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/mock-utils/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './provider-entities'; 2 | export * from './pull-data'; 3 | export * from './init-db'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/mock-utils/utils/provider-entities.ts: -------------------------------------------------------------------------------- 1 | import { TestingModule } from '@nestjs/testing'; 2 | import { EntityManager } from '@mikro-orm/core'; 3 | import { 4 | Users, 5 | Addresses, 6 | Comments, 7 | Roles, 8 | UserGroups, 9 | Notes, 10 | } from '../entities'; 11 | 12 | export function getRepository(module: TestingModule, emToken: symbol) { 13 | const em = module.get(emToken); 14 | 15 | const userRepository = em.getRepository(Users); 16 | const addressesRepository = em.getRepository(Addresses); 17 | const notesRepository = em.getRepository(Notes); 18 | const commentsRepository = em.getRepository(Comments); 19 | const rolesRepository = em.getRepository(Roles); 20 | const userGroupRepository = em.getRepository(UserGroups); 21 | 22 | return { 23 | userRepository, 24 | addressesRepository, 25 | notesRepository, 26 | commentsRepository, 27 | rolesRepository, 28 | userGroupRepository, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/delete-one/delete-one.ts: -------------------------------------------------------------------------------- 1 | import { MicroOrmService } from '../../service'; 2 | 3 | export async function deleteOne( 4 | this: MicroOrmService, 5 | id: number | string 6 | ): Promise { 7 | const data = await this.microOrmUtilService 8 | .queryBuilder() 9 | .where({ 10 | [this.microOrmUtilService.currentPrimaryColumn]: id, 11 | }) 12 | .getSingleResult(); 13 | 14 | if (!data) return void 0; 15 | 16 | await this.microOrmUtilService.entityManager.removeAndFlush(data); 17 | 18 | return void 0; 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/get-one/get-one.ts: -------------------------------------------------------------------------------- 1 | import { NotFoundException } from '@nestjs/common'; 2 | import { QueryOne, ValidateQueryError } from '@klerick/json-api-nestjs'; 3 | import { wrap } from '@mikro-orm/core'; 4 | import { MicroOrmService } from '../../service'; 5 | 6 | export async function getOne( 7 | this: MicroOrmService, 8 | id: number | string, 9 | query: QueryOne 10 | ): Promise { 11 | const queryBuilder = this.microOrmUtilService.queryBuilder().where({ 12 | [this.microOrmUtilService.currentPrimaryColumn]: id, 13 | }); 14 | 15 | const resultItem = await this.microOrmUtilService 16 | .prePareQueryBuilder(queryBuilder, query as any) 17 | .getSingleResult(); 18 | 19 | if (!resultItem) { 20 | const error: ValidateQueryError = { 21 | code: 'invalid_arguments', 22 | message: `Resource '${this.microOrmUtilService.currentAlias}' with id '${id}' does not exist`, 23 | path: ['fields'], 24 | }; 25 | throw new NotFoundException([error]); 26 | } 27 | 28 | return wrap(resultItem).toJSON() as E; 29 | } 30 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/index.ts: -------------------------------------------------------------------------------- 1 | export * from './get-all/get-all'; 2 | export * from './get-one/get-one'; 3 | export * from './delete-one/delete-one'; 4 | export * from './post-one/post-one'; 5 | export * from './patch-one/patch-one'; 6 | export * from './get-relationship/get-relationship'; 7 | export * from './delete-relationship/delete-relationship'; 8 | export * from './post-relationship/post-relationship'; 9 | export * from './patch-relationship/patch-relationship'; 10 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/post-one/post-one.ts: -------------------------------------------------------------------------------- 1 | import { PostData } from '@klerick/json-api-nestjs'; 2 | import { MicroOrmService } from '../../service'; 3 | 4 | export async function postOne( 5 | this: MicroOrmService, 6 | inputData: PostData 7 | ): Promise { 8 | const { attributes, relationships, id } = inputData; 9 | 10 | const idObject = id 11 | ? { [this.microOrmUtilService.currentPrimaryColumn.toString()]: id } 12 | : {}; 13 | 14 | const attributesObject = { 15 | ...attributes, 16 | ...idObject, 17 | }; 18 | 19 | const entityIns = this.microOrmUtilService.createEntity(attributesObject); 20 | 21 | return this.microOrmUtilService.saveEntity(entityIns, relationships); 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './microorm-service'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/src/lib/type.ts: -------------------------------------------------------------------------------- 1 | export type MicroOrmParam = { 2 | arrayType?: string[]; 3 | }; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "importHelpers": true, 8 | "noImplicitOverride": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "noPropertyAccessFromIndexSignature": true 12 | }, 13 | "files": [], 14 | "include": [], 15 | "references": [ 16 | { 17 | "path": "./tsconfig.lib.json" 18 | }, 19 | { 20 | "path": "./tsconfig.spec.json" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "target": "es2021", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strictBindCallApply": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-microorm/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node10", 7 | "types": [ 8 | "jest", 9 | "node" 10 | ], 11 | "paths": { 12 | "@klerick/json-api-nestjs-shared": [ 13 | "libs/json-api/json-api-nestjs-shared/src/index.ts" 14 | ], 15 | "@klerick/json-api-nestjs": [ 16 | "libs/json-api/json-api-nestjs/src/index.ts" 17 | ] 18 | }, 19 | "allowJs": true 20 | }, 21 | "include": [ 22 | "jest.config.ts", 23 | "src/**/*.test.ts", 24 | "src/**/*.spec.ts", 25 | "src/**/*.d.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": [ 22 | "error", 23 | { 24 | "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] 25 | } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'json-api-nestjs-sdk', 3 | preset: '../../../jest.preset.js', 4 | testEnvironment: 'node', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../../coverage/libs/json-api/json-api-nestjs-sdk', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | FilterOperand, 3 | ResourceObject, 4 | QueryField, 5 | } from '@klerick/json-api-nestjs-shared'; 6 | 7 | export { JsonApiUtilsService, JsonApiSdkService } from './lib/service'; 8 | export * from './lib/json-api-js'; 9 | export { adapterForAxios } from './lib/utils'; 10 | export { AtomicOperations, Operands, QueryParams } from './lib/types'; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const ID_KEY = 'id'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './json-api-utils.service'; 2 | export * from './atomic-operations.service'; 3 | export * from './json-api-sdk.service'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/token/index.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | import { JsonApiSdkConfig, AtomicFactory as TypeAtomicFactory } from '../types'; 4 | 5 | export const JSON_API_SDK_CONFIG = new InjectionToken( 6 | 'Main config object for sdk' 7 | ); 8 | 9 | export const AtomicFactory = new InjectionToken( 10 | 'AtomicFactory' 11 | ); 12 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/atomic-type.ts: -------------------------------------------------------------------------------- 1 | import { 2 | KEY_MAIN_INPUT_SCHEMA, 3 | KEY_MAIN_OUTPUT_SCHEMA, 4 | Operation, 5 | ResourceObject, 6 | } from '@klerick/json-api-nestjs-shared'; 7 | import { AtomicMainOperations } from './atomic-operation'; 8 | 9 | export type BodyType = { 10 | op: Operation; 11 | ref: { 12 | type: string; 13 | id?: string; 14 | relationship?: string; 15 | tmpId?: string; 16 | }; 17 | data?: any; 18 | }; 19 | 20 | export type AtomicBody = { 21 | [KEY_MAIN_INPUT_SCHEMA]: BodyType[]; 22 | }; 23 | export type AtomicResponse = { 24 | [KEY_MAIN_OUTPUT_SCHEMA]: { 25 | [K in keyof R]: R[K] extends object ? ResourceObject : never; 26 | }; 27 | }; 28 | 29 | export type AtomicVoidOperation = { 30 | [K in keyof AtomicMainOperations<[]>]: (...arg: any) => void; 31 | }; 32 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/config.ts: -------------------------------------------------------------------------------- 1 | import { PartialByKeys } from './utils'; 2 | import { HttpInnerClient } from './http-inner-client'; 3 | 4 | export type JsonApiSdkConfig = { 5 | apiHost: string; 6 | apiPrefix?: string; 7 | idKey: string; 8 | idIsNumber?: boolean; 9 | operationUrl?: string; 10 | dateFields: string[]; 11 | }; 12 | 13 | export type JsonSdkConfig = PartialByKeys< 14 | JsonApiSdkConfig, 15 | 'idKey' | 'apiPrefix' | 'idIsNumber' | 'dateFields' | 'operationUrl' 16 | >; 17 | 18 | export type JsonConfig = JsonSdkConfig & { 19 | adapter?: HttpInnerClient; 20 | }; 21 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/filter-operand.ts: -------------------------------------------------------------------------------- 1 | import { FilterOperand } from '@klerick/json-api-nestjs-shared'; 2 | 3 | export type FilterOperandForString = Exclude< 4 | FilterOperand, 5 | FilterOperand.in | FilterOperand.nin | FilterOperand.some 6 | >; 7 | 8 | export type Operands = { 9 | [P in FilterOperand]?: P extends FilterOperandForString ? string : string[]; 10 | }; 11 | 12 | export type OperandsRelation = 13 | | { 14 | [FilterOperand.eq]: null; 15 | } 16 | | { 17 | [FilterOperand.ne]: null; 18 | }; 19 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/http-request-params.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MainData, 3 | BaseAttribute, 4 | RelationKeys, 5 | BaseMainData, 6 | } from '@klerick/json-api-nestjs-shared'; 7 | 8 | export type Relationships< 9 | Entity extends object, 10 | IdKey extends string = 'id' 11 | > = { 12 | [P in RelationKeys]?: BaseMainData; 13 | }; 14 | 15 | export type BaseRelationships< 16 | Entity extends object, 17 | IdKey extends string = 'id' 18 | > = { relationships?: Relationships }; 19 | 20 | type PostMainData = Omit, 'id'> & { 21 | id?: string; 22 | }; 23 | 24 | export type PostData = { 25 | data: PostMainData & BaseAttribute & BaseRelationships; 26 | }; 27 | 28 | export type PatchData = { 29 | data: MainData & BaseAttribute & BaseRelationships; 30 | }; 31 | 32 | export type RelationBodyData = { 33 | data: MainData | MainData[]; 34 | }; 35 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './http-inner-client'; 2 | export * from './http-request-params'; 3 | export * from './atomic-type'; 4 | export * from './atomic-operation'; 5 | export * from './utils'; 6 | export * from './config'; 7 | export * from './query-params'; 8 | export * from './promise-json-api-sdk'; 9 | export * from './filter-operand'; 10 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/types/utils.ts: -------------------------------------------------------------------------------- 1 | export type ReturnIfArray = I extends unknown[] ? O[] : O; 2 | 3 | export type PartialByKeys = Omit & 4 | Partial>; 5 | 6 | export type FunctionProperty = T[K] extends ( 7 | ...args: any 8 | ) => any 9 | ? T[K] 10 | : never; 11 | 12 | export type FunctionPropertyNames = { 13 | [K in keyof T]: T[K] extends (...args: any) => any ? K : never; 14 | }[keyof T]; 15 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/utils/entity-array.ts: -------------------------------------------------------------------------------- 1 | import { PageProps } from '@klerick/json-api-nestjs-shared'; 2 | 3 | export class EntityArray extends Array { 4 | constructor(items: T[], private pageProps: PageProps) { 5 | super(...items); 6 | Object.defineProperty(this, 'pageProps', { 7 | writable: false, 8 | enumerable: false, 9 | value: pageProps, 10 | }); 11 | } 12 | 13 | static override get [Symbol.species]() { 14 | return Array; 15 | } 16 | 17 | get totalItems() { 18 | return this.pageProps.totalItems; 19 | } 20 | 21 | get pageSize() { 22 | return this.pageProps.pageSize; 23 | } 24 | 25 | get pageNumber() { 26 | return this.pageProps.pageNumber; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './http-params'; 2 | export * from './generate-atomic-body'; 3 | export * from './entity-array'; 4 | export * from './utils'; 5 | export * from './adapter-for-axios'; 6 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/lib/utils/utils.ts: -------------------------------------------------------------------------------- 1 | import { kebabCase } from 'change-case-commonjs'; 2 | 3 | import { ID_KEY } from '../constants'; 4 | import { JsonApiSdkConfig, JsonSdkConfig } from '../types'; 5 | 6 | export function isRelation(val: any): boolean { 7 | const result = !( 8 | val === null || 9 | !val || 10 | ['String', 'Boolean', 'Number', 'Date'].includes(val.constructor.name) 11 | ); 12 | 13 | if (!result) return result; 14 | return ID_KEY in val; 15 | } 16 | 17 | export function getTypeForReq(str: string): string { 18 | return kebabCase(str).toLowerCase(); 19 | } 20 | 21 | export function resultConfig(partialConfig: JsonSdkConfig): JsonApiSdkConfig { 22 | return { 23 | ...partialConfig, 24 | idKey: partialConfig.idKey ? partialConfig.idKey : ID_KEY, 25 | idIsNumber: 26 | partialConfig.idIsNumber === undefined 27 | ? true 28 | : !!partialConfig.idIsNumber, 29 | dateFields: partialConfig.dateFields ? partialConfig.dateFields : [], 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/src/ngModule.ts: -------------------------------------------------------------------------------- 1 | export { FilterOperand, ResourceObject } from '@klerick/json-api-nestjs-shared'; 2 | 3 | export { 4 | AtomicFactory, 5 | provideJsonApi, 6 | JSON_API_SDK_CONFIG, 7 | getProviders, 8 | } from './lib/json-api-angular'; 9 | export { JsonApiUtilsService, JsonApiSdkService } from './lib/service'; 10 | export { AtomicOperations, JsonSdkConfig } from './lib/types'; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/tsconfig-mjs.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "module": "es2015", 7 | "target": "ES2022", 8 | "types": [ 9 | "node" 10 | ] 11 | }, 12 | "include": [ 13 | "src/**/*.ts" 14 | ], 15 | "exclude": [ 16 | "jest.config.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test-d.ts", 19 | "src/**/___test___/**/*.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "importHelpers": true, 8 | "noImplicitOverride": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "noPropertyAccessFromIndexSignature": true 12 | }, 13 | "files": [], 14 | "include": [], 15 | "references": [ 16 | { 17 | "path": "./tsconfig.lib.json" 18 | }, 19 | { 20 | "path": "./tsconfig-mjs.lib.json" 21 | }, 22 | { 23 | "path": "./tsconfig.spec.json" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-sdk/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node10", 7 | "types": ["jest", "node"], 8 | "paths": { 9 | "@klerick/json-api-nestjs-shared": [ 10 | "libs/json-api/json-api-nestjs-shared/src/index.ts" 11 | ] 12 | }, 13 | "allowJs": true 14 | }, 15 | "include": [ 16 | "jest.config.ts", 17 | "src/**/*.test.ts", 18 | "src/**/*.spec.ts", 19 | "src/**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": [ 22 | "error", 23 | { 24 | "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] 25 | } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0-beta.3 (2025-05-23) 2 | 3 | ### 🚀 Features 4 | 5 | - **json-api-nestjs,json-api-nestjs-microorm,json-api-nestjs-sdk,json-api-nestjs-shared,json-api-nestjs-typeorm:** up nestjs ([42b6b82](https://github.com/klerick/nestjs-json-api/commit/42b6b82)) 6 | 7 | ### ❤️ Thank You 8 | 9 | - Alex H 10 | 11 | ## 1.0.0-beta.0 (2025-05-21) 12 | 13 | ### 🚀 Features 14 | 15 | - **json-api-nestjs-shared:** Use new structure ([4359ac7](https://github.com/klerick/nestjs-json-api/commit/4359ac7)) 16 | - **json-api-nestjs-shared:** Use shared type from separate package ([1a1c859](https://github.com/klerick/nestjs-json-api/commit/1a1c859)) 17 | - **json-api-nestjs:** Microro orm ([4696f51](https://github.com/klerick/nestjs-json-api/commit/4696f51)) 18 | 19 | ### ❤️ Thank You 20 | 21 | - Alex H 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/README.md: -------------------------------------------------------------------------------- 1 | # json-api-nestjs-shared 2 | 3 | Helper module for **[json-api-nestjs](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-api/json-api-nestjs)** 4 | 5 | ## Installation 6 | 7 | ```bash 8 | $ npm install @klerick/json-api-nestjs-shared 9 | ``` 10 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'json-api-nestjs-shared', 3 | preset: '../../../jest.preset.js', 4 | testEnvironment: 'node', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../../coverage/libs/json-api/json-api-nestjs-shared', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/json-api-nestjs-shared", 3 | "version": "1.0.0-beta.3", 4 | "description": "Shared Helper for JsonApi Plugin for NestJs", 5 | "keywords": [ 6 | "nestjs", 7 | "nest", 8 | "jsonapi", 9 | "json-api", 10 | "typeorm", 11 | "microorm", 12 | "CRUD" 13 | ], 14 | "dependencies": { 15 | "tslib": ">2.3.0", 16 | "reflect-metadata": "^0.1.12 || ^0.2.0", 17 | "rxjs": "^7.1.0" 18 | }, 19 | "type": "commonjs", 20 | "main": "./cjs/src/index.js", 21 | "types": "./cjs/src/index.d.ts", 22 | "module": "./mjs/src/index.js" 23 | } 24 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/utils'; 2 | export * from './lib/types'; 3 | export * from './lib/constants'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const KEY_MAIN_INPUT_SCHEMA = 'atomic:operations'; 2 | export const KEY_MAIN_OUTPUT_SCHEMA = 'atomic:results'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/lib/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './query-type'; 2 | export * from './entity-type'; 3 | export * from './response-body'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/lib/types/query-type.ts: -------------------------------------------------------------------------------- 1 | export enum QueryField { 2 | filter = 'filter', 3 | sort = 'sort', 4 | include = 'include', 5 | page = 'page', 6 | fields = 'fields', 7 | } 8 | 9 | export enum FilterOperand { 10 | eq = 'eq', 11 | gt = 'gt', 12 | gte = 'gte', 13 | like = 'like', 14 | lt = 'lt', 15 | lte = 'lte', 16 | ne = 'ne', 17 | regexp = 'regexp', 18 | in = 'in', 19 | nin = 'nin', 20 | some = 'some', 21 | } 22 | 23 | export enum FilterOperandOnlyInNin { 24 | in = 'in', 25 | nin = 'nin', 26 | } 27 | export enum FilterOperandOnlySimple { 28 | eq = 'eq', 29 | gt = 'gt', 30 | gte = 'gte', 31 | like = 'like', 32 | lt = 'lt', 33 | lte = 'lte', 34 | ne = 'ne', 35 | regexp = 'regexp', 36 | } 37 | 38 | export enum Operation { 39 | add = 'add', 40 | update = 'update', 41 | remove = 'remove', 42 | } 43 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './object-utils'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/src/lib/utils/object-utils.spec.ts: -------------------------------------------------------------------------------- 1 | import { getEntityName } from './object-utils'; 2 | 3 | describe('object utils', () => { 4 | it('getEntityName', () => { 5 | expect(getEntityName('Entity')).toBe('Entity'); 6 | expect(getEntityName(class EntityClass {})).toBe('EntityClass'); 7 | class EntityClassInst {} 8 | const tmp = new EntityClassInst(); 9 | expect(getEntityName(tmp as any)).toBe('EntityClassInst'); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/tsconfig-mjs.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "types": [ 5 | "node" 6 | ], 7 | "module": "es2015", 8 | "target": "ES2022", 9 | "removeComments": false, 10 | "declaration": true 11 | }, 12 | "include": [ 13 | "src/**/*.ts" 14 | ], 15 | "exclude": [ 16 | "jest.config.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test-d.ts", 19 | "src/**/___test___/**/*.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "noPropertyAccessFromIndexSignature": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": [ 7 | "node" 8 | ], 9 | "target": "es2021", 10 | "strictNullChecks": true, 11 | "noImplicitAny": true, 12 | "strictBindCallApply": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "noFallthroughCasesInSwitch": true 15 | }, 16 | "include": [ 17 | "src/**/*.ts" 18 | ], 19 | "exclude": [ 20 | "jest.config.ts", 21 | "src/**/*.spec.ts", 22 | "src/**/*.test.ts", 23 | "src/**/*.test-d.ts", 24 | "src/lib/utils/___test___/**/*.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-shared/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node10", 7 | "types": ["jest", "node"], 8 | "allowJs": true 9 | }, 10 | "include": [ 11 | "jest.config.ts", 12 | "src/**/*.test.ts", 13 | "src/**/*.spec.ts", 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": [ 22 | "error", 23 | { 24 | "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] 25 | } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0-beta.3 (2025-05-23) 2 | 3 | ### 🚀 Features 4 | 5 | - **json-api-nestjs,json-api-nestjs-microorm,json-api-nestjs-sdk,json-api-nestjs-shared,json-api-nestjs-typeorm:** up nestjs ([42b6b82](https://github.com/klerick/nestjs-json-api/commit/42b6b82)) 6 | 7 | ### ❤️ Thank You 8 | 9 | - Alex H 10 | 11 | ## 0.1.0-beta.0 (2025-05-21) 12 | 13 | ### 🚀 Features 14 | 15 | - **json-api-nestjs-typeorm:** Adapter for typerorm ([f25d319](https://github.com/klerick/nestjs-json-api/commit/f25d319)) 16 | 17 | ### 🩹 Fixes 18 | 19 | - **json-api-nestjs-typeorm, json-api-nestjs-microorm:** Fix mysql like error ([780bbf9](https://github.com/klerick/nestjs-json-api/commit/780bbf9)) 20 | 21 | ### ❤️ Thank You 22 | 23 | - Alex H 24 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/README.md: -------------------------------------------------------------------------------- 1 | # json-api-nestjs-typeorm 2 | 3 | TypeOrm adapter for **[json-api-nestjs](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-api/json-api-nestjs)** 4 | 5 | ## Installation 6 | 7 | ```bash 8 | $ npm install @klerick/json-api-nestjs-typeorm 9 | ``` 10 | 11 | 12 | ## Configuration params 13 | 14 | The following interface is using for the configuration: 15 | 16 | ```typescript 17 | export type TypeOrmParam = { 18 | useSoftDelete?: boolean // Use soft delete 19 | runInTransaction?: any>( 20 | isolationLevel: IsolationLevel, 21 | fn: Func 22 | ) => ReturnType // You can use cutom function for wrapping transaction in atomic operation, example: runInTransaction from https://github.com/Aliheym/typeorm-transactional 23 | }; 24 | ``` 25 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'json-api-nestjs-typeorm', 3 | preset: '../../../jest.preset.js', 4 | testEnvironment: 'node', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../../coverage/libs/json-api/json-api-nestjs-typeorm', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/json-api-nestjs-typeorm", 3 | "version": "0.1.0-beta.3", 4 | "dependencies": { 5 | "tslib": ">2.3.0", 6 | "reflect-metadata": "^0.1.12 || ^0.2.0", 7 | "rxjs": "^7.1.0" 8 | }, 9 | "type": "commonjs", 10 | "main": "./src/index.js", 11 | "typings": "./src/index.d.ts", 12 | "description": "MicroOrm adapter for JsonApi Plugin for NestJs", 13 | "keywords": [ 14 | "nestjs", 15 | "nest", 16 | "jsonapi", 17 | "json-api", 18 | "typeorm", 19 | "microorm", 20 | "CRUD" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/type-orm-json-api.module'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const SUB_QUERY_ALIAS_FOR_PAGINATION = 'subQueryWithLimitOffset'; 2 | export const ALIAS_FOR_PAGINATION = 'aliasForPagination'; 3 | export const DEFAULT_CONNECTION_NAME = 'default'; 4 | export const CURRENT_ENTITY_REPOSITORY = Symbol('CURRENT_ENTITY_REPOSITORY'); 5 | export const CURRENT_DATA_SOURCE_TOKEN = Symbol('CURRENT_DATA_SOURCE_TOKEN'); 6 | export const CURRENT_ENTITY_MANAGER_TOKEN = Symbol( 7 | 'CURRENT_ENTITY_MANAGER_TOKEN' 8 | ); 9 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type-orm-json-api.module'; 2 | export * from './type'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/mock-utils/entities/index.ts: -------------------------------------------------------------------------------- 1 | export * from './users'; 2 | export * from './roles'; 3 | export * from './comments'; 4 | export * from './addresses'; 5 | export * from './user-groups'; 6 | export * from './notes'; 7 | export * from './pods'; 8 | 9 | import { Users } from './users'; 10 | import { Roles } from './roles'; 11 | import { Comments } from './comments'; 12 | import { Addresses } from './addresses'; 13 | import { UserGroups } from './user-groups'; 14 | import { Notes } from './notes'; 15 | import { Pods } from './pods'; 16 | 17 | export const Entities = [ 18 | Users, 19 | Roles, 20 | Comments, 21 | Addresses, 22 | UserGroups, 23 | Notes, 24 | Pods, 25 | ]; 26 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/mock-utils/entities/notes.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryGeneratedColumn, 3 | Column, 4 | Entity, 5 | JoinColumn, 6 | ManyToOne, 7 | UpdateDateColumn, 8 | } from 'typeorm'; 9 | 10 | import { Users, IUsers } from './index'; 11 | 12 | @Entity('notes') 13 | export class Notes { 14 | @PrimaryGeneratedColumn('uuid') 15 | public id!: string; 16 | 17 | @Column({ 18 | type: 'text', 19 | nullable: false, 20 | }) 21 | public text!: string; 22 | 23 | @Column({ 24 | name: 'created_at', 25 | type: 'timestamp', 26 | nullable: true, 27 | default: () => 'CURRENT_TIMESTAMP(0)', 28 | }) 29 | public createdAt!: Date; 30 | 31 | @UpdateDateColumn({ 32 | name: 'updated_at', 33 | type: 'timestamp', 34 | nullable: true, 35 | default: () => 'CURRENT_TIMESTAMP(0)', 36 | }) 37 | public updatedAt!: Date; 38 | 39 | @ManyToOne(() => Users, (item) => item.notes) 40 | @JoinColumn({ 41 | name: 'created_by', 42 | }) 43 | public createdBy!: IUsers; 44 | } 45 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/mock-utils/entities/pods.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Column, 3 | CreateDateColumn, 4 | Entity, 5 | PrimaryColumn, 6 | UpdateDateColumn, 7 | } from 'typeorm'; 8 | 9 | export type IPods = Pods; 10 | 11 | @Entity('pods') 12 | export class Pods { 13 | @PrimaryColumn() 14 | public id!: string; 15 | 16 | @Column({ 17 | type: 'varchar', 18 | length: 50, 19 | nullable: false, 20 | unique: true, 21 | }) 22 | public name!: string; 23 | 24 | @CreateDateColumn({ 25 | name: 'created_at', 26 | type: 'timestamp', 27 | nullable: true, 28 | default: () => 'CURRENT_TIMESTAMP(0)', 29 | }) 30 | public createdAt!: Date; 31 | 32 | @UpdateDateColumn({ 33 | name: 'updated_at', 34 | type: 'timestamp', 35 | nullable: true, 36 | default: () => 'CURRENT_TIMESTAMP(0)', 37 | }) 38 | public updatedAt!: Date; 39 | } 40 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/mock-utils/entities/user-groups.ts: -------------------------------------------------------------------------------- 1 | import { PrimaryGeneratedColumn, OneToMany, Entity, Column } from 'typeorm'; 2 | 3 | import { IUsers, Users } from './index'; 4 | 5 | @Entity('user_groups') 6 | export class UserGroups { 7 | @PrimaryGeneratedColumn() 8 | public id!: number; 9 | 10 | @Column({ 11 | type: 'varchar', 12 | length: 50, 13 | nullable: false, 14 | unique: true, 15 | }) 16 | public label!: string; 17 | 18 | @OneToMany(() => Users, (item) => item.userGroup) 19 | public users!: IUsers[]; 20 | } 21 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/orm-methods/delete-one/delete-one.ts: -------------------------------------------------------------------------------- 1 | import { FindOptionsWhere } from 'typeorm'; 2 | import { TypeOrmService } from '../../service'; 3 | 4 | export async function deleteOne( 5 | this: TypeOrmService, 6 | id: number | string 7 | ): Promise { 8 | const data = await this.repository.findOne({ 9 | where: { 10 | [this.typeormUtilsService.currentPrimaryColumn.toString()]: id, 11 | } as FindOptionsWhere, 12 | }); 13 | if (!data) return void 0; 14 | 15 | this.config.useSoftDelete 16 | ? await this.repository.softRemove(data) 17 | : await this.repository.remove(data); 18 | 19 | return void 0; 20 | } 21 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/orm-methods/delete-relationship/delete-relationship.ts: -------------------------------------------------------------------------------- 1 | import { PostRelationshipData } from '@klerick/json-api-nestjs'; 2 | import { RelationKeys } from '@klerick/json-api-nestjs-shared'; 3 | 4 | import { TypeOrmService } from '../../service'; 5 | 6 | export async function deleteRelationship< 7 | E extends object, 8 | IdKey extends string, 9 | Rel extends RelationKeys 10 | >( 11 | this: TypeOrmService, 12 | id: number | string, 13 | rel: Rel, 14 | input: PostRelationshipData 15 | ): Promise { 16 | const idsResult = await this.typeormUtilsService.validateRelationInputData( 17 | rel, 18 | input 19 | ); 20 | const postBuilder = this.repository 21 | .createQueryBuilder() 22 | .relation(rel.toString()) 23 | .of(id); 24 | 25 | if (Array.isArray(idsResult)) { 26 | await postBuilder.remove(idsResult); 27 | } else { 28 | await postBuilder.set(null); 29 | } 30 | return void 0; 31 | } 32 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/orm-methods/index.ts: -------------------------------------------------------------------------------- 1 | export { getAll } from './get-all/get-all'; 2 | export { getOne } from './get-one/get-one'; 3 | export { deleteOne } from './delete-one/delete-one'; 4 | export { postOne } from './post-one/post-one'; 5 | export { patchOne } from './patch-one/patch-one'; 6 | export { getRelationship } from './get-relationship/get-relationship'; 7 | export { postRelationship } from './post-relationship/post-relationship'; 8 | export { deleteRelationship } from './delete-relationship/delete-relationship'; 9 | export { patchRelationship } from './patch-relationship/patch-relationship'; 10 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/src/lib/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type-orm.service'; 2 | export * from './typeorm-utils.service'; 3 | export * from './type-orm-format.error.service'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "noPropertyAccessFromIndexSignature": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "target": "es2023", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strictBindCallApply": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/lib/mock-utils/**/*.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs-typeorm/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node10", 7 | "types": ["jest", "node"], 8 | "paths": { 9 | "@klerick/json-api-nestjs-shared": [ 10 | "libs/json-api/json-api-nestjs-shared/src/index.ts" 11 | ], 12 | "@klerick/json-api-nestjs": [ 13 | "libs/json-api/json-api-nestjs/src/index.ts" 14 | ] 15 | }, 16 | "allowJs": true 17 | }, 18 | "include": [ 19 | "jest.config.ts", 20 | "src/**/*.test.ts", 21 | "src/**/*.spec.ts", 22 | "src/**/*.d.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": [ 22 | "error", 23 | { 24 | "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] 25 | } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'json-api-nestjs', 4 | preset: '../../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../../coverage/libs/json-api/json-api-nestjs', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/json-api-nestjs", 3 | "version": "10.0.0-beta.5", 4 | "type": "commonjs", 5 | "description": "JsonApi Plugin for NestJs", 6 | "keywords": [ 7 | "nestjs", 8 | "nest", 9 | "jsonapi", 10 | "json-api", 11 | "typeorm", 12 | "microorm", 13 | "CRUD" 14 | ], 15 | "dependencies": { 16 | "tslib": ">2.3.0", 17 | "reflect-metadata": "^0.1.12 || ^0.2.0", 18 | "rxjs": "^7.1.0", 19 | "@klerick/json-api-nestjs-shared": "0.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/constants/constants.ts: -------------------------------------------------------------------------------- 1 | export const JSON_API_CONTROLLER_POSTFIX = 'JsonApiController'; 2 | export const JSON_API_MODULE_POSTFIX = 'JsonApiModule'; 3 | export const DEFAULT_CONNECTION_NAME = 'default'; 4 | export const ORM_SERVICE_PROPS = Symbol('ORM_SERVICE_PROPS'); 5 | export const PARAMS_RESOURCE_ID = 'id'; 6 | export const PARAMS_RELATION_NAME = 'relName'; 7 | export const DESC = 'DESC'; 8 | export const ASC = 'ASC'; 9 | 10 | export const SORT_TYPE = [DESC, ASC] as const; 11 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/constants/default.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_QUERY_PAGE = 1; 2 | export const DEFAULT_PAGE_SIZE = 20; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/constants/di.ts: -------------------------------------------------------------------------------- 1 | export const ORM_SERVICE = Symbol('ORM_SERVICE'); 2 | 3 | export const MODULE_OPTIONS_TOKEN = Symbol('MODULE_OPTIONS_TOKEN'); 4 | export const CONTROLLER_OPTIONS_TOKEN = Symbol('CONTROLLER_OPTIONS_TOKEN'); 5 | 6 | export const CURRENT_ENTITY = Symbol('CURRENT_ENTITY'); 7 | export const ENTITY_PARAM_MAP = Symbol('ENTITY_PARAM_MAP'); 8 | 9 | export const ZOD_INPUT_QUERY_SCHEMA = Symbol('ZOD_INPUT_QUERY_SCHEMA'); 10 | export const ZOD_QUERY_SCHEMA = Symbol('ZOD_INPUT_QUERY_SCHEMA'); 11 | export const ZOD_POST_SCHEMA = Symbol('ZOD_POST_SCHEMA'); 12 | export const ZOD_PATCH_SCHEMA = Symbol('ZOD_PATCH_SCHEMA'); 13 | export const ZOD_POST_RELATIONSHIP_SCHEMA = Symbol( 14 | 'ZOD_POST_RELATIONSHIP_SCHEMA' 15 | ); 16 | export const ZOD_PATCH_RELATIONSHIP_SCHEMA = Symbol( 17 | 'ZOD_PATCH_RELATIONSHIP_SCHEMA' 18 | ); 19 | 20 | export const FIND_ONE_ROW_ENTITY = Symbol('FIND_ONE_ROW_ENTITY'); 21 | export const CHECK_RELATION_NAME = Symbol('CHECK_RELATION_NAME'); 22 | export const RUN_IN_TRANSACTION_FUNCTION = Symbol( 23 | 'RUN_IN_TRANSACTION_FUNCTION' 24 | ); 25 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './default'; 2 | export * from './reflection'; 3 | export * from './di'; 4 | export * from './constants'; 5 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/constants/reflection.ts: -------------------------------------------------------------------------------- 1 | export const JSON_API_DECORATOR_ENTITY = Symbol('JSON_API_ENTITY'); 2 | export const JSON_API_DECORATOR_OPTIONS = Symbol('JSON_API_OPTIONS'); 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const MAP_CONTROLLER_ENTITY = Symbol('MAP_CONTROLLER_ENTITY'); 2 | export const MAP_CONTROLLER_INTERCEPTORS = Symbol( 3 | 'MAP_CONTROLLER_INTERCEPTORS' 4 | ); 5 | export const MAP_ENTITY = Symbol('MAP_ENTITY'); 6 | export const ZOD_INPUT_OPERATION = Symbol('ZOD_INPUT_OPERATION'); 7 | export const ASYNC_ITERATOR_FACTORY = Symbol('ASYNC_ITERATOR_FACTORY'); 8 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/controllers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './operation.controller'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/factory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './async-iterator'; 2 | export * from './map-controller-entity'; 3 | export * from './map-entity-name-to-entity'; 4 | export * from './zod-input-operation'; 5 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/factory/map-controller-entity.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, ValueProvider } from '@nestjs/common'; 2 | import { Type } from '@nestjs/common/interfaces/type.interface'; 3 | import { AnyEntity, EntityClass } from '@klerick/json-api-nestjs-shared'; 4 | import { MapController } from '../types'; 5 | import { MAP_CONTROLLER_ENTITY } from '../constants'; 6 | 7 | export function MapControllerEntity( 8 | entities: EntityClass[], 9 | entityModules: DynamicModule[] 10 | ): ValueProvider { 11 | const mapController = entities.reduce((acum, entity, index) => { 12 | const entityModule = entityModules[index]; 13 | if (entityModule.controllers) { 14 | const controller = entityModule.controllers.at(0); 15 | if (controller) acum.set(entity, controller); 16 | } 17 | 18 | return acum; 19 | }, new Map, Type>()); 20 | 21 | return { 22 | provide: MAP_CONTROLLER_ENTITY, 23 | useValue: mapController, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/factory/map-entity-name-to-entity.ts: -------------------------------------------------------------------------------- 1 | import { ValueProvider } from '@nestjs/common'; 2 | import { 3 | getEntityName, 4 | AnyEntity, 5 | EntityClass, 6 | } from '@klerick/json-api-nestjs-shared'; 7 | import { kebabCase } from 'change-case-commonjs'; 8 | import { MapEntity } from '../types'; 9 | import { MAP_ENTITY } from '../constants'; 10 | 11 | export function MapEntityNameToEntity( 12 | entities: EntityClass[] 13 | ): ValueProvider { 14 | return { 15 | provide: MAP_ENTITY, 16 | useValue: entities.reduce( 17 | (acum, item) => acum.set(kebabCase(getEntityName(item)), item), 18 | new Map>() 19 | ), 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/factory/zod-input-operation.ts: -------------------------------------------------------------------------------- 1 | import { FactoryProvider } from '@nestjs/common'; 2 | import { AnyEntity, EntityClass } from '@klerick/json-api-nestjs-shared'; 3 | import { MAP_CONTROLLER_ENTITY, ZOD_INPUT_OPERATION } from '../constants'; 4 | import { MapController } from '../types'; 5 | import { zodInputOperation, ZodInputOperation } from '../utils'; 6 | import { ENTITY_PARAM_MAP } from '../../../constants'; 7 | import { EntityParamMap } from '../../mixin/types'; 8 | 9 | export function ZodInputOperation(): FactoryProvider< 10 | ZodInputOperation 11 | > { 12 | return { 13 | provide: ZOD_INPUT_OPERATION, 14 | useFactory( 15 | mapController: MapController, 16 | entityMapProps: EntityParamMap> 17 | ) { 18 | return zodInputOperation(mapController, entityMapProps); 19 | }, 20 | inject: [MAP_CONTROLLER_ENTITY, ENTITY_PARAM_MAP], 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/pipes/input-operation.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { KEY_MAIN_INPUT_SCHEMA } from '@klerick/json-api-nestjs-shared'; 8 | import { errorMap } from 'zod-validation-error'; 9 | import { ZodError } from 'zod'; 10 | import { JSONValue } from '../../mixin/types'; 11 | import { InputArray, ZodInputOperation } from '../utils'; 12 | import { ZOD_INPUT_OPERATION } from '../constants'; 13 | 14 | export class InputOperationPipe 15 | implements PipeTransform 16 | { 17 | @Inject(ZOD_INPUT_OPERATION) 18 | private zodInputOperation!: ZodInputOperation; 19 | 20 | transform(value: JSONValue): InputArray { 21 | try { 22 | return this.zodInputOperation.parse(value, { 23 | errorMap: errorMap, 24 | })[KEY_MAIN_INPUT_SCHEMA]; 25 | } catch (e) { 26 | if (e instanceof ZodError) { 27 | throw new BadRequestException(e.issues); 28 | } 29 | 30 | throw new InternalServerErrorException(e); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './execute.service'; 2 | export * from './swagger.service'; 3 | export * from './explorer.service'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/types/index.ts: -------------------------------------------------------------------------------- 1 | import { NestInterceptor, Type } from '@nestjs/common'; 2 | import { Module } from '@nestjs/core/injector/module'; 3 | import { Controller } from '@nestjs/common/interfaces'; 4 | import { EntityClass } from '@klerick/json-api-nestjs-shared'; 5 | import { JsonBaseController } from '../../mixin/controllers'; 6 | 7 | export type MapControllerInterceptor = Map< 8 | Controller, 9 | Map<(...arg: any) => any, NestInterceptor[]> 10 | >; 11 | export type MapController = Map< 12 | EntityClass, 13 | Type 14 | >; 15 | export type MapEntity = Map>; 16 | 17 | export type OperationMethode = keyof Omit< 18 | { [k in keyof JsonBaseController]: string }, 19 | 'getAll' | 'getOne' | 'getRelationship' 20 | >; 21 | 22 | export type ParamsForExecute< 23 | E extends object = object, 24 | O extends OperationMethode = OperationMethode 25 | > = { 26 | methodName: O; 27 | controller: Type>; 28 | params: Parameters[O]>; 29 | module: Module; 30 | }; 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/atomic-operation/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './zod/zod-helper'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mixin/mixin.module'; 2 | export * from './atomic-operation/atomic-operation.module'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/controllers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './json-base.controller'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './json-api/json-api.decorator'; 2 | export * from './inject-service/inject-service.decorator'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/decorators/inject-service/inject-service.decorator.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PROPERTY_DEPS_METADATA, 3 | SELF_DECLARED_DEPS_METADATA, 4 | } from '@nestjs/common/constants'; 5 | import 'reflect-metadata'; 6 | 7 | import { InjectService } from './inject-service.decorator'; 8 | import { ORM_SERVICE } from '../../../../constants'; 9 | 10 | describe('InjectServiceDecorator', () => { 11 | it('should save property key', () => { 12 | class SomeClass { 13 | @InjectService() protected property: any; 14 | constructor(@InjectService() protected test: any) {} 15 | } 16 | 17 | const properties = Reflect.getMetadata(PROPERTY_DEPS_METADATA, SomeClass); 18 | const properties1 = Reflect.getMetadata( 19 | SELF_DECLARED_DEPS_METADATA, 20 | SomeClass 21 | ); 22 | expect( 23 | properties.find((item: any) => item.type === ORM_SERVICE) 24 | ).toBeDefined(); 25 | 26 | expect( 27 | properties1.find((item: any) => item.param === ORM_SERVICE) 28 | ).toBeDefined(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/decorators/inject-service/inject-service.decorator.ts: -------------------------------------------------------------------------------- 1 | import { Inject } from '@nestjs/common'; 2 | 3 | import { ORM_SERVICE } from '../../../../constants'; 4 | 5 | export function InjectService(): PropertyDecorator & ParameterDecorator { 6 | return Inject(ORM_SERVICE); 7 | } 8 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/decorators/json-api/json-api.decorator.ts: -------------------------------------------------------------------------------- 1 | import { AnyEntity, EntityClass } from '@klerick/json-api-nestjs-shared'; 2 | import { 3 | JSON_API_DECORATOR_ENTITY, 4 | JSON_API_DECORATOR_OPTIONS, 5 | } from '../../../../constants'; 6 | import { DecoratorOptions } from '../../types'; 7 | 8 | export function JsonApi( 9 | entity: EntityClass, 10 | options?: DecoratorOptions 11 | ): ClassDecorator { 12 | return (target): typeof target => { 13 | Reflect.defineMetadata(JSON_API_DECORATOR_ENTITY, entity, target); 14 | if (options) { 15 | Reflect.defineMetadata(JSON_API_DECORATOR_OPTIONS, options, target); 16 | } 17 | return target; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/factory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './zod-validate.factory'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils'; 2 | export * from './create-controller'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/helpers/utils.spec.ts: -------------------------------------------------------------------------------- 1 | import { getEntityName } from '@klerick/json-api-nestjs-shared'; 2 | 3 | import { nameIt, excludeMethod, getProviderName } from './utils'; 4 | import { Bindings } from '../config/bindings'; 5 | import { JSON_API_CONTROLLER_POSTFIX } from '../../../constants'; 6 | 7 | describe('Test utils', () => { 8 | it('nameIt', () => { 9 | const newNameClass = 'newNameClass'; 10 | const newClass = nameIt(newNameClass, class {}); 11 | expect(getEntityName(newClass)).toBe(newNameClass); 12 | }); 13 | 14 | it('excludeMethod', () => { 15 | expect(excludeMethod(['patchRelationship'])).toEqual( 16 | Object.keys(Bindings).filter((i) => i !== 'patchRelationship') 17 | ); 18 | }); 19 | 20 | it('getProviderName', () => { 21 | class BookList {} 22 | expect(getProviderName(BookList, JSON_API_CONTROLLER_POSTFIX)).toEqual( 23 | 'BookList' + JSON_API_CONTROLLER_POSTFIX 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/interceptors/error.interceptors.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CallHandler, 3 | ExecutionContext, 4 | Inject, 5 | Injectable, 6 | NestInterceptor, 7 | } from '@nestjs/common'; 8 | import { ResourceObject } from '@klerick/json-api-nestjs-shared'; 9 | import { ErrorFormatService } from '../service'; 10 | import { catchError, Observable, throwError } from 'rxjs'; 11 | 12 | @Injectable() 13 | export class ErrorInterceptors implements NestInterceptor { 14 | @Inject(ErrorFormatService) private errorFormatService!: ErrorFormatService; 15 | 16 | private static _instance: ErrorInterceptors; 17 | constructor() { 18 | if (ErrorInterceptors._instance) { 19 | return ErrorInterceptors._instance; 20 | } 21 | ErrorInterceptors._instance = this; 22 | } 23 | 24 | intercept( 25 | context: ExecutionContext, 26 | next: CallHandler> 27 | ): Observable> { 28 | return next 29 | .handle() 30 | .pipe( 31 | catchError((error) => 32 | throwError(() => this.errorFormatService.formatError(error)) 33 | ) 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/interceptors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './error.interceptors'; 2 | export * from './log-time.interceptors'; 3 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/interceptors/log-time.interceptors.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CallHandler, 3 | ExecutionContext, 4 | Injectable, 5 | NestInterceptor, 6 | } from '@nestjs/common'; 7 | import { ResourceObject } from '@klerick/json-api-nestjs-shared'; 8 | 9 | import { map, Observable } from 'rxjs'; 10 | 11 | @Injectable() 12 | export class LogTimeInterceptors implements NestInterceptor { 13 | private static _instance: LogTimeInterceptors; 14 | constructor() { 15 | if (LogTimeInterceptors._instance) { 16 | return LogTimeInterceptors._instance; 17 | } 18 | LogTimeInterceptors._instance = this; 19 | } 20 | 21 | intercept( 22 | context: ExecutionContext, 23 | next: CallHandler> 24 | ): Observable> { 25 | const now = performance.now(); 26 | return next.handle().pipe( 27 | map((r) => { 28 | const response = context.switchToHttp().getResponse(); 29 | const time = performance.now() - now; 30 | response.setHeader('x-response-time', time); 31 | if (r && r.meta) { 32 | r.meta['time'] = time; 33 | } 34 | 35 | return r; 36 | }) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/check-item-entity/index.ts: -------------------------------------------------------------------------------- 1 | export * from './check-item-entity.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/parse-relationship-name/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parse-relationship-name.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/patch-input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './patch-input.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/patch-input/patch-input.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | import { errorMap } from 'zod-validation-error'; 9 | 10 | import { JSONValue } from '../../types'; 11 | import { PatchData, ZodPatch } from '../../zod'; 12 | import { ZOD_PATCH_SCHEMA } from '../../../../constants'; 13 | 14 | export class PatchInputPipe 15 | implements PipeTransform> 16 | { 17 | @Inject(ZOD_PATCH_SCHEMA) 18 | private zodInputPatchSchema!: ZodPatch; 19 | transform(value: JSONValue): PatchData { 20 | try { 21 | return this.zodInputPatchSchema.parse(value, { 22 | errorMap: errorMap, 23 | })['data'] as PatchData; 24 | } catch (e) { 25 | if (e instanceof ZodError) { 26 | throw new BadRequestException(e.issues); 27 | } 28 | 29 | throw new InternalServerErrorException(e); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/patch-relationship/index.ts: -------------------------------------------------------------------------------- 1 | export * from './patch-relationship.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/patch-relationship/patch-relationship.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | import { errorMap } from 'zod-validation-error'; 9 | 10 | import { JSONValue } from '../../types'; 11 | import { PatchRelationshipData, ZodPatchRelationship } from '../../zod'; 12 | import { ZOD_PATCH_RELATIONSHIP_SCHEMA } from '../../../../constants'; 13 | 14 | export class PatchRelationshipPipe 15 | implements PipeTransform 16 | { 17 | @Inject(ZOD_PATCH_RELATIONSHIP_SCHEMA) 18 | private zodInputPatchRelationshipSchema!: ZodPatchRelationship; 19 | transform(value: JSONValue): PatchRelationshipData { 20 | try { 21 | return this.zodInputPatchRelationshipSchema.parse(value, { 22 | errorMap: errorMap, 23 | })['data']; 24 | } catch (e) { 25 | if (e instanceof ZodError) { 26 | throw new BadRequestException(e.issues); 27 | } 28 | 29 | throw new InternalServerErrorException(e); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/post-input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './post-input.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/post-input/post-input.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | import { errorMap } from 'zod-validation-error'; 9 | 10 | import { PostData, ZodPost } from '../../zod'; 11 | import { ZOD_POST_SCHEMA } from '../../../../constants'; 12 | import { JSONValue } from '../../types'; 13 | 14 | export class PostInputPipe 15 | implements PipeTransform> 16 | { 17 | @Inject(ZOD_POST_SCHEMA) private zodInputPostSchema!: ZodPost; 18 | transform(value: JSONValue): PostData { 19 | try { 20 | return this.zodInputPostSchema.parse(value, { 21 | errorMap: errorMap, 22 | })['data'] as PostData; 23 | } catch (e) { 24 | if (e instanceof ZodError) { 25 | throw new BadRequestException(e.issues); 26 | } 27 | 28 | throw new InternalServerErrorException(e); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/post-relationship/index.ts: -------------------------------------------------------------------------------- 1 | export * from './post-relationship.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/post-relationship/post-relationship.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | import { errorMap } from 'zod-validation-error'; 9 | 10 | import { JSONValue } from '../../types'; 11 | import { PostRelationshipData, ZodPostRelationship } from '../../zod'; 12 | import { ZOD_POST_RELATIONSHIP_SCHEMA } from '../../../../constants'; 13 | 14 | export class PostRelationshipPipe 15 | implements PipeTransform 16 | { 17 | @Inject(ZOD_POST_RELATIONSHIP_SCHEMA) 18 | private zodInputPostRelationshipSchema!: ZodPostRelationship; 19 | transform(value: JSONValue): PostRelationshipData { 20 | try { 21 | return this.zodInputPostRelationshipSchema.parse(value, { 22 | errorMap: errorMap, 23 | })['data']; 24 | } catch (e) { 25 | if (e instanceof ZodError) { 26 | throw new BadRequestException(e.issues); 27 | } 28 | 29 | throw new InternalServerErrorException(e); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query-check-select-field/index.ts: -------------------------------------------------------------------------------- 1 | export * from './query-check-select-field'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query-check-select-field/query-check-select-field.ts: -------------------------------------------------------------------------------- 1 | import { BadRequestException, Inject, PipeTransform } from '@nestjs/common'; 2 | import { CONTROLLER_OPTIONS_TOKEN } from '../../../../constants'; 3 | import { ValidateQueryError } from '../../../../types'; 4 | import { Query } from '../../zod'; 5 | import { EntityControllerParam } from '../../types'; 6 | 7 | export class QueryCheckSelectField 8 | implements PipeTransform, Query> 9 | { 10 | @Inject(CONTROLLER_OPTIONS_TOKEN) private configParam!: EntityControllerParam; 11 | transform(value: Query): Query { 12 | if (this.configParam.requiredSelectField && value.fields === null) { 13 | const error: ValidateQueryError = { 14 | code: 'invalid_arguments', 15 | message: `Fields params in query is required'`, 16 | path: ['fields'], 17 | }; 18 | throw new BadRequestException([error]); 19 | } 20 | return value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query-filed-on-include/index.ts: -------------------------------------------------------------------------------- 1 | export * from './query-filed-in-include.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query-input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './query-input.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query-input/query-input.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Inject, 3 | PipeTransform, 4 | BadRequestException, 5 | InternalServerErrorException, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | import { errorMap } from 'zod-validation-error'; 9 | import { ZOD_INPUT_QUERY_SCHEMA } from '../../../../constants'; 10 | import { ZodInputQuery, InputQuery } from '../../zod'; 11 | import { JSONValue } from '../../types'; 12 | 13 | export class QueryInputPipe 14 | implements PipeTransform> 15 | { 16 | @Inject(ZOD_INPUT_QUERY_SCHEMA) 17 | private zodInputQuerySchema!: ZodInputQuery; 18 | 19 | transform(value: JSONValue): InputQuery { 20 | try { 21 | return this.zodInputQuerySchema.parse(value, { 22 | errorMap: errorMap, 23 | }); 24 | } catch (e) { 25 | if (e instanceof ZodError) { 26 | throw new BadRequestException(e.issues); 27 | } 28 | 29 | throw new InternalServerErrorException(e); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query/index.ts: -------------------------------------------------------------------------------- 1 | export * from './query.pipe'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/pipe/query/query.pipe.ts: -------------------------------------------------------------------------------- 1 | import { 2 | InternalServerErrorException, 3 | BadRequestException, 4 | Inject, 5 | PipeTransform, 6 | } from '@nestjs/common'; 7 | import { ZodError } from 'zod'; 8 | 9 | import { ZOD_QUERY_SCHEMA } from '../../../../constants'; 10 | import { ZodQuery, Query, InputQuery } from '../../zod'; 11 | 12 | export class QueryPipe 13 | implements PipeTransform, Query> 14 | { 15 | @Inject(ZOD_QUERY_SCHEMA) 16 | private zodQuerySchema!: ZodQuery; 17 | 18 | transform(value: InputQuery): Query { 19 | try { 20 | return this.zodQuerySchema.parse(value); 21 | } catch (e) { 22 | if (e instanceof ZodError) { 23 | throw new BadRequestException(e.issues); 24 | } 25 | 26 | throw new InternalServerErrorException(e); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './entity-param-map.service'; 2 | export * from './json-api-transformer.service'; 3 | export * from './error-format.service'; 4 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/swagger/index.ts: -------------------------------------------------------------------------------- 1 | export * from './swagger-bind.service'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/swagger/method/index.ts: -------------------------------------------------------------------------------- 1 | import { getAll } from './get-all'; 2 | import { getOne } from './get-one'; 3 | import { deleteOne } from './delete-one'; 4 | import { postOne } from './post-one'; 5 | import { patchOne } from './patch-one'; 6 | import { getRelationship } from './get-relationship'; 7 | import { deleteRelationship } from './delete-relationship'; 8 | import { postRelationship } from './post-relationship'; 9 | import { patchRelationship } from './patch-relationship'; 10 | 11 | import { OrmService } from '../../types'; 12 | 13 | export const swaggerMethod = { 14 | getAll, 15 | getOne, 16 | deleteOne, 17 | postOne, 18 | patchOne, 19 | getRelationship, 20 | deleteRelationship, 21 | postRelationship, 22 | patchRelationship, 23 | } as const; 24 | 25 | export type SwaggerMethod = { 26 | [Key in keyof OrmService]?: (typeof swaggerMethod)[Key]; 27 | }; 28 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/types/decorator-options.type.ts: -------------------------------------------------------------------------------- 1 | import { MethodName } from './binding.type'; 2 | 3 | import { PrepareParams } from '../../../types'; 4 | 5 | type ControllerOptions = { 6 | allowMethod: Array; 7 | overrideRoute: string; 8 | }; 9 | 10 | export type DecoratorOptions> = Partial< 11 | ControllerOptions & Omit['options'], 'operationUrl'> 12 | >; 13 | 14 | export type EntityControllerParam> = 15 | PrepareParams['options'] & DecoratorOptions; 16 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './binding.type'; 2 | export * from './decorator-options.type'; 3 | export * from './orm-service.type'; 4 | export * from './module.type'; 5 | export type JSONValue = 6 | | string 7 | | number 8 | | boolean 9 | | null 10 | | { [x: string]: JSONValue } 11 | | Array; 12 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/types/module.type.ts: -------------------------------------------------------------------------------- 1 | import { EntityClass } from '@klerick/json-api-nestjs-shared'; 2 | import { EntityParam } from '../../../types'; 3 | 4 | export type EntityParamMap = Map>; 5 | 6 | export type CheckRelationName = ( 7 | entity: EntityClass, 8 | params: string 9 | ) => boolean; 10 | 11 | export type FindOneRowEntity = ( 12 | entity: EntityClass, 13 | params: number | string 14 | ) => Promise; 15 | 16 | export type RunInTransaction< 17 | F extends (...arg: any[]) => Promise = (...arg: any[]) => Promise 18 | > = (arg: F) => ReturnType; 19 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/index.ts: -------------------------------------------------------------------------------- 1 | export * from './zod-input-query-schema'; 2 | export * from './zod-query-schema'; 3 | export * from './zod-input-post-schema'; 4 | export * from './zod-input-patch-schema'; 5 | export * from './zod-input-post-relationship-schema'; 6 | export * from './zod-input-patch-relationship-schema'; 7 | 8 | export { Relationships, Data, Attributes, Id, Type } from './zod-share'; 9 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-input-patch-relationship-schema/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | import { zodData } from '../zod-share'; 4 | 5 | export const zodPatchRelationship = z 6 | .object({ 7 | data: z.union([zodData().nullable(), zodData().array()]), 8 | }) 9 | .strict(); 10 | 11 | export type ZodPatchRelationship = typeof zodPatchRelationship; 12 | export type PatchRelationship = z.infer; 13 | export type PatchRelationshipData = PatchRelationship['data']; 14 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-input-post-relationship-schema/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | import { zodData } from '../zod-share'; 4 | 5 | export const zodPostRelationship = z 6 | .object({ 7 | data: z.union([zodData(), zodData().array().nonempty()]), 8 | }) 9 | .strict(); 10 | 11 | export type ZodPostRelationship = typeof zodPostRelationship; 12 | export type PostRelationship = z.infer; 13 | export type PostRelationshipData = PostRelationship['data']; 14 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-input-query-schema/filter.test-d.ts: -------------------------------------------------------------------------------- 1 | import { ZodFilterInputQuery } from './filter'; 2 | import { Users } from '../../../../utils/___test___/test-classes.helper'; 3 | import { expectAssignable, expectNotAssignable } from 'tsd'; 4 | 5 | type FilterType = ZodFilterInputQuery; 6 | const checkShape = { 7 | target: { 8 | id: { 9 | some: '', 10 | eq: '', 11 | }, 12 | testArrayNull: { 13 | some: '', 14 | }, 15 | addresses: { 16 | eq: 'null', 17 | }, 18 | }, 19 | relation: { 20 | addresses: { 21 | arrayField: { 22 | in: '', 23 | }, 24 | }, 25 | }, 26 | } satisfies FilterType; 27 | expectAssignable(checkShape); 28 | expectNotAssignable({ 29 | ...checkShape, 30 | notAllow: {}, 31 | }); 32 | expectNotAssignable({ 33 | ...checkShape, 34 | addresses: { 35 | in: null, 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-input-query-schema/include.ts: -------------------------------------------------------------------------------- 1 | import { isString } from '@klerick/json-api-nestjs-shared'; 2 | import { z } from 'zod'; 3 | 4 | export function zodIncludeInputQuery() { 5 | return z 6 | .string() 7 | .optional() 8 | .transform((data) => { 9 | if (!data || !isString(data)) return null; 10 | return data 11 | .split(',') 12 | .map((i) => i.trim()) 13 | .filter((i) => !!i); 14 | }); 15 | } 16 | 17 | export type ZodIncludeInputQuery = z.infer< 18 | ReturnType 19 | >; 20 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-query-schema/include.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | import { uniqueArray } from '../zod-utils'; 3 | import { EntityParamMapService } from '../../service'; 4 | import { NonEmptyStringTuple } from '../../../../types'; 5 | 6 | export function zodIncludeQuery( 7 | entityParamMapService: EntityParamMapService 8 | ) { 9 | const relationProps: NonEmptyStringTuple< 10 | typeof entityParamMapService.entityParaMap.relations 11 | > = entityParamMapService.entityParaMap.relations as any; 12 | 13 | return z 14 | .enum(relationProps) 15 | .array() 16 | .nonempty() 17 | .refine(uniqueArray(), { 18 | message: 'Include should have unique relation', 19 | }) 20 | .nullable(); 21 | } 22 | 23 | export type ZodIncludeQuery< 24 | E extends object, 25 | IdKey extends string 26 | > = ReturnType>; 27 | export type IncludeQuery = z.infer< 28 | ZodIncludeQuery 29 | >; 30 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/id.spec.ts: -------------------------------------------------------------------------------- 1 | import { ZodError } from 'zod'; 2 | 3 | import { ZodId, zodId } from './id'; 4 | import { TypeField } from '../../../../types'; 5 | 6 | describe('zodIdSchema', () => { 7 | let numberStringSchema: ZodId; 8 | let stringSchema: ZodId; 9 | beforeAll(() => { 10 | numberStringSchema = zodId(TypeField.number); 11 | stringSchema = zodId(TypeField.string); 12 | }); 13 | 14 | it('Should be correct', () => { 15 | const check1 = '1'; 16 | const check2 = '12'; 17 | const check3 = '123'; 18 | const check4 = '-123'; 19 | 20 | const check5 = 'sfdsf'; 21 | const checkArray = [check1, check2, check3, check4]; 22 | for (const item of checkArray) { 23 | expect(numberStringSchema.parse(item)).toBe(item); 24 | } 25 | expect(stringSchema.parse(check5)).toBe(check5); 26 | }); 27 | 28 | it('Should be not ok', () => { 29 | expect.assertions(1); 30 | 31 | try { 32 | numberStringSchema.parse('sdfdfsfsf'); 33 | } catch (e) { 34 | expect(e).toBeInstanceOf(ZodError); 35 | } 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/id.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | import { TypeField, TypeForId } from '../../../../types'; 3 | 4 | const reg = new RegExp('^-?\\d+$'); 5 | 6 | export function zodId(typeId: TypeForId) { 7 | let idSchema = z.string(); 8 | if (typeId === TypeField.number) { 9 | idSchema = idSchema.regex(reg); 10 | } 11 | 12 | return idSchema; 13 | } 14 | 15 | export type ZodId = ReturnType; 16 | export type Id = z.infer; 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/index.ts: -------------------------------------------------------------------------------- 1 | export * from './page'; 2 | export * from './id'; 3 | export * from './type'; 4 | export * from './attributes'; 5 | export * from './rel-data'; 6 | export * from './relationships'; 7 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/page.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | import { DEFAULT_PAGE_SIZE, DEFAULT_QUERY_PAGE } from '../../../../constants'; 3 | 4 | export function zodPageInputQuery() { 5 | return z 6 | .object({ 7 | size: z 8 | .preprocess((x) => Number(x), z.number().int().min(1)) 9 | .default(DEFAULT_PAGE_SIZE), 10 | number: z 11 | .preprocess((x) => Number(x), z.number().int().min(1)) 12 | .default(DEFAULT_QUERY_PAGE), 13 | }) 14 | .strict() 15 | .default({ 16 | size: DEFAULT_PAGE_SIZE, 17 | number: DEFAULT_QUERY_PAGE, 18 | }); 19 | } 20 | 21 | export type ZodPageInputQuery = ReturnType; 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/rel-data.spec.ts: -------------------------------------------------------------------------------- 1 | import { zodRelData, ZodRelData } from './rel-data'; 2 | 3 | import { ZodError } from 'zod'; 4 | import { TypeField } from '../../../../types'; 5 | 6 | describe('zodDataSchema', () => { 7 | let zodData: ZodRelData; 8 | beforeAll(() => { 9 | zodData = zodRelData('users', TypeField.string); 10 | }); 11 | 12 | it('Should be ok', () => { 13 | const check = { 14 | type: 'users', 15 | id: 'id', 16 | }; 17 | expect(zodData.parse(check)).toEqual(check); 18 | }); 19 | 20 | it('Should be not ok', () => { 21 | const check = {}; 22 | const check1 = { 23 | test: '1', 24 | }; 25 | const check3: any[] = []; 26 | const check4 = 'adfsdf'; 27 | const check5 = true; 28 | const checkArray = [check, check1, check3, check4, check5]; 29 | expect.assertions(checkArray.length); 30 | for (const item of checkArray) { 31 | try { 32 | zodData.parse(item); 33 | } catch (e) { 34 | expect(e).toBeInstanceOf(ZodError); 35 | } 36 | } 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/rel-data.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | import { TypeForId } from '../../../../types'; 4 | import { nonEmptyObject } from '../zod-utils'; 5 | 6 | import { zodType, zodId } from './'; 7 | 8 | export function zodRelData(typeName: T, typeId: TypeForId) { 9 | return z 10 | .object({ 11 | id: zodId(typeId), 12 | type: zodType(typeName), 13 | }) 14 | .strict() 15 | .refine(nonEmptyObject); 16 | } 17 | 18 | export type ZodRelData = ReturnType>; 19 | export type RelData = z.infer>; 20 | 21 | export function zodData() { 22 | return z 23 | .object({ 24 | type: z.coerce.string(), 25 | id: z.coerce.string(), 26 | }) 27 | .strict() 28 | .refine(nonEmptyObject); 29 | } 30 | 31 | export type ZodData = ReturnType; 32 | export type Data = z.infer; 33 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/type.spec.ts: -------------------------------------------------------------------------------- 1 | import { zodType, ZodType } from './type'; 2 | import { ZodError } from 'zod'; 3 | 4 | describe('type', () => { 5 | const literal = 'users'; 6 | let userTypeSchema: ZodType; 7 | beforeAll(() => { 8 | userTypeSchema = zodType(literal); 9 | }); 10 | it('should be ok', () => { 11 | expect(userTypeSchema.parse(literal)).toEqual(literal); 12 | }); 13 | it('should be ok', () => { 14 | expect.assertions(1); 15 | try { 16 | userTypeSchema.parse('test'); 17 | } catch (e) { 18 | expect(e).toBeInstanceOf(ZodError); 19 | } 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/modules/mixin/zod/zod-share/type.ts: -------------------------------------------------------------------------------- 1 | import { z, ZodNullable, ZodOptional, ZodType as InnerZodType } from 'zod'; 2 | 3 | export function zodType(type: T) { 4 | return z.literal(type); 5 | } 6 | 7 | export type ZodType = ReturnType>; 8 | export type Type = z.infer>; 9 | 10 | type ResultPatchSchema< 11 | Schema extends InnerZodType, 12 | Null extends true | false 13 | > = Null extends true ? ZodOptional> : ZodOptional; 14 | 15 | type ResultPostSchema< 16 | Schema extends InnerZodType, 17 | Null extends true | false 18 | > = Null extends true ? ZodOptional> : Schema; 19 | 20 | export type ResultSchema< 21 | Schema extends InnerZodType, 22 | Null extends true | false, 23 | isPatch extends true | false 24 | > = isPatch extends true 25 | ? ResultPatchSchema 26 | : ResultPostSchema; 27 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/types/common-type.ts: -------------------------------------------------------------------------------- 1 | import { ModuleMetadata, PipeTransform, Type } from '@nestjs/common'; 2 | 3 | export type NestController = NonNullable; 4 | export type NestProvider = NonNullable; 5 | export type NestImport = NonNullable; 6 | export type PipeMixin = Type; 7 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/types/error.types.ts: -------------------------------------------------------------------------------- 1 | import { ZodIssue } from 'zod'; 2 | 3 | export type InnerErrorType = 4 | | 'invalid_arguments' 5 | | 'unrecognized_keys' 6 | | 'internal_error'; 7 | 8 | export type InnerError = { 9 | code: InnerErrorType; 10 | message: string; 11 | path: string[]; 12 | keys?: string[]; 13 | error?: Error; 14 | }; 15 | 16 | export type ValidateQueryError = ZodIssue | InnerError; 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './common-type'; 2 | export * from './module-options.types'; 3 | export * from './utils-type'; 4 | export * from './entity-param.type'; 5 | export * from './error.types'; 6 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module-helper'; 2 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "noPropertyAccessFromIndexSignature": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "target": "es2023", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strictBindCallApply": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true, 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.test-d.ts", "src/lib/utils/___test___/**/*.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/json-api/json-api-nestjs/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node16", 7 | "types": ["jest", "node"], 8 | "paths": { 9 | "@klerick/json-api-nestjs-shared": [ 10 | "libs/json-api/json-api-nestjs-shared/src/index.ts" 11 | ] 12 | }, 13 | "allowJs": true 14 | }, 15 | "include": [ 16 | "jest.config.ts", 17 | "src/**/*.test.ts", 18 | "src/**/*.spec.ts", 19 | "src/**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": "error" 22 | } 23 | }, 24 | { 25 | "files": ["*.ts"], 26 | "rules": { 27 | "@angular-eslint/prefer-standalone": "off" 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.0.0 (2024-12-18) 2 | 3 | ### 🚀 Features 4 | 5 | - **json-api-nestjs-sdk,nestjs-json-rpc-sdk:** Change export ([7953371](https://github.com/klerick/nestjs-json-api/commit/7953371)) 6 | 7 | ### ❤️ Thank You 8 | 9 | - Alex H 10 | 11 | # 1.0.0 (2024-04-12) 12 | 13 | 14 | ### 🚀 Features 15 | 16 | - **nestjs-json-rpc-sdk:** sdk for rpc ([eaa48e6](https://github.com/klerick/nestjs-json-api/commit/eaa48e6)) 17 | 18 | - **nestjs-json-rpc,nestjs-json-rpc-sdk:** add ws transport ([31450b3](https://github.com/klerick/nestjs-json-api/commit/31450b3)) 19 | 20 | - **nestjs-json-rpc-sdk:** add takeUntil for disconnect socket ([aefaf95](https://github.com/klerick/nestjs-json-api/commit/aefaf95)) 21 | 22 | - ⚠️ **nestjs-json-rpc-sdk:** Create git tag ([e226170](https://github.com/klerick/nestjs-json-api/commit/e226170)) 23 | 24 | 25 | #### ⚠️ Breaking Changes 26 | 27 | - **nestjs-json-rpc-sdk:** Up to major version 28 | 29 | ### ❤️ Thank You 30 | 31 | - Alex H -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'nestjs-json-rpc-sdk', 4 | preset: '../../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../../coverage/libs/json-rpc/nestjs-json-rpc-sdk', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../tmp/angular-lib/nestjs-json-rpc-sdk", 4 | "lib": { 5 | "entryFile": "./src/ngModule.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/nestjs-json-rpc-sdk", 3 | "version": "2.0.0", 4 | "engines": { 5 | "node": ">= 16.0.0" 6 | }, 7 | "description": "Client for RPS server, which use @klerick/nestjs-json-rpc", 8 | "contributors": [ 9 | { 10 | "email": "klerick666@gmain.com", 11 | "name": "Aleksandr Kharkovey" 12 | } 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/klerick/nestjs-json-api.git" 17 | }, 18 | "private": false, 19 | "license": "MIT", 20 | "main": "./src/index.js", 21 | "files": [ 22 | "**/*" 23 | ], 24 | "keywords": [ 25 | "nestjs", 26 | "nest", 27 | "RPC", 28 | "JSON-RPC" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | axiosTransportFactory, 3 | RpcFactory, 4 | ResultRpcFactoryPromise, 5 | ResultRpcFactory, 6 | } from './lib/factory'; 7 | export { 8 | RpcConfig, 9 | TransportType, 10 | ErrorCodeType, 11 | RpcError, 12 | LoopFunc, 13 | HttpAgentFactory, 14 | Transport, 15 | PayloadRpc, 16 | RpcResult, 17 | } from './lib/types'; 18 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/angular/json-rpc-angular.module.ts: -------------------------------------------------------------------------------- 1 | import { makeEnvironmentProviders } from '@angular/core'; 2 | 3 | import { JSON_RPC_SDK_CONFIG } from './tokens'; 4 | import { JsonRpcAngularConfig } from '../types'; 5 | 6 | export const provideJsonRpc = (config: JsonRpcAngularConfig) => 7 | makeEnvironmentProviders([ 8 | { 9 | useValue: config, 10 | provide: JSON_RPC_SDK_CONFIG, 11 | }, 12 | ]); 13 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/angular/tokens.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { 3 | LoopFunc, 4 | RpcBatch, 5 | RpcReturnList, 6 | Transport, 7 | JsonRpcAngularConfig, 8 | } from '../types'; 9 | 10 | import { 11 | angularTransportFactory, 12 | rpcBatchFactory, 13 | rpcFactory, 14 | } from './factory'; 15 | 16 | export const JSON_RPC_SDK_CONFIG = new InjectionToken( 17 | 'Main config object for sdk' 18 | ); 19 | 20 | export const JSON_RPC_SDK_TRANSPORT = new InjectionToken>( 21 | 'Transport for RPC', 22 | { 23 | factory: angularTransportFactory, 24 | } 25 | ); 26 | 27 | export const JSON_RPC = new InjectionToken>( 28 | 'Rpc client', 29 | { 30 | factory: rpcFactory, 31 | } 32 | ); 33 | 34 | export const RPC_BATCH = new InjectionToken('Rpc client for batch', { 35 | factory: rpcBatchFactory, 36 | }); 37 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/constans/index.ts: -------------------------------------------------------------------------------- 1 | export const JSON_RPC_VERSION = '2.0'; 2 | export const WS_EVENT_NAME = 'rpc'; 3 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/factory/axios-transport.factory.ts: -------------------------------------------------------------------------------- 1 | import { Axios, AxiosResponse } from 'axios'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { 5 | HttpAgentFactory, 6 | LoopFunc, 7 | PayloadRpc, 8 | ReturnTransportCall, 9 | RpcResult, 10 | } from '../types'; 11 | import { map } from 'rxjs/operators'; 12 | 13 | export function axiosTransportFactory( 14 | axios: Axios 15 | ): HttpAgentFactory { 16 | return (url: string) => (body: PayloadRpc) => { 17 | const controller = new AbortController(); 18 | const signal = controller.signal; 19 | 20 | return new Observable>>((subscriber) => { 21 | axios 22 | .post< 23 | ReturnTransportCall, 24 | AxiosResponse, PayloadRpc>, 25 | PayloadRpc 26 | >(url, body, { signal }) 27 | .then((response) => subscriber.next(response)) 28 | .catch((error: unknown) => subscriber.error(error)) 29 | .finally(() => subscriber.complete()); 30 | 31 | return { unsubscribe: () => controller.abort() }; 32 | }).pipe(map((r) => r.data)); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/factory/fetch-transport.factory.ts: -------------------------------------------------------------------------------- 1 | import { fromFetch } from 'rxjs/fetch'; 2 | import { LoopFunc, PayloadRpc, RpcResult, Transport } from '../types'; 3 | 4 | export function fetchTransportFactory( 5 | url: string 6 | ): Transport { 7 | return (body: PayloadRpc) => 8 | fromFetch>(url, { 9 | method: 'post', 10 | body: JSON.stringify(body), 11 | selector: (r) => r.json(), 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/factory/id-request.spec.ts: -------------------------------------------------------------------------------- 1 | import { idRequest } from './id-request'; 2 | 3 | describe('id-request', () => { 4 | it('should be increment', () => { 5 | expect(idRequest()).toBe(1); 6 | expect(idRequest()).toBe(2); 7 | expect(idRequest()).toBe(3); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/factory/id-request.ts: -------------------------------------------------------------------------------- 1 | let i = 0; 2 | export const idRequest = () => ++i; 3 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/factory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './axios-transport.factory'; 2 | export * from './id-request'; 3 | export * from './rpc.factory'; 4 | export * from './transport.factory'; 5 | export * from './fetch-transport.factory'; 6 | export * from './io-transport.factory'; 7 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/json-rpc-angular.ts: -------------------------------------------------------------------------------- 1 | export { provideJsonRpc } from './angular/json-rpc-angular.module'; 2 | export { JsonRpcAngularConfig, TransportType, Rpc } from './types'; 3 | export { JSON_RPC, RPC_BATCH } from './angular/tokens'; 4 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/types/angular-type.ts: -------------------------------------------------------------------------------- 1 | import { 2 | RpcMainHttpConfig, 3 | RpcNativeSocketFactory, 4 | RpcNativeSocketFalse, 5 | RpcNativeSocketTrue, 6 | TransportType, 7 | } from './config'; 8 | import { RpcReturnList } from './rpc'; 9 | 10 | type RpcWsMainConfig = { 11 | transport: TransportType.WS; 12 | destroySubjectToken?: any; 13 | }; 14 | 15 | type RpcTokenForWs = { 16 | tokenSocketInst: any; 17 | }; 18 | 19 | type RpcNativeConfig = RpcNativeSocketTrue & 20 | (RpcNativeSocketFactory | RpcTokenForWs); 21 | 22 | type RpcIoConfig = RpcNativeSocketFalse & RpcTokenForWs; 23 | 24 | type RpcAngularWsConfig = RpcWsMainConfig & (RpcNativeConfig | RpcIoConfig); 25 | 26 | export type JsonRpcAngularConfig = RpcMainHttpConfig | RpcAngularWsConfig; 27 | 28 | export type Rpc = RpcReturnList; 29 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config'; 2 | export * from './rpc'; 3 | export * from './rpc-error-object'; 4 | export * from './utils'; 5 | export * from './angular-type'; 6 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/types/rpc-error-object.ts: -------------------------------------------------------------------------------- 1 | import { JsonRpcVersion } from './rpc'; 2 | 3 | export enum ErrorCodeType { 4 | ParseError = 'Parse error', 5 | InvalidRequest = 'Invalid request', 6 | MethodNotFound = 'Method not found', 7 | InvalidParams = 'Invalid params', 8 | InternalError = 'Internal error', 9 | ServerError = 'Server error', 10 | } 11 | 12 | export type RpcErrorObject = { 13 | jsonrpc: JsonRpcVersion; 14 | error: { 15 | message: ErrorCodeType | string; 16 | code: number; 17 | data?: { 18 | title: string; 19 | description: string; 20 | }; 21 | }; 22 | id: null | number; 23 | }; 24 | 25 | export class RpcError extends Error { 26 | data!: { 27 | title: string; 28 | description: string; 29 | }; 30 | code!: number; 31 | id: null | number = null; 32 | constructor(rpcError: RpcErrorObject) { 33 | super(rpcError.error.message); 34 | this.id = rpcError.id; 35 | this.code = rpcError.error.code; 36 | if (rpcError.error.data) { 37 | this.data = rpcError.error.data; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/types/utils.ts: -------------------------------------------------------------------------------- 1 | import { Transport } from './rpc'; 2 | 3 | export type LoopFunc = (...args: any) => any; 4 | 5 | export type ReturnGenericType = 6 | ReturnType extends Promise ? U : ReturnType; 7 | 8 | export type HttpAgentFactory = ( 9 | url: string 10 | ) => Transport; 11 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/body.spec.ts: -------------------------------------------------------------------------------- 1 | import { generateBody, generateBodyMethod } from './body'; 2 | import { JSON_RPC_VERSION } from '../constans'; 3 | 4 | describe('body', () => { 5 | it('generateBodyMethod', () => { 6 | const nameSpace = 'nameSpace'; 7 | const method = 'method'; 8 | expect(generateBodyMethod(nameSpace, method)).toBe( 9 | `${nameSpace}.${method}` 10 | ); 11 | }); 12 | 13 | it('generateBody', () => { 14 | const nameSpace = 'nameSpace'; 15 | const method = 'method'; 16 | const params = ['param1', 'param2']; 17 | const id = 1; 18 | const result = generateBody( 19 | generateBodyMethod(nameSpace, method), 20 | params, 21 | id 22 | ); 23 | expect(result).toEqual({ 24 | jsonrpc: JSON_RPC_VERSION, 25 | method: generateBodyMethod(nameSpace, method), 26 | params, 27 | id, 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/body.ts: -------------------------------------------------------------------------------- 1 | import { LoopFunc, PayloadRpc } from '../types'; 2 | import { JSON_RPC_VERSION } from '../constans'; 3 | 4 | export function generateBodyMethod(nameSpace: string, method: string): string { 5 | return `${nameSpace}.${method}`; 6 | } 7 | 8 | export function generateBody( 9 | method: string, 10 | params: Parameters, 11 | id: number 12 | ): PayloadRpc { 13 | return { 14 | jsonrpc: JSON_RPC_VERSION, 15 | params, 16 | method, 17 | id, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './wrapper-call'; 2 | export * from './rpc-proxy'; 3 | export * from './rpc-batch'; 4 | export * from './body'; 5 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/pipe.ts: -------------------------------------------------------------------------------- 1 | import { OperatorFunction, pipe, throwError } from 'rxjs'; 2 | import { map } from 'rxjs/operators'; 3 | 4 | import { 5 | LoopFunc, 6 | ReturnGenericType, 7 | ReturnTransportCall, 8 | RpcError, 9 | RpcResult, 10 | } from '../types'; 11 | 12 | export const mapParseResponse = (r: RpcResult) => { 13 | if ('error' in r) return r; 14 | return r.result; 15 | }; 16 | 17 | export const throwOrReturnError = (returnError = false) => { 18 | return (r: ReturnTransportCall) => { 19 | if (!(typeof r === 'object' && r !== null && 'error' in r)) { 20 | return r; 21 | } 22 | const error = new RpcError(r); 23 | if (!returnError) throw error; 24 | return error; 25 | }; 26 | }; 27 | 28 | export function parseResponse(): OperatorFunction< 29 | RpcResult, 30 | ReturnTransportCall 31 | > { 32 | return pipe(map(mapParseResponse)); 33 | } 34 | 35 | export function throwRpcError(): OperatorFunction< 36 | ReturnTransportCall, 37 | ReturnGenericType 38 | > { 39 | return pipe(map((r) => throwOrReturnError()(r))); 40 | } 41 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/rpc-proxy.ts: -------------------------------------------------------------------------------- 1 | import { lastValueFrom } from 'rxjs'; 2 | 3 | import { LoopFunc, RpcReturnList, Transport } from '../types'; 4 | import { WrapperCall } from './wrapper-call'; 5 | 6 | export const rpcProxy = >( 7 | transport: Transport, 8 | usePromise = false 9 | ): T => { 10 | const mockRpcNameSpace = {} as T; 11 | return new Proxy(mockRpcNameSpace, { 12 | get(target, nameSpace: keyof T) { 13 | const mockRpcmethode = {} as T[typeof nameSpace]; 14 | return new Proxy(mockRpcmethode, { 15 | get(target, method: keyof T[typeof nameSpace]) { 16 | return (...arg: Parameters) => { 17 | const wr = new WrapperCall( 18 | String(nameSpace), 19 | String(method), 20 | arg, 21 | transport 22 | ); 23 | if (usePromise) return lastValueFrom(wr); 24 | return wr; 25 | }; 26 | }, 27 | }); 28 | }, 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/lib/utils/wrapper-call.spec.ts: -------------------------------------------------------------------------------- 1 | import { WrapperCall } from './wrapper-call'; 2 | import { Transport } from '../types'; 3 | import { of } from 'rxjs'; 4 | 5 | function mockRPC(a: number, b: string): number { 6 | return 1; 7 | } 8 | 9 | describe('wrapper-call', () => { 10 | let nameSpace: string; 11 | let method: string; 12 | let arg: Parameters; 13 | let transport: Transport; 14 | 15 | beforeEach(() => { 16 | nameSpace = 'namespace'; 17 | method = 'method'; 18 | arg = [1, 'test']; 19 | }); 20 | 21 | it('should be init Observable', (done) => { 22 | const result = { result: 'result' }; 23 | transport = jest.fn().mockImplementationOnce((input) => { 24 | return of(result); 25 | }); 26 | expect.assertions(2); 27 | const instWrapperCall = new WrapperCall(nameSpace, method, arg, transport); 28 | instWrapperCall.subscribe({ 29 | next: (r) => { 30 | expect(r).toEqual(result.result); 31 | }, 32 | complete: () => { 33 | expect(transport).toHaveBeenCalledWith(instWrapperCall.body); 34 | done(); 35 | }, 36 | error: (err) => done(err), 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/src/ngModule.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/json-rpc-angular'; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/tsconfig-mjs.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["node"], 5 | "module": "es2015", 6 | "target": "ES2022", 7 | "removeComments": false, 8 | "declaration": true, 9 | }, 10 | "include": ["src/**/*.ts"], 11 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], 12 | "angularCompilerOptions": { 13 | "compilationMode": "partial", 14 | "enableI18nLegacyMessageIdFormat": false, 15 | "strictInjectionParameters": true, 16 | "strictInputAccessModifiers": true, 17 | "strictTemplates": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "inlineSources": true, 12 | "inlineSourceMap": true, 13 | "sourceMap": false 14 | }, 15 | "files": [], 16 | "include": [], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.lib.json" 20 | }, 21 | { 22 | "path": "./tsconfig-mjs.lib.json" 23 | }, 24 | { 25 | "path": "./tsconfig.spec.json" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "declaration": false, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc-sdk/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 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": "error" 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.0 (2024-04-12) 2 | 3 | 4 | ### 🚀 Features 5 | 6 | - **nestjs-json-rpc:** default transport for rpc ([f89f7cf](https://github.com/klerick/nestjs-json-api/commit/f89f7cf)) 7 | 8 | - **nestjs-json-rpc-sdk:** sdk for rpc ([eaa48e6](https://github.com/klerick/nestjs-json-api/commit/eaa48e6)) 9 | 10 | - **nestjs-json-rpc,nestjs-json-rpc-sdk:** add ws transport ([31450b3](https://github.com/klerick/nestjs-json-api/commit/31450b3)) 11 | 12 | - ⚠️ **nestjs-json-rpc,nestjs-json-rpc-sdk:** Create git tag ([7c7ae72](https://github.com/klerick/nestjs-json-api/commit/7c7ae72)) 13 | 14 | - ⚠️ **nestjs-json-rpc:** Create git tag ([309c1e2](https://github.com/klerick/nestjs-json-api/commit/309c1e2)) 15 | 16 | 17 | #### ⚠️ Breaking Changes 18 | 19 | - **nestjs-json-rpc,nestjs-json-rpc-sdk:** Up to major version 20 | - **nestjs-json-rpc:** Up to major version 21 | 22 | ### ❤️ Thank You 23 | 24 | - Alex H -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'nestjs-json-rpc', 4 | preset: '../../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../../coverage/libs/json-rpc/nestjs-json-rpc', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klerick/nestjs-json-rpc", 3 | "version": "1.0.0", 4 | "engines": { 5 | "node": ">= 16.0.0" 6 | }, 7 | "type": "commonjs", 8 | "description": "JSON-RPC server for NestJs", 9 | "contributors": [ 10 | { 11 | "email": "klerick666@gmain.com", 12 | "name": "Aleksandr Kharkovey" 13 | } 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/klerick/nestjs-json-api.git" 18 | }, 19 | "private": false, 20 | "license": "MIT", 21 | "files": [ 22 | "**/*" 23 | ], 24 | "keywords": [ 25 | "nestjs", 26 | "nest", 27 | "RPC", 28 | "JSON-RPC" 29 | ], 30 | "peerDependencies": { 31 | "socket.io": "*.*.*", 32 | "ws": "*.*.*", 33 | "@nestjs/platform-socket.io": "^10.3.0", 34 | "@nestjs/websockets": "^10.3.0", 35 | "@nestjs/platform-ws": "^10.3.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/nestjs-json-rpc.module'; 2 | export { TransportType, CommonRpcConfig, ErrorCodeType } from './lib/types'; 3 | export { 4 | fromRpcErrorToRpcErrorObject, 5 | createError, 6 | RpcError, 7 | createErrorCustomError, 8 | } from './lib/utils'; 9 | 10 | export { RpcHandler, RpcParamsPipe } from './lib/decorators'; 11 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/constants/index.ts: -------------------------------------------------------------------------------- 1 | import { ErrorCodeType } from '../types'; 2 | 3 | export const JsonRpcMetadataKey = '__rpc-metadata__'; 4 | export const JsonRpcMetadataKeyParamPipe = '__rpc-metadata-param-pipe__'; 5 | 6 | export const MAP_HANDLER = Symbol('MAP_HANDLER'); 7 | export const RPC_CONTEXT = Symbol('RPC_CONTEXT'); 8 | export const ASYNC_ITERATOR_FACTORY = Symbol('ASYNC_ITERATOR_FACTORY'); 9 | export const ZOD_INPUT_DATA = Symbol('ZOD_INPUT_DATA'); 10 | 11 | export const ErrorCode: Record = { 12 | [ErrorCodeType.ParseError]: -32700, 13 | [ErrorCodeType.InvalidRequest]: -32600, 14 | [ErrorCodeType.MethodNotFound]: -32601, 15 | [ErrorCodeType.InvalidParams]: -32602, 16 | [ErrorCodeType.InternalError]: -32603, 17 | [ErrorCodeType.ServerError]: -32000, 18 | } as const; 19 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/http-transport/controllers/json-rpc.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Inject, Post, UseFilters } from '@nestjs/common'; 2 | import { HandlerService } from '../../util/service'; 3 | import { InputDataPipe } from '../../util/pipe/input-data.pipe'; 4 | import { PayloadRpcData, RpcResult } from '../../../types'; 5 | import { RpcErrorObject } from '../../../types'; 6 | import { RpcErrorExceptionFilter } from '../filter/rpc-error-exception.filter'; 7 | 8 | @Controller('/') 9 | export class JsonRpcController { 10 | @Inject(HandlerService) private readonly handlerService!: HandlerService; 11 | 12 | @Post('') 13 | @UseFilters(new RpcErrorExceptionFilter()) 14 | async handler( 15 | @Body(InputDataPipe) body: PayloadRpcData 16 | ): Promise> { 17 | return this.handlerService.runRpc(body); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/http-transport/filter/rpc-error-exception.filter.ts: -------------------------------------------------------------------------------- 1 | import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'; 2 | 3 | import { getBodyError } from '../../../utils'; 4 | 5 | @Catch() 6 | export class RpcErrorExceptionFilter implements ExceptionFilter { 7 | catch(exception: Error, host: ArgumentsHost): void { 8 | host.switchToHttp().getResponse().send(getBodyError(exception)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/http-transport/http-transport.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Provider } from '@nestjs/common'; 2 | import { Type } from '@nestjs/common/interfaces/type.interface'; 3 | import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface'; 4 | 5 | import { JsonRpcController } from './controllers/json-rpc.controller'; 6 | 7 | export class HttpTransportModule { 8 | static forRoot( 9 | providers: Provider[], 10 | imports: Array< 11 | Type | DynamicModule | Promise | ForwardReference 12 | > = [] 13 | ): DynamicModule { 14 | return { 15 | module: HttpTransportModule, 16 | providers, 17 | controllers: [JsonRpcController], 18 | // exports: [RPC_CONTEXT], 19 | imports, 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './http-transport/http-transport.module'; 2 | export * from './util/util.module'; 3 | export * from './ws-socket-transport/ws-socket-transport.module'; 4 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/util/service/explorer.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test } from '@nestjs/testing'; 2 | import { ExplorerService } from './explorer.service'; 3 | import { RpcHandler } from '../../../decorators'; 4 | 5 | @RpcHandler() 6 | class TestClass {} 7 | 8 | @RpcHandler() 9 | class Test2Class {} 10 | 11 | describe('explorer.service', () => { 12 | let explorerService: ExplorerService; 13 | beforeEach(async () => { 14 | const testModuleRef = await Test.createTestingModule({ 15 | providers: [ExplorerService, TestClass, Test2Class], 16 | }).compile(); 17 | explorerService = testModuleRef.get(ExplorerService); 18 | }); 19 | 20 | it('explorer', async () => { 21 | const result = explorerService.explore(); 22 | expect(result.length).toBe(2); 23 | expect(result).toContain(TestClass); 24 | expect(result).toContain(Test2Class); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/util/service/explorer.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable, Type } from '@nestjs/common'; 2 | import { ModulesContainer } from '@nestjs/core'; 3 | import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; 4 | 5 | import { JsonRpcMetadataKey } from '../../../constants'; 6 | 7 | @Injectable() 8 | export class ExplorerService { 9 | @Inject(ModulesContainer) 10 | private readonly modulesContainer!: ModulesContainer; 11 | 12 | explore(): Type[] { 13 | const modules = [...this.modulesContainer.values()]; 14 | return modules 15 | .reduce( 16 | (acum, module) => (acum.push(...module.providers.values()), acum), 17 | [] as InstanceWrapper[] 18 | ) 19 | .map((instanceWrapper) => { 20 | const { instance } = instanceWrapper; 21 | if (!instance) { 22 | return undefined; 23 | } 24 | 25 | const metadata = Reflect.getMetadata( 26 | JsonRpcMetadataKey, 27 | instance.constructor 28 | ); 29 | return metadata ? (instance.constructor as Type) : undefined; 30 | }) 31 | .filter((i): i is Type => !!i); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/util/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler.service'; 2 | export * from './explorer.service'; 3 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/util/util.module.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test } from '@nestjs/testing'; 2 | import { UtilModule } from './util.module'; 3 | import { ExplorerService } from './service'; 4 | import { MAP_HANDLER } from '../../constants'; 5 | 6 | class TestClass {} 7 | class Test2Class {} 8 | 9 | describe('Check util module', () => { 10 | let utilModule: UtilModule; 11 | let explorerService: ExplorerService; 12 | let mapHandler: Map; 13 | beforeEach(async () => { 14 | const testModuleRef = await Test.createTestingModule({ 15 | imports: [UtilModule], 16 | providers: [TestClass, Test2Class], 17 | }).compile(); 18 | 19 | explorerService = testModuleRef.get(ExplorerService); 20 | utilModule = testModuleRef.get(UtilModule); 21 | mapHandler = testModuleRef.get(MAP_HANDLER); 22 | }); 23 | 24 | it('onApplicationBootstrap', async () => { 25 | jest 26 | .spyOn(explorerService, 'explore') 27 | .mockReturnValue([TestClass, Test2Class]); 28 | utilModule.onApplicationBootstrap(); 29 | expect(mapHandler.size).toBe(2); 30 | expect(mapHandler.get(TestClass.name)).toBeInstanceOf(TestClass); 31 | expect(mapHandler.get(Test2Class.name)).toBeInstanceOf(Test2Class); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const WS_EVENT_NAME = 'rpc'; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/factory/create-gateway.factory.ts: -------------------------------------------------------------------------------- 1 | import { WebSocketGatewayService } from '../service'; 2 | import { GatewayMetadata } from '@nestjs/websockets/interfaces'; 3 | import { WebSocketGateway } from '@nestjs/websockets'; 4 | import { Type } from '@nestjs/common'; 5 | 6 | export function createGatewayFactory( 7 | service: Type, 8 | config: GatewayMetadata 9 | ): Type { 10 | WebSocketGateway(config)(service); 11 | return service; 12 | } 13 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/factory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-gateway.factory'; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/filter/rpc-ws-error-exception.filter.ts: -------------------------------------------------------------------------------- 1 | import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'; 2 | import { WebSocket } from 'ws'; 3 | import { Socket } from 'socket.io'; 4 | 5 | import { getBodyError } from '../../../utils'; 6 | import { WS_EVENT_NAME } from '../constants'; 7 | 8 | @Catch() 9 | export class RpcWsErrorExceptionFilter implements ExceptionFilter { 10 | catch(exception: Error, host: ArgumentsHost): void { 11 | const body = getBodyError(exception); 12 | const client = host.switchToWs().getClient(); 13 | if (client instanceof WebSocket) { 14 | client.send(JSON.stringify({ event: WS_EVENT_NAME, data: body })); 15 | } else { 16 | client.emit(WS_EVENT_NAME, body); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './web-socket-gateway.service'; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/service/web-socket-gateway.service.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MessageBody, 3 | SubscribeMessage, 4 | WebSocketGateway, 5 | WsResponse, 6 | } from '@nestjs/websockets'; 7 | import { Inject, UseFilters, UsePipes } from '@nestjs/common'; 8 | import { HandlerService } from '../../util/service'; 9 | import { PayloadRpcData, RpcErrorObject, RpcResult } from '../../../types'; 10 | import { InputDataPipe } from '../../util/pipe/input-data.pipe'; 11 | import { WS_EVENT_NAME } from '../constants'; 12 | import { RpcWsErrorExceptionFilter } from '../filter/rpc-ws-error-exception.filter'; 13 | 14 | type WsRpcResponse = WsResponse< 15 | RpcResult | RpcErrorObject | Array 16 | >; 17 | 18 | @WebSocketGateway() 19 | export class WebSocketGatewayService { 20 | @Inject(HandlerService) private readonly handlerService!: HandlerService; 21 | 22 | @UsePipes(InputDataPipe) 23 | @UseFilters(new RpcWsErrorExceptionFilter()) 24 | @SubscribeMessage(WS_EVENT_NAME) 25 | async run(@MessageBody() body: PayloadRpcData): Promise { 26 | const result = await this.handlerService.runRpc(body); 27 | return { data: result, event: WS_EVENT_NAME }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/modules/ws-socket-transport/ws-socket-transport.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Provider } from '@nestjs/common'; 2 | import { Type } from '@nestjs/common/interfaces/type.interface'; 3 | import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface'; 4 | import { GatewayMetadata } from '@nestjs/websockets/interfaces'; 5 | 6 | import { WebSocketGatewayService } from './service'; 7 | import { createGatewayFactory } from './factory'; 8 | 9 | export class WsSocketTransportModule { 10 | static forRoot( 11 | wsConfig: GatewayMetadata, 12 | providers: Provider[], 13 | imports: Array< 14 | Type | DynamicModule | Promise | ForwardReference 15 | > = [] 16 | ): DynamicModule { 17 | return { 18 | module: WsSocketTransportModule, 19 | providers: [ 20 | ...providers, 21 | createGatewayFactory(WebSocketGatewayService, wsConfig), 22 | ], 23 | imports, 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './async-iterator.provider'; 2 | export * from './map-handler-store.provider'; 3 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/providers/map-handler-store.provider.ts: -------------------------------------------------------------------------------- 1 | import { ValueProvider } from '@nestjs/common'; 2 | import { MAP_HANDLER } from '../constants'; 3 | 4 | export const mapHandlerStoreProvider: ValueProvider = { 5 | provide: MAP_HANDLER, 6 | useValue: new Map(), 7 | }; 8 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/providers/zod-input-data.provider.ts: -------------------------------------------------------------------------------- 1 | import { ValueProvider } from '@nestjs/common'; 2 | import { ZOD_INPUT_DATA } from '../constants'; 3 | import { ZPayloadRpc } from '../types'; 4 | 5 | export const zodInputDataProvider: ValueProvider = { 6 | provide: ZOD_INPUT_DATA, 7 | useValue: ZPayloadRpc, 8 | }; 9 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/types/error-code-type.ts: -------------------------------------------------------------------------------- 1 | export enum ErrorCodeType { 2 | ParseError = 'Parse error', 3 | InvalidRequest = 'Invalid request', 4 | MethodNotFound = 'Method not found', 5 | InvalidParams = 'Invalid params', 6 | InternalError = 'Internal error', 7 | ServerError = 'Server error', 8 | } 9 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/types/error-payloade.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | import { zVersion } from './payloade'; 4 | 5 | const zRpcIdError = z.union([z.number(), z.null()]); 6 | const zRpcErrorData = z.object({ 7 | title: z.string(), 8 | description: z.string().optional(), 9 | }); 10 | const zRpcError = z.object({ 11 | message: z.string(), 12 | code: z.number(), 13 | data: zRpcErrorData.optional(), 14 | }); 15 | 16 | export const ZRpcError = z.object({ 17 | jsonrpc: zVersion, 18 | error: zRpcError, 19 | id: zRpcIdError, 20 | }); 21 | 22 | export type RpcErrorObject = z.infer; 23 | export type RpcErrorData = z.infer; 24 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module-options'; 2 | export * from './payloade'; 3 | export * from './error-code-type'; 4 | export * from './utils'; 5 | export * from './error-payloade'; 6 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/types/module-options.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DynamicModule, 3 | ForwardReference, 4 | Provider, 5 | Type, 6 | } from '@nestjs/common'; 7 | import { GatewayMetadata } from '@nestjs/websockets/interfaces'; 8 | 9 | export enum TransportType { 10 | HTTP, 11 | WS, 12 | } 13 | 14 | export type HttpTransportConfig = { 15 | transport: TransportType.HTTP; 16 | path: string; 17 | }; 18 | 19 | export type WSTransportConfig = { 20 | transport: TransportType.WS; 21 | wsConfig: GatewayMetadata; 22 | }; 23 | 24 | export type CommonRpcConfig = { 25 | providers?: Provider[]; 26 | imports?: Array< 27 | Type | DynamicModule | Promise | ForwardReference 28 | >; 29 | }; 30 | 31 | export type JsonRpcHttpConfig = CommonRpcConfig & HttpTransportConfig; 32 | export type JsonRpcWsConfig = CommonRpcConfig & WSTransportConfig; 33 | 34 | export type JsonRpcConfig = JsonRpcHttpConfig | JsonRpcWsConfig; 35 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/types/utils.ts: -------------------------------------------------------------------------------- 1 | export type ValueOf = T[keyof T]; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './error'; 2 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "target": "es2021", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strictBindCallApply": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/json-rpc/nestjs-json-rpc/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 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /libs/microorm-database/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/microorm-database/README.md: -------------------------------------------------------------------------------- 1 | # microorm-database 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test microorm-database` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/microorm-database/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | displayName: 'microorm-database', 3 | preset: '../../jest.preset.js', 4 | testEnvironment: 'node', 5 | transform: { 6 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'html'], 9 | coverageDirectory: '../../coverage/libs/microorm-database', 10 | }; 11 | -------------------------------------------------------------------------------- /libs/microorm-database/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "microorm-database", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/microorm-database/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "// targets": "to see all targets run: nx show project microorm-database --web", 8 | "targets": {} 9 | } 10 | -------------------------------------------------------------------------------- /libs/microorm-database/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/micro-orm-database.module'; 2 | export * from './lib/entities'; 3 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/config.ts: -------------------------------------------------------------------------------- 1 | import { Options } from '@mikro-orm/core'; 2 | 3 | import ormConfig from './config-cli'; 4 | 5 | const { entitiesTs, ...configOther } = ormConfig; 6 | 7 | export const config: Options = { 8 | discovery: { requireEntitiesArray: true }, 9 | contextName: 'default', 10 | // @ts-ignore 11 | registerRequestContext: false, 12 | ...configOther, 13 | }; 14 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/entities/book-list.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Entity, 3 | PrimaryKey, 4 | Property, 5 | ManyToMany, 6 | Collection, 7 | } from '@mikro-orm/core'; 8 | 9 | import { IUsers, Users } from './users'; 10 | 11 | export type IBookList = BookList; 12 | 13 | @Entity({ 14 | tableName: 'book_list', 15 | }) 16 | export class BookList { 17 | @PrimaryKey({ 18 | type: 'uuid', 19 | defaultRaw: 'uuid_generate_v4()', 20 | }) 21 | public id!: string; 22 | 23 | @Property({ 24 | type: 'text', 25 | nullable: false, 26 | }) 27 | public text!: string; 28 | 29 | @Property({ 30 | length: 0, 31 | name: 'created_at', 32 | nullable: true, 33 | defaultRaw: 'CURRENT_TIMESTAMP(0)', 34 | columnType: 'timestamp(0) without time zone', 35 | type: 'timestamp', 36 | }) 37 | createdAt: Date = new Date(); 38 | 39 | @Property({ 40 | length: 0, 41 | onUpdate: () => new Date(), 42 | name: 'updated_at', 43 | nullable: true, 44 | columnType: 'timestamp(0) without time zone', 45 | defaultRaw: 'CURRENT_TIMESTAMP(0)', 46 | }) 47 | updatedAt: Date = new Date(); 48 | 49 | @ManyToMany(() => Users, (item) => item.books) 50 | public users = new Collection(this); 51 | } 52 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/entities/index.ts: -------------------------------------------------------------------------------- 1 | export * from './users'; 2 | export * from './roles'; 3 | export * from './addresses'; 4 | export * from './comments'; 5 | export * from './book-list'; 6 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/micro-orm-database.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { MikroOrmModule } from '@mikro-orm/nestjs'; 3 | import { MikroOrmCoreModule } from '@mikro-orm/nestjs/mikro-orm-core.module'; 4 | 5 | import { config } from './config'; 6 | 7 | @Module({ 8 | imports: [MikroOrmModule.forRoot(config), MikroOrmModule.forMiddleware()], 9 | exports: [MikroOrmCoreModule], 10 | }) 11 | export class MicroOrmDatabaseModule {} 12 | 13 | export { config }; 14 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123104848_CreateUsersTable.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123104848_CreateUsersTable extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`create table "users" ("id" serial primary key, "login" varchar(100) not null, "first_name" varchar(100) null default 'NULL', "last_name" varchar(100) null default 'NULL', "is_active" boolean null default false, "created_at" timestamp(0) without time zone null default current_timestamp(0), "updated_at" timestamp(0) without time zone null default current_timestamp(0));`); 7 | this.addSql(`alter table "users" add constraint "users_login_unique" unique ("login");`); 8 | } 9 | 10 | override async down(): Promise { 11 | this.addSql(`drop table if exists "users" cascade;`); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123105611_CreateAddressesTable.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123105611_CreateAddressesTable extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`create table "addresses" ("id" serial primary key, "city" varchar(70) null, "state" varchar(70) null, "country" varchar(68) null, "created_at" timestamp(0) without time zone null default current_timestamp(0), "updated_at" timestamp(0) without time zone null default current_timestamp(0));`); 7 | } 8 | 9 | override async down(): Promise { 10 | this.addSql(`drop table if exists "addresses" cascade;`); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123110115_CreateRolesTable.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123110115_CreateRolesTable extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`create table "roles" ("id" serial primary key, "name" varchar(128) null default 'NULL', "key" varchar(128) not null, "is_default" boolean not null default 'false', "created_at" timestamp(0) without time zone null default current_timestamp(0), "updated_at" timestamp(0) without time zone null default current_timestamp(0));`); 7 | this.addSql(`alter table "roles" add constraint "roles_key_unique" unique ("key");`); 8 | } 9 | 10 | override async down(): Promise { 11 | this.addSql(`drop table if exists "roles" cascade;`); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123111042_CreateCommentsTable.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123111042_CreateCommentsTable extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`create type "comment_kind_enum" as enum ('COMMENT', 'MESSAGE', 'NOTE');`); 7 | this.addSql(`create table "comments" ("id" serial primary key, "text" text not null, "kind" "comment_kind_enum" not null, "created_at" timestamp(0) without time zone null default current_timestamp(0), "updated_at" timestamp(0) without time zone null default current_timestamp(0));`); 8 | } 9 | 10 | override async down(): Promise { 11 | this.addSql(`drop table if exists "comments" cascade;`); 12 | 13 | this.addSql(`drop type "comment_kind_enum";`); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123123708_CreateUsersRolesRelations.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123123708_CreateUsersRolesRelations extends Migration { 4 | override async up(): Promise { 5 | this.addSql( 6 | `create table "users_have_roles" ("users_id" int not null, "roles_id" int not null, constraint "users_have_roles_pkey" primary key ("users_id", "roles_id"));` 7 | ); 8 | 9 | this.addSql( 10 | `alter table "users_have_roles" add constraint "users_have_roles_users_id_foreign" foreign key ("users_id") references "users" ("id") on update cascade on delete cascade;` 11 | ); 12 | this.addSql( 13 | `alter table "users_have_roles" add constraint "users_have_roles_roles_id_foreign" foreign key ("roles_id") references "roles" ("id") on update cascade on delete cascade;` 14 | ); 15 | } 16 | 17 | override async down(): Promise { 18 | this.addSql(`drop table if exists "users_have_roles" cascade;`); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123124745_CreateUsersUsersRelations.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123124745_CreateUsersUsersRelations extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`alter table "users" add column "manager_id" int null;`); 7 | this.addSql(`alter table "users" add constraint "users_manager_id_foreign" foreign key ("manager_id") references "users" ("id") on update cascade on delete set null;`); 8 | this.addSql(`alter table "users" add constraint "users_manager_id_unique" unique ("manager_id");`); 9 | } 10 | 11 | override async down(): Promise { 12 | this.addSql(`alter table "users" drop constraint "users_manager_id_foreign";`); 13 | 14 | this.addSql(`alter table "users" drop constraint "users_manager_id_unique";`); 15 | this.addSql(`alter table "users" drop column "manager_id";`); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123125941_CreateUsersAddressRelations.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123125941_CreateUsersAddressRelations extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`alter table "users" add column "addresses_id" int not null;`); 7 | this.addSql(`alter table "users" add constraint "users_addresses_id_foreign" foreign key ("addresses_id") references "addresses" ("id") on update cascade;`); 8 | this.addSql(`alter table "users" add constraint "users_addresses_id_unique" unique ("addresses_id");`); 9 | } 10 | 11 | override async down(): Promise { 12 | this.addSql(`alter table "users" drop constraint "users_addresses_id_foreign";`); 13 | 14 | this.addSql(`alter table "users" drop constraint "users_addresses_id_unique";`); 15 | this.addSql(`alter table "users" drop column "addresses_id";`); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123130345_CreateUsersCommentsRelations.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123130345_CreateUsersCommentsRelations extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`alter table "comments" add column "created_by" int not null;`); 7 | this.addSql(`alter table "comments" add constraint "comments_created_by_foreign" foreign key ("created_by") references "users" ("id") on update cascade;`); 8 | } 9 | 10 | override async down(): Promise { 11 | this.addSql(`alter table "comments" drop constraint "comments_created_by_foreign";`); 12 | 13 | this.addSql(`alter table "comments" drop column "created_by";`); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123131039_CreateBookListTable.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123131039_CreateBookListTable extends Migration { 4 | override async up(): Promise { 5 | this.addSql(`create extension if not exists "uuid-ossp";`); 6 | this.addSql( 7 | `create table "book_list" ("id" uuid not null default uuid_generate_v4(), "text" text not null, "created_at" timestamp(0) without time zone null default current_timestamp(0), "updated_at" timestamp(0) without time zone null default current_timestamp(0), constraint "book_list_pkey" primary key ("id"));` 8 | ); 9 | } 10 | 11 | override async down(): Promise { 12 | this.addSql(`drop table if exists "book_list" cascade;`); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /libs/microorm-database/src/lib/migrations/Migration20250123131438_CreateUsersBookListRelations.ts: -------------------------------------------------------------------------------- 1 | import { Migration } from '@mikro-orm/migrations'; 2 | 3 | export class Migration20250123131438_CreateUsersBookListRelations extends Migration { 4 | 5 | override async up(): Promise { 6 | this.addSql(`create table "users_have_book" ("users_id" int not null, "book_list_id" uuid not null, constraint "users_have_book_pkey" primary key ("users_id", "book_list_id"));`); 7 | 8 | this.addSql(`alter table "users_have_book" add constraint "users_have_book_users_id_foreign" foreign key ("users_id") references "users" ("id") on update cascade on delete cascade;`); 9 | this.addSql(`alter table "users_have_book" add constraint "users_have_book_book_list_id_foreign" foreign key ("book_list_id") references "book_list" ("id") on update cascade on delete cascade;`); 10 | } 11 | 12 | override async down(): Promise { 13 | this.addSql(`drop table if exists "users_have_book" cascade;`); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /libs/microorm-database/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true, 10 | "noPropertyAccessFromIndexSignature": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/microorm-database/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"], 7 | "target": "es2021", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "strictBindCallApply": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noFallthroughCasesInSwitch": true 13 | }, 14 | "include": ["src/**/*.ts"], 15 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /libs/microorm-database/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "moduleResolution": "node10", 7 | "types": ["jest", "node"] 8 | }, 9 | "include": [ 10 | "jest.config.ts", 11 | "src/**/*.test.ts", 12 | "src/**/*.spec.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /libs/type-for-rpc/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | }, 17 | { 18 | "files": ["*.json"], 19 | "parser": "jsonc-eslint-parser", 20 | "rules": { 21 | "@nx/dependency-checks": "error" 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /libs/type-for-rpc/README.md: -------------------------------------------------------------------------------- 1 | # type-for-rpc 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Building 6 | 7 | Run `nx build type-for-rpc` to build the library. 8 | 9 | ## Running unit tests 10 | 11 | Run `nx test type-for-rpc` to execute the unit tests via [Jest](https://jestjs.io). 12 | -------------------------------------------------------------------------------- /libs/type-for-rpc/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'type-for-rpc', 4 | preset: '../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../coverage/libs/type-for-rpc', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/type-for-rpc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nestjs-json-api/type-for-rpc", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "tslib": "^2.3.0" 6 | }, 7 | "type": "commonjs", 8 | "main": "./src/index.js", 9 | "typings": "./src/index.d.ts" 10 | } 11 | -------------------------------------------------------------------------------- /libs/type-for-rpc/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "type-for-rpc", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/type-for-rpc/src", 5 | "projectType": "library", 6 | "targets": { 7 | "build": { 8 | "executor": "@nx/js:tsc", 9 | "outputs": ["{options.outputPath}"], 10 | "options": { 11 | "outputPath": "dist/libs/type-for-rpc", 12 | "main": "libs/type-for-rpc/src/index.ts", 13 | "tsConfig": "libs/type-for-rpc/tsconfig.lib.json", 14 | "assets": ["libs/type-for-rpc/*.md"] 15 | } 16 | } 17 | }, 18 | "tags": [] 19 | } 20 | -------------------------------------------------------------------------------- /libs/type-for-rpc/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/rpc-service'; 2 | -------------------------------------------------------------------------------- /libs/type-for-rpc/src/lib/rpc-service.ts: -------------------------------------------------------------------------------- 1 | export type InputType = { 2 | a: number; 3 | b: number; 4 | }; 5 | 6 | export type OutputType = { 7 | c: string; 8 | d: string; 9 | }; 10 | 11 | export interface RpcService { 12 | someMethode(firstArg: number): Promise; 13 | someOtherMethode(firstArg: number, secondArgument: number): Promise; 14 | methodeWithObjectParams(a: InputType): Promise; 15 | } 16 | -------------------------------------------------------------------------------- /libs/type-for-rpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/type-for-rpc/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/type-for-rpc/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 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /libs/typeorm-database/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.base.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 7 | "rules": {} 8 | }, 9 | { 10 | "files": ["*.ts", "*.tsx"], 11 | "rules": {} 12 | }, 13 | { 14 | "files": ["*.js", "*.jsx"], 15 | "rules": {} 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /libs/typeorm-database/README.md: -------------------------------------------------------------------------------- 1 | # typeorm-database 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test typeorm-database` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /libs/typeorm-database/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export default { 3 | displayName: 'typeorm-database', 4 | preset: '../../jest.preset.js', 5 | testEnvironment: 'node', 6 | transform: { 7 | '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], 8 | }, 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageDirectory: '../../coverage/libs/typeorm-database', 11 | }; 12 | -------------------------------------------------------------------------------- /libs/typeorm-database/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typeorm-database", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "sourceRoot": "libs/typeorm-database/src", 5 | "projectType": "library", 6 | "tags": [], 7 | "// targets": "to see all targets run: nx show project typeorm-database --web", 8 | "targets": {} 9 | } 10 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/type-orm-database.module'; 2 | export * from './lib/entities'; 3 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/config.ts: -------------------------------------------------------------------------------- 1 | import { TypeOrmModuleOptions } from '@nestjs/typeorm'; 2 | 3 | import { config as ormConfig } from './config-cli'; 4 | import * as allEntities from './entities'; 5 | 6 | export const config: TypeOrmModuleOptions = { 7 | ...ormConfig, 8 | ...{ 9 | entities: Object.values(allEntities) as any, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities-mysql/addresses.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryGeneratedColumn, 3 | OneToOne, 4 | Column, 5 | Entity, 6 | UpdateDateColumn, 7 | } from 'typeorm'; 8 | 9 | import { Users, IUsers } from '.'; 10 | 11 | export type IAddresses = Addresses; 12 | 13 | @Entity('addresses') 14 | export class Addresses { 15 | @PrimaryGeneratedColumn() 16 | public id!: number; 17 | 18 | @Column({ 19 | type: 'varchar', 20 | length: 70, 21 | nullable: true, 22 | default: 'NULL', 23 | }) 24 | public city!: string; 25 | 26 | @Column({ 27 | type: 'varchar', 28 | length: 70, 29 | nullable: true, 30 | default: 'NULL', 31 | }) 32 | public state!: string; 33 | 34 | @Column({ 35 | type: 'varchar', 36 | length: 68, 37 | nullable: true, 38 | default: 'NULL', 39 | }) 40 | public country!: string; 41 | 42 | @Column({ 43 | name: 'created_at', 44 | type: 'timestamp', 45 | nullable: true, 46 | }) 47 | public createdAt!: Date; 48 | 49 | @UpdateDateColumn({ 50 | name: 'updated_at', 51 | type: 'timestamp', 52 | nullable: true, 53 | }) 54 | public updatedAt!: Date; 55 | 56 | @OneToOne(() => Users, (item) => item.addresses) 57 | public user!: IUsers; 58 | } 59 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities-mysql/book-list.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Column, 3 | Entity, 4 | ManyToMany, 5 | PrimaryGeneratedColumn, 6 | UpdateDateColumn, 7 | } from 'typeorm'; 8 | 9 | import { IUsers, Users } from './users'; 10 | 11 | export type IBookList = BookList; 12 | 13 | @Entity('book_list') 14 | export class BookList { 15 | @PrimaryGeneratedColumn() 16 | public id!: string; 17 | 18 | @Column({ 19 | type: 'text', 20 | nullable: false, 21 | }) 22 | public text!: string; 23 | 24 | @Column({ 25 | name: 'created_at', 26 | type: 'timestamp', 27 | nullable: true, 28 | }) 29 | public createdAt!: Date; 30 | 31 | @UpdateDateColumn({ 32 | name: 'updated_at', 33 | type: 'timestamp', 34 | nullable: true, 35 | }) 36 | public updatedAt!: Date; 37 | 38 | @ManyToMany(() => Users, (item) => item.books) 39 | public users!: IUsers[]; 40 | } 41 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities-mysql/comments.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryGeneratedColumn, 3 | Column, 4 | Entity, 5 | JoinColumn, 6 | ManyToOne, 7 | UpdateDateColumn, 8 | } from 'typeorm'; 9 | 10 | export enum CommentKind { 11 | Comment = 'COMMENT', 12 | Message = 'MESSAGE', 13 | Note = 'NOTE', 14 | } 15 | 16 | import { Users, IUsers } from '.'; 17 | 18 | export type IComments = Comments; 19 | 20 | @Entity('comments') 21 | export class Comments { 22 | @PrimaryGeneratedColumn() 23 | public id!: number; 24 | 25 | @Column({ 26 | type: 'text', 27 | nullable: false, 28 | }) 29 | public text!: string; 30 | 31 | @Column({ 32 | type: 'enum', 33 | enum: CommentKind, 34 | nullable: false, 35 | }) 36 | public kind!: CommentKind; 37 | 38 | @Column({ 39 | name: 'created_at', 40 | type: 'timestamp', 41 | nullable: true, 42 | }) 43 | public createdAt!: Date; 44 | 45 | @UpdateDateColumn({ 46 | name: 'updated_at', 47 | type: 'timestamp', 48 | nullable: true, 49 | }) 50 | public updatedAt!: Date; 51 | 52 | @ManyToOne(() => Users, (item: Users) => item.id) 53 | @JoinColumn({ 54 | name: 'created_by', 55 | }) 56 | public createdBy!: IUsers; 57 | } 58 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities-mysql/index.ts: -------------------------------------------------------------------------------- 1 | export * from './addresses'; 2 | export * from './roles'; 3 | export * from './users'; 4 | export * from './comments'; 5 | export * from './book-list'; 6 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities-mysql/roles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryGeneratedColumn, 3 | Entity, 4 | Column, 5 | ManyToMany, 6 | UpdateDateColumn, 7 | } from 'typeorm'; 8 | 9 | import { Users, IUsers } from '.'; 10 | 11 | export type IRoles = Roles; 12 | 13 | @Entity('roles') 14 | export class Roles { 15 | @PrimaryGeneratedColumn() 16 | public id!: number; 17 | 18 | @Column({ 19 | type: 'varchar', 20 | length: 128, 21 | nullable: true, 22 | default: 'NULL', 23 | }) 24 | public name!: string; 25 | 26 | @Column({ 27 | type: 'varchar', 28 | length: 128, 29 | nullable: false, 30 | unique: true, 31 | }) 32 | public key!: string; 33 | 34 | @Column({ 35 | name: 'is_default', 36 | default: false, 37 | }) 38 | public isDefault!: boolean; 39 | 40 | @Column({ 41 | name: 'created_at', 42 | type: 'timestamp', 43 | nullable: true, 44 | }) 45 | public createdAt!: Date; 46 | 47 | @UpdateDateColumn({ 48 | name: 'updated_at', 49 | type: 'timestamp', 50 | nullable: true, 51 | }) 52 | public updatedAt!: Date; 53 | 54 | @ManyToMany(() => Users, (item: Users) => item.roles) 55 | public users!: IUsers[]; 56 | } 57 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities/book-list.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Column, 3 | Entity, 4 | ManyToMany, 5 | PrimaryGeneratedColumn, 6 | UpdateDateColumn, 7 | } from 'typeorm'; 8 | 9 | import { IUsers, Users } from './users'; 10 | 11 | export type IBookList = BookList; 12 | 13 | @Entity('book_list') 14 | export class BookList { 15 | @PrimaryGeneratedColumn() 16 | public id!: string; 17 | 18 | @Column({ 19 | type: 'text', 20 | nullable: false, 21 | }) 22 | public text!: string; 23 | 24 | @Column({ 25 | name: 'created_at', 26 | type: 'timestamp', 27 | nullable: true, 28 | default: 'CURRENT_TIMESTAMP', 29 | }) 30 | public createdAt!: Date; 31 | 32 | @UpdateDateColumn({ 33 | name: 'updated_at', 34 | type: 'timestamp', 35 | nullable: true, 36 | default: 'CURRENT_TIMESTAMP', 37 | }) 38 | public updatedAt!: Date; 39 | 40 | @ManyToMany(() => Users, (item) => item.books) 41 | public users!: IUsers[]; 42 | } 43 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities/index.ts: -------------------------------------------------------------------------------- 1 | export * from './addresses'; 2 | export * from './roles'; 3 | export * from './users'; 4 | export * from './comments'; 5 | export * from './users-have-roles'; 6 | export * from './book-list'; 7 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/entities/users-have-roles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrimaryGeneratedColumn, 3 | Entity, 4 | Column, 5 | UpdateDateColumn, 6 | } from 'typeorm'; 7 | 8 | @Entity('users_have_roles') 9 | export class UsersHaveRoles { 10 | @PrimaryGeneratedColumn() 11 | public id!: number; 12 | 13 | @Column({ 14 | name: 'users_id', 15 | type: 'int', 16 | nullable: false, 17 | unique: false, 18 | }) 19 | public userId!: number; 20 | 21 | @Column({ 22 | name: 'roles_id', 23 | type: 'int', 24 | nullable: false, 25 | unique: false, 26 | }) 27 | public roleId!: number; 28 | 29 | @Column({ 30 | name: 'created_at', 31 | type: 'timestamp', 32 | nullable: true, 33 | default: 'CURRENT_TIMESTAMP', 34 | }) 35 | public createdAt!: Date; 36 | 37 | @UpdateDateColumn({ 38 | name: 'updated_at', 39 | type: 'timestamp', 40 | nullable: true, 41 | default: 'CURRENT_TIMESTAMP', 42 | }) 43 | public updatedAt!: Date; 44 | } 45 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/seeders/factory/addresses.factory.ts: -------------------------------------------------------------------------------- 1 | import { FactorizedAttrs, Factory } from '@jorgebodega/typeorm-factory'; 2 | import { faker } from '@faker-js/faker'; 3 | 4 | import { Addresses } from '../../entities'; 5 | import { DataSource } from 'typeorm'; 6 | 7 | export class AddressesFactory extends Factory { 8 | protected entity = Addresses; 9 | protected attrs(): FactorizedAttrs { 10 | return { 11 | city: faker.location.city(), 12 | state: faker.location.state(), 13 | country: faker.location.country(), 14 | }; 15 | } 16 | 17 | constructor(protected dataSource: DataSource) { 18 | super(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/seeders/factory/comments.factory.ts: -------------------------------------------------------------------------------- 1 | import { FactorizedAttrs, Factory } from '@jorgebodega/typeorm-factory'; 2 | import { faker } from '@faker-js/faker'; 3 | import { DataSource } from 'typeorm'; 4 | import { CommentKind, Comments } from '../../entities'; 5 | 6 | export class CommentsFactory extends Factory { 7 | protected entity = Comments; 8 | protected attrs(): FactorizedAttrs { 9 | const text = faker.lorem.paragraph(faker.number.int(5)); 10 | return { 11 | kind: CommentKind.Comment, 12 | text, 13 | }; 14 | } 15 | 16 | constructor(protected dataSource: DataSource) { 17 | super(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/seeders/factory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './addresses.factory'; 2 | export * from './comments.factory'; 3 | export * from './user.factory'; 4 | export * from './roles.factory'; 5 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/seeders/factory/roles.factory.ts: -------------------------------------------------------------------------------- 1 | import { FactorizedAttrs, Factory } from '@jorgebodega/typeorm-factory'; 2 | import { DataSource } from 'typeorm'; 3 | import { faker } from '@faker-js/faker'; 4 | import { Roles } from '../../entities'; 5 | 6 | export class RolesFactory extends Factory { 7 | protected entity = Roles; 8 | protected rolesList = ['USERS', 'ADMIN', 'OTHER']; 9 | protected attrs(): FactorizedAttrs { 10 | const key = faker.number.int(this.rolesList.length - 1); 11 | return { 12 | name: this.rolesList[key].toLowerCase(), 13 | key: this.rolesList[key], 14 | }; 15 | } 16 | 17 | constructor(protected dataSource: DataSource) { 18 | super(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/seeders/root.seeder.ts: -------------------------------------------------------------------------------- 1 | import { Seeder } from '@jorgebodega/typeorm-seeding'; 2 | import { DataSource } from 'typeorm'; 3 | 4 | import { AddressesFactory, UserFactory } from './factory'; 5 | 6 | export default class RootSeeder extends Seeder { 7 | async run(dataSource: DataSource): Promise { 8 | await new UserFactory(dataSource).createMany(10); 9 | await new AddressesFactory(dataSource).createMany(10); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /libs/typeorm-database/src/lib/type-orm-database.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | 4 | import { config } from './config'; 5 | 6 | @Module({ 7 | imports: [TypeOrmModule.forRoot(config)], 8 | exports: [TypeOrmModule], 9 | }) 10 | export class TypeOrmDatabaseModule {} 11 | -------------------------------------------------------------------------------- /libs/typeorm-database/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /libs/typeorm-database/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/typeorm-database/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 | "jest.config.ts", 10 | "src/**/*.test.ts", 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nestjs-json-api/source", 3 | "$schema": "node_modules/nx/schemas/project-schema.json", 4 | "targets": { 5 | "local-registry": { 6 | "executor": "@nx/js:verdaccio", 7 | "options": { 8 | "port": 4873, 9 | "config": ".verdaccio/config.yml", 10 | "storage": "tmp/local-registry/storage" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tools/scripts/preparation-npm-package.mjs: -------------------------------------------------------------------------------- 1 | import devkit from '@nx/devkit'; 2 | 3 | import {readdirSync, statSync, rmdirSync} from 'fs'; 4 | import {join} from 'path'; 5 | 6 | const { readCachedProjectGraph } = devkit; 7 | 8 | 9 | function cleanEmptyFoldersRecursively(folder) { 10 | if (!statSync(folder).isDirectory()) return 11 | let files = readdirSync(folder); 12 | if (files.length > 0) { 13 | files.forEach((file) => cleanEmptyFoldersRecursively(join(folder, file))); 14 | 15 | // re-evaluate files; after deleting subfolder 16 | // we may have parent folder empty now 17 | files = readdirSync(folder); 18 | } 19 | 20 | if (files.length === 0) { 21 | rmdirSync(folder); 22 | } 23 | } 24 | 25 | const [, , name] = process.argv; 26 | 27 | const graph = readCachedProjectGraph(); 28 | const project = graph.nodes[name]; 29 | 30 | const outputPath = project.data?.targets?.build?.options?.outputPath; 31 | 32 | process.chdir(outputPath); 33 | 34 | cleanEmptyFoldersRecursively('./') 35 | --------------------------------------------------------------------------------