{"id":15408894,"url":"https://github.com/antongolub/nestjs-esm-fix","last_synced_at":"2025-06-26T20:34:05.148Z","repository":{"id":57750125,"uuid":"524994449","full_name":"antongolub/nestjs-esm-fix","owner":"antongolub","description":"Patch Nestjs app ESM bundles to make them work RHRN","archived":false,"fork":false,"pushed_at":"2023-08-30T09:31:06.000Z","size":160,"stargazers_count":5,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-01T13:34:33.569Z","etag":null,"topics":["esbuild","esm","nestjs","tsc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antongolub.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-15T13:18:03.000Z","updated_at":"2023-10-21T04:07:06.000Z","dependencies_parsed_at":"2024-06-21T17:33:14.595Z","dependency_job_id":"255be24d-1e70-4cce-84db-b9ceca121723","html_url":"https://github.com/antongolub/nestjs-esm-fix","commit_stats":{"total_commits":68,"total_committers":4,"mean_commits":17.0,"dds":0.3970588235294118,"last_synced_commit":"dc241a8118a74e29c26c8547aada1219d65304f4"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antongolub%2Fnestjs-esm-fix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antongolub%2Fnestjs-esm-fix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antongolub%2Fnestjs-esm-fix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antongolub%2Fnestjs-esm-fix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antongolub","download_url":"https://codeload.github.com/antongolub/nestjs-esm-fix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223696445,"owners_count":17187628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esbuild","esm","nestjs","tsc"],"created_at":"2024-10-01T16:35:41.835Z","updated_at":"2024-11-08T14:04:33.707Z","avatar_url":"https://github.com/antongolub.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nestjs-esm-fix\n[![CI](https://github.com/antongolub/nestjs-esm-fix/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/antongolub/nestjs-esm-fix/actions/workflows/ci.yaml)\n[![Maintainability](https://api.codeclimate.com/v1/badges/af8edb33072e8e033ce7/maintainability)](https://codeclimate.com/github/antongolub/nestjs-esm-fix/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/af8edb33072e8e033ce7/test_coverage)](https://codeclimate.com/github/antongolub/nestjs-esm-fix/test_coverage)\n[![npm (tag)](https://img.shields.io/npm/v/nestjs-esm-fix)](https://www.npmjs.com/package/nestjs-esm-fix)\n\n\u003e Patch [Nestjs](https://github.com/nestjs/nest) app ESM bundles to make them work RHRN  \n\u003e ⚠️ This is a temporary solution until Nestjs is fixed\n\n## Stack\n* [Nestjs 9.x](https://github.com/nestjs/nest). \u003csub\u003e_10.x and above were not tested at all_\u003c/sub\u003e\n* [esbuild 0.15.x](https://github.com/evanw/esbuild)\n\n## Problems\n\u003e https://github.com/nestjs/nest-cli/issues/1157\n\u003e https://github.com/nestjs/swagger/issues/1450\n\u003e https://github.com/evanw/esbuild/pull/509\n\u003e https://github.com/evanw/esbuild/issues/566\n\n1. `openapi` is not defined. https://github.com/nestjs/swagger/issues/1450\n```js\n__decorate([\n  Post('event-unsafe-batch'),\n  HttpCode(200),\n  openapi.ApiResponse({ status: 200, type: String }),\n  __param(0, Body()),\n  __param(1, Req()),\n  __metadata(\"design:type\", Function),\n  __metadata(\"design:paramtypes\", [Object, Object]),\n  __metadata(\"design:returntype\", Promise)\n], EventUnsafeController.prototype, \"logEventBatch\", null);\n```\n\n2. openapi / class-validator DTOs are referenced by `require` API. https://github.com/microsoft/TypeScript/issues/43329\n```js\nexport class CspReportDto {\n  static _OPENAPI_METADATA_FACTORY() {\n    return { timestamp: { required: false, type: () =\u003e Object }, 'csp-report': { required: true, type: () =\u003e require(\"./csp.dto.js\").CspReport } };\n  }\n}\n```\n\n3. NodeJS builtins are referenced via `require` API.\n```js\nvar require_async4 = __commonJS({\n  \"node_modules/resolve/lib/async.js\"(exports, module2) {\n    var fs2 = require(\"fs\");\n```\n\n4. esbuild-compiled ESM bundle cannot refer to `views/redoc.handlebars`\n```js\nconst redocFilePath = path_1.default.join(__dirname, \"..\", \"views\", \"redoc.handlebars\");\n```\n\n5. `_OPENAPI_METADATA_FACTORY` class fields may be empty, so the swagger declaration cannot be properly rendered.\n```js\nvar Meta = class {\n};\n// →\nvar Meta = class {\n  static _OPENAPI_METADATA_FACTORY() {\n    return { appName: { required: false,  type: () =\u003e  String }, appHost: { required: false,  type: () =\u003e  String }, appVersion: { required: false,  type: () =\u003e  String }, appNamespace: { required: false,  type: () =\u003e  String }, appConfig: { required: false,  type: () =\u003e  typeof (_a3 = typeof Record !== \"undefined\" \u0026\u0026 Record) === \"function\" ? _a3 : Object }, deviceInfo: { required: false,  type: () =\u003e  typeof (_b3 = typeof Record !== \"undefined\" \u0026\u0026 Record) === \"function\" ? _b3 : Object }, userAgent: { required: false,  type: () =\u003e  String }, envProfile: { required: false,  enum:  typeof (_c = typeof import_substrate2.EnvironmentProfile !== \"undefined\" \u0026\u0026 import_substrate2.EnvironmentProfile) === \"function\" ? _c : Object } }\n  }\n};\n```\n\n6. Extra type wrappers cannot be processed by openapi / `class-validator` / `class-transformer`\n```js\n  __metadata(\"design:type\", typeof (_d = typeof Array !== \"undefined\" \u0026\u0026 Array) === \"function\" ? _d : Object)\n  __metadata(\"design:type\", typeof (_e = typeof import_substrate2.LogLevel !== \"undefined\" \u0026\u0026 import_substrate2.LogLevel) === \"function\" ? _e : Object)\n  // →\n  __metadata(\"design:type\", Array)\n  __metadata(\"design:type\", import_substrate2.LogLevel)\n```\n\n## Solution\nOld good monkey patching.\n\n## Install\n```bash\nyarn add -D nestjs-esm-fix\n```\n\n## Usage\n### CLI\n```bash\nnestjs-esm-fix target/**/*.js\nnestjs-esm-fix --target=target/**/*.js\nnestjs-esm-fix --target=**/* --cwd=target\n```\n| Option                    | Description                                                                                                            | Default         |\n|---------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------|\n| `--target`                | Pattern to match files to fix.                                                                                         | `**/*`          |\n| `--cwd`                   | Current working dir.                                                                                                   | `process.cwd()` |\n| `--openapi-complex-types` | Simplify `__metadata(\"design:type\")` declarations.                                                                     | `true`          |\n| `--openapi-meta`          | Restore `static OPENAPI_METADATA_FACTORY` if missing.                                                                  | `true`          |\n| `--openapi-var`           | Inject openapi variable. Set `--no-openapi-var` to disable.                                                            | `true`          |\n| `--dirname-var`           | Inject `__dirname` and `__filename` polyfills.                                                                         | `true`          |\n| `--importify`             | Replace `require` with `import` API for Nodejs builtins. Replace `type: () =\u003e require(smth)` statements with `import`. | `true`          |\n| `--require-main`          | Inject `main` field for `require` API polyfill.                                                                        | `true`          |\n| `--redoc-tpl`             | Inject `redoc.hbs` templates.                                                                                          | `true`          |\n\n### JS API\n```js\nimport { fix } from 'nestjs-esm-fix'\nawait fix({\n  cwd: '.',\n  target: 'target/**/*.js',\n  openapiComplexTypes: true,\n  openapiVar: true,\n  openapiMeta: true,\n  dirnameVar: true,\n  importify: true,\n  requireMain: true,\n  redocTpl: true\n})\n```\n\n## License\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantongolub%2Fnestjs-esm-fix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantongolub%2Fnestjs-esm-fix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantongolub%2Fnestjs-esm-fix/lists"}