├── .eslintrc.js ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── .yarn ├── releases │ └── yarn-4.6.0.cjs └── sdks │ ├── eslint │ ├── bin │ │ └── eslint.js │ ├── lib │ │ ├── api.js │ │ ├── types │ │ │ ├── index.d.ts │ │ │ ├── rules │ │ │ │ └── index.d.ts │ │ │ ├── universal.d.ts │ │ │ └── use-at-your-own-risk.d.ts │ │ ├── universal.js │ │ └── unsupported-api.js │ └── package.json │ ├── integrations.yml │ └── typescript │ ├── bin │ ├── tsc │ └── tsserver │ ├── lib │ ├── tsc.js │ ├── tsserver.js │ ├── tsserverlibrary.js │ └── typescript.js │ └── package.json ├── .yarnrc.yml ├── LICENSE ├── README.md ├── lib ├── decorators │ ├── InjectOpensearchClient.ts │ └── index.ts ├── helpers.ts ├── index.ts ├── interfaces │ ├── index.ts │ └── module-options.ts ├── opensearch-client.ts ├── opensearch.module.ts └── symbols.ts ├── package.json ├── scripts └── sync-tests.js ├── test ├── base │ ├── app.test.ts │ ├── package.json │ └── tsconfig.json ├── nestjs10-opensearch2 │ └── package.json ├── nestjs10-opensearch3 │ └── package.json ├── nestjs11-opensearch2 │ └── package.json ├── nestjs11-opensearch3 │ └── package.json ├── nestjs8-opensearch1 │ └── package.json ├── nestjs9-opensearch2-ts5 │ └── package.json └── nestjs9-opensearch2 │ └── package.json ├── tsconfig.json └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | sourceType: 'module', 5 | project: ['tsconfig.json', 'test/*/tsconfig.json'], 6 | }, 7 | plugins: ['@typescript-eslint'], 8 | extends: [ 9 | 'eslint:recommended', 10 | 'plugin:@typescript-eslint/recommended', 11 | ], 12 | env: { 13 | node: true 14 | }, 15 | ignorePatterns: [ 16 | '.eslintrc.js', 17 | 'dist' 18 | ], 19 | rules: { 20 | quotes: ['warn', 'single'], 21 | semi: ['warn', 'always'], 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.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 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /connect.lock 33 | /coverage 34 | /libpeerconnection.log 35 | testem.log 36 | /typings 37 | 38 | # System files 39 | ._* 40 | .DS_Store 41 | Thumbs.db 42 | 43 | # Yarn 44 | .pnp.* 45 | .yarn/* 46 | !.yarn/patches 47 | !.yarn/plugins 48 | !.yarn/releases 49 | !.yarn/sdks 50 | !.yarn/versions 51 | 52 | # Copying files 53 | test/**/* 54 | !test/base 55 | !test/**/package.json 56 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "arcanis.vscode-zipfs", 4 | "dbaeumer.vscode-eslint" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/.yarn": true, 4 | "**/.pnp.*": true 5 | }, 6 | "eslint.nodePath": ".yarn/sdks", 7 | "typescript.tsdk": ".yarn/sdks/typescript/lib", 8 | "typescript.enablePromptUseWorkspaceTsdk": true 9 | } 10 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/bin/eslint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/bin/eslint.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/bin/eslint.js your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/bin/eslint.js`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/api.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/types/index.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/types/rules/index.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/rules 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/rules your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/rules`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/types/universal.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/universal 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/universal your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/use-at-your-own-risk 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/use-at-your-own-risk your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/universal.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/universal 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/universal your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/lib/unsupported-api.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require eslint/use-at-your-own-risk 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real eslint/use-at-your-own-risk your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint", 3 | "version": "9.20.1-sdk", 4 | "main": "./lib/api.js", 5 | "type": "commonjs", 6 | "bin": { 7 | "eslint": "./bin/eslint.js" 8 | }, 9 | "exports": { 10 | ".": { 11 | "types": "./lib/types/index.d.ts", 12 | "default": "./lib/api.js" 13 | }, 14 | "./package.json": "./package.json", 15 | "./use-at-your-own-risk": { 16 | "types": "./lib/types/use-at-your-own-risk.d.ts", 17 | "default": "./lib/unsupported-api.js" 18 | }, 19 | "./rules": { 20 | "types": "./lib/types/rules/index.d.ts" 21 | }, 22 | "./universal": { 23 | "types": "./lib/types/universal.d.ts", 24 | "default": "./lib/universal.js" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.yarn/sdks/integrations.yml: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by @yarnpkg/sdks. 2 | # Manual changes might be lost! 3 | 4 | integrations: 5 | - vscode 6 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/bin/tsc 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/bin/tsc your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsserver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/bin/tsserver 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/bin/tsserver your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsc.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsc.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/lib/tsc.js your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsserver.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsserver.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | const moduleWrapper = exports => { 32 | return wrapWithUserWrapper(moduleWrapperFn(exports)); 33 | }; 34 | 35 | const moduleWrapperFn = tsserver => { 36 | if (!process.versions.pnp) { 37 | return tsserver; 38 | } 39 | 40 | const {isAbsolute} = require(`path`); 41 | const pnpApi = require(`pnpapi`); 42 | 43 | const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); 44 | const isPortal = str => str.startsWith("portal:/"); 45 | const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); 46 | 47 | const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { 48 | return `${locator.name}@${locator.reference}`; 49 | })); 50 | 51 | // VSCode sends the zip paths to TS using the "zip://" prefix, that TS 52 | // doesn't understand. This layer makes sure to remove the protocol 53 | // before forwarding it to TS, and to add it back on all returned paths. 54 | 55 | function toEditorPath(str) { 56 | // We add the `zip:` prefix to both `.zip/` paths and virtual paths 57 | if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { 58 | // We also take the opportunity to turn virtual paths into physical ones; 59 | // this makes it much easier to work with workspaces that list peer 60 | // dependencies, since otherwise Ctrl+Click would bring us to the virtual 61 | // file instances instead of the real ones. 62 | // 63 | // We only do this to modules owned by the the dependency tree roots. 64 | // This avoids breaking the resolution when jumping inside a vendor 65 | // with peer dep (otherwise jumping into react-dom would show resolution 66 | // errors on react). 67 | // 68 | const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; 69 | if (resolved) { 70 | const locator = pnpApi.findPackageLocator(resolved); 71 | if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { 72 | str = resolved; 73 | } 74 | } 75 | 76 | str = normalize(str); 77 | 78 | if (str.match(/\.zip\//)) { 79 | switch (hostInfo) { 80 | // Absolute VSCode `Uri.fsPath`s need to start with a slash. 81 | // VSCode only adds it automatically for supported schemes, 82 | // so we have to do it manually for the `zip` scheme. 83 | // The path needs to start with a caret otherwise VSCode doesn't handle the protocol 84 | // 85 | // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 86 | // 87 | // 2021-10-08: VSCode changed the format in 1.61. 88 | // Before | ^zip:/c:/foo/bar.zip/package.json 89 | // After | ^/zip//c:/foo/bar.zip/package.json 90 | // 91 | // 2022-04-06: VSCode changed the format in 1.66. 92 | // Before | ^/zip//c:/foo/bar.zip/package.json 93 | // After | ^/zip/c:/foo/bar.zip/package.json 94 | // 95 | // 2022-05-06: VSCode changed the format in 1.68 96 | // Before | ^/zip/c:/foo/bar.zip/package.json 97 | // After | ^/zip//c:/foo/bar.zip/package.json 98 | // 99 | case `vscode <1.61`: { 100 | str = `^zip:${str}`; 101 | } break; 102 | 103 | case `vscode <1.66`: { 104 | str = `^/zip/${str}`; 105 | } break; 106 | 107 | case `vscode <1.68`: { 108 | str = `^/zip${str}`; 109 | } break; 110 | 111 | case `vscode`: { 112 | str = `^/zip/${str}`; 113 | } break; 114 | 115 | // To make "go to definition" work, 116 | // We have to resolve the actual file system path from virtual path 117 | // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) 118 | case `coc-nvim`: { 119 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 120 | str = resolve(`zipfile:${str}`); 121 | } break; 122 | 123 | // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) 124 | // We have to resolve the actual file system path from virtual path, 125 | // everything else is up to neovim 126 | case `neovim`: { 127 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 128 | str = `zipfile://${str}`; 129 | } break; 130 | 131 | default: { 132 | str = `zip:${str}`; 133 | } break; 134 | } 135 | } else { 136 | str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); 137 | } 138 | } 139 | 140 | return str; 141 | } 142 | 143 | function fromEditorPath(str) { 144 | switch (hostInfo) { 145 | case `coc-nvim`: { 146 | str = str.replace(/\.zip::/, `.zip/`); 147 | // The path for coc-nvim is in format of //zipfile://.yarn/... 148 | // So in order to convert it back, we use .* to match all the thing 149 | // before `zipfile:` 150 | return process.platform === `win32` 151 | ? str.replace(/^.*zipfile:\//, ``) 152 | : str.replace(/^.*zipfile:/, ``); 153 | } break; 154 | 155 | case `neovim`: { 156 | str = str.replace(/\.zip::/, `.zip/`); 157 | // The path for neovim is in format of zipfile:////.yarn/... 158 | return str.replace(/^zipfile:\/\//, ``); 159 | } break; 160 | 161 | case `vscode`: 162 | default: { 163 | return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) 164 | } break; 165 | } 166 | } 167 | 168 | // Force enable 'allowLocalPluginLoads' 169 | // TypeScript tries to resolve plugins using a path relative to itself 170 | // which doesn't work when using the global cache 171 | // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 172 | // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but 173 | // TypeScript already does local loads and if this code is running the user trusts the workspace 174 | // https://github.com/microsoft/vscode/issues/45856 175 | const ConfiguredProject = tsserver.server.ConfiguredProject; 176 | const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; 177 | ConfiguredProject.prototype.enablePluginsWithOptions = function() { 178 | this.projectService.allowLocalPluginLoads = true; 179 | return originalEnablePluginsWithOptions.apply(this, arguments); 180 | }; 181 | 182 | // And here is the point where we hijack the VSCode <-> TS communications 183 | // by adding ourselves in the middle. We locate everything that looks 184 | // like an absolute path of ours and normalize it. 185 | 186 | const Session = tsserver.server.Session; 187 | const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; 188 | let hostInfo = `unknown`; 189 | 190 | Object.assign(Session.prototype, { 191 | onMessage(/** @type {string | object} */ message) { 192 | const isStringMessage = typeof message === 'string'; 193 | const parsedMessage = isStringMessage ? JSON.parse(message) : message; 194 | 195 | if ( 196 | parsedMessage != null && 197 | typeof parsedMessage === `object` && 198 | parsedMessage.arguments && 199 | typeof parsedMessage.arguments.hostInfo === `string` 200 | ) { 201 | hostInfo = parsedMessage.arguments.hostInfo; 202 | if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { 203 | const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( 204 | // The RegExp from https://semver.org/ but without the caret at the start 205 | /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ 206 | ) ?? []).map(Number) 207 | 208 | if (major === 1) { 209 | if (minor < 61) { 210 | hostInfo += ` <1.61`; 211 | } else if (minor < 66) { 212 | hostInfo += ` <1.66`; 213 | } else if (minor < 68) { 214 | hostInfo += ` <1.68`; 215 | } 216 | } 217 | } 218 | } 219 | 220 | const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { 221 | return typeof value === 'string' ? fromEditorPath(value) : value; 222 | }); 223 | 224 | return originalOnMessage.call( 225 | this, 226 | isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) 227 | ); 228 | }, 229 | 230 | send(/** @type {any} */ msg) { 231 | return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { 232 | return typeof value === `string` ? toEditorPath(value) : value; 233 | }))); 234 | } 235 | }); 236 | 237 | return tsserver; 238 | }; 239 | 240 | const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); 241 | // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. 242 | // Ref https://github.com/microsoft/TypeScript/pull/55326 243 | if (major > 5 || (major === 5 && minor >= 5)) { 244 | moduleWrapper(absRequire(`typescript`)); 245 | } 246 | 247 | // Defer to the real typescript/lib/tsserver.js your application uses 248 | module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); 249 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsserverlibrary.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsserverlibrary.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | const moduleWrapper = exports => { 32 | return wrapWithUserWrapper(moduleWrapperFn(exports)); 33 | }; 34 | 35 | const moduleWrapperFn = tsserver => { 36 | if (!process.versions.pnp) { 37 | return tsserver; 38 | } 39 | 40 | const {isAbsolute} = require(`path`); 41 | const pnpApi = require(`pnpapi`); 42 | 43 | const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); 44 | const isPortal = str => str.startsWith("portal:/"); 45 | const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); 46 | 47 | const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { 48 | return `${locator.name}@${locator.reference}`; 49 | })); 50 | 51 | // VSCode sends the zip paths to TS using the "zip://" prefix, that TS 52 | // doesn't understand. This layer makes sure to remove the protocol 53 | // before forwarding it to TS, and to add it back on all returned paths. 54 | 55 | function toEditorPath(str) { 56 | // We add the `zip:` prefix to both `.zip/` paths and virtual paths 57 | if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { 58 | // We also take the opportunity to turn virtual paths into physical ones; 59 | // this makes it much easier to work with workspaces that list peer 60 | // dependencies, since otherwise Ctrl+Click would bring us to the virtual 61 | // file instances instead of the real ones. 62 | // 63 | // We only do this to modules owned by the the dependency tree roots. 64 | // This avoids breaking the resolution when jumping inside a vendor 65 | // with peer dep (otherwise jumping into react-dom would show resolution 66 | // errors on react). 67 | // 68 | const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; 69 | if (resolved) { 70 | const locator = pnpApi.findPackageLocator(resolved); 71 | if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { 72 | str = resolved; 73 | } 74 | } 75 | 76 | str = normalize(str); 77 | 78 | if (str.match(/\.zip\//)) { 79 | switch (hostInfo) { 80 | // Absolute VSCode `Uri.fsPath`s need to start with a slash. 81 | // VSCode only adds it automatically for supported schemes, 82 | // so we have to do it manually for the `zip` scheme. 83 | // The path needs to start with a caret otherwise VSCode doesn't handle the protocol 84 | // 85 | // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 86 | // 87 | // 2021-10-08: VSCode changed the format in 1.61. 88 | // Before | ^zip:/c:/foo/bar.zip/package.json 89 | // After | ^/zip//c:/foo/bar.zip/package.json 90 | // 91 | // 2022-04-06: VSCode changed the format in 1.66. 92 | // Before | ^/zip//c:/foo/bar.zip/package.json 93 | // After | ^/zip/c:/foo/bar.zip/package.json 94 | // 95 | // 2022-05-06: VSCode changed the format in 1.68 96 | // Before | ^/zip/c:/foo/bar.zip/package.json 97 | // After | ^/zip//c:/foo/bar.zip/package.json 98 | // 99 | case `vscode <1.61`: { 100 | str = `^zip:${str}`; 101 | } break; 102 | 103 | case `vscode <1.66`: { 104 | str = `^/zip/${str}`; 105 | } break; 106 | 107 | case `vscode <1.68`: { 108 | str = `^/zip${str}`; 109 | } break; 110 | 111 | case `vscode`: { 112 | str = `^/zip/${str}`; 113 | } break; 114 | 115 | // To make "go to definition" work, 116 | // We have to resolve the actual file system path from virtual path 117 | // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) 118 | case `coc-nvim`: { 119 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 120 | str = resolve(`zipfile:${str}`); 121 | } break; 122 | 123 | // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) 124 | // We have to resolve the actual file system path from virtual path, 125 | // everything else is up to neovim 126 | case `neovim`: { 127 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 128 | str = `zipfile://${str}`; 129 | } break; 130 | 131 | default: { 132 | str = `zip:${str}`; 133 | } break; 134 | } 135 | } else { 136 | str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); 137 | } 138 | } 139 | 140 | return str; 141 | } 142 | 143 | function fromEditorPath(str) { 144 | switch (hostInfo) { 145 | case `coc-nvim`: { 146 | str = str.replace(/\.zip::/, `.zip/`); 147 | // The path for coc-nvim is in format of //zipfile://.yarn/... 148 | // So in order to convert it back, we use .* to match all the thing 149 | // before `zipfile:` 150 | return process.platform === `win32` 151 | ? str.replace(/^.*zipfile:\//, ``) 152 | : str.replace(/^.*zipfile:/, ``); 153 | } break; 154 | 155 | case `neovim`: { 156 | str = str.replace(/\.zip::/, `.zip/`); 157 | // The path for neovim is in format of zipfile:////.yarn/... 158 | return str.replace(/^zipfile:\/\//, ``); 159 | } break; 160 | 161 | case `vscode`: 162 | default: { 163 | return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) 164 | } break; 165 | } 166 | } 167 | 168 | // Force enable 'allowLocalPluginLoads' 169 | // TypeScript tries to resolve plugins using a path relative to itself 170 | // which doesn't work when using the global cache 171 | // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 172 | // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but 173 | // TypeScript already does local loads and if this code is running the user trusts the workspace 174 | // https://github.com/microsoft/vscode/issues/45856 175 | const ConfiguredProject = tsserver.server.ConfiguredProject; 176 | const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; 177 | ConfiguredProject.prototype.enablePluginsWithOptions = function() { 178 | this.projectService.allowLocalPluginLoads = true; 179 | return originalEnablePluginsWithOptions.apply(this, arguments); 180 | }; 181 | 182 | // And here is the point where we hijack the VSCode <-> TS communications 183 | // by adding ourselves in the middle. We locate everything that looks 184 | // like an absolute path of ours and normalize it. 185 | 186 | const Session = tsserver.server.Session; 187 | const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; 188 | let hostInfo = `unknown`; 189 | 190 | Object.assign(Session.prototype, { 191 | onMessage(/** @type {string | object} */ message) { 192 | const isStringMessage = typeof message === 'string'; 193 | const parsedMessage = isStringMessage ? JSON.parse(message) : message; 194 | 195 | if ( 196 | parsedMessage != null && 197 | typeof parsedMessage === `object` && 198 | parsedMessage.arguments && 199 | typeof parsedMessage.arguments.hostInfo === `string` 200 | ) { 201 | hostInfo = parsedMessage.arguments.hostInfo; 202 | if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { 203 | const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( 204 | // The RegExp from https://semver.org/ but without the caret at the start 205 | /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ 206 | ) ?? []).map(Number) 207 | 208 | if (major === 1) { 209 | if (minor < 61) { 210 | hostInfo += ` <1.61`; 211 | } else if (minor < 66) { 212 | hostInfo += ` <1.66`; 213 | } else if (minor < 68) { 214 | hostInfo += ` <1.68`; 215 | } 216 | } 217 | } 218 | } 219 | 220 | const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { 221 | return typeof value === 'string' ? fromEditorPath(value) : value; 222 | }); 223 | 224 | return originalOnMessage.call( 225 | this, 226 | isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) 227 | ); 228 | }, 229 | 230 | send(/** @type {any} */ msg) { 231 | return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { 232 | return typeof value === `string` ? toEditorPath(value) : value; 233 | }))); 234 | } 235 | }); 236 | 237 | return tsserver; 238 | }; 239 | 240 | const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); 241 | // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. 242 | // Ref https://github.com/microsoft/TypeScript/pull/55326 243 | if (major > 5 || (major === 5 && minor >= 5)) { 244 | moduleWrapper(absRequire(`typescript`)); 245 | } 246 | 247 | // Defer to the real typescript/lib/tsserverlibrary.js your application uses 248 | module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); 249 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/typescript.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "5.7.3-sdk", 4 | "main": "./lib/typescript.js", 5 | "type": "commonjs", 6 | "bin": { 7 | "tsc": "./bin/tsc", 8 | "tsserver": "./bin/tsserver" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | yarnPath: .yarn/releases/yarn-4.6.0.cjs 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 NeoAtlan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

nestjs-opensearch

4 |

5 | OpenSearch module for NestJS framework 6 |
7 | Installation 8 | · 9 | Usage 10 | · 11 | Issues 12 |
13 | NPM Version 14 | Package License 15 | NPM Downloads 16 |

17 |
18 |

19 | 20 | ## Installation 21 | For NPM: 22 | ```bash 23 | $ npm i --save nestjs-opensearch @opensearch-project/opensearch 24 | ``` 25 | For Yarn: 26 | ```bash 27 | $ yarn add nestjs-opensearch @opensearch-project/opensearch 28 | ``` 29 | 30 | ## Module configuration 31 | Module for single connection: 32 | ```typescript 33 | import { OpensearchModule } from 'nestjs-opensearch'; 34 | 35 | @Module({ 36 | imports: [ 37 | OpensearchModule.forRoot({ 38 | node: 'https://*****.es.amazonaws.com', 39 | }), 40 | ], 41 | providers: (...), 42 | }) 43 | export class SearchModule { } 44 | ``` 45 | 46 | Module for multiple connections: 47 | ```typescript 48 | import { OpensearchModule } from 'nestjs-opensearch'; 49 | 50 | @Module({ 51 | imports: [ 52 | OpensearchModule.forRoot({ 53 | clientName: 'foo', 54 | node: 'https://*****.es.amazonaws.com', 55 | }), 56 | OpensearchModule.forRoot({ 57 | clientName: 'bar', 58 | node: 'https://*****.es.amazonaws.com', 59 | }), 60 | ], 61 | providers: (...), 62 | }) 63 | export class SearchModule { } 64 | ``` 65 | 66 | Module for async configuration using useFactory: 67 | ```typescript 68 | import { OpensearchModule } from 'nestjs-opensearch'; 69 | 70 | @Module({ 71 | imports: [ 72 | OpensearchModule.forRootAsync({ 73 | clientName: 'baz', 74 | // See also: https://docs.nestjs.com/techniques/configuration 75 | imports: [ ConfigModule ], 76 | inject: [ ConfigService ], 77 | useFactory: (configService) => ({ 78 | node: configService.get('opensearch.node'), 79 | }), 80 | }), 81 | ], 82 | providers: (...), 83 | }) 84 | export class SearchModule { } 85 | ``` 86 | 87 | Module for async configuration using useClass: 88 | ```typescript 89 | import type { ClientOptions } from '@opensearch-project/opensearch'; 90 | import { OpensearchModule, OpensearchClientOptionsFactory } from 'nestjs-opensearch'; 91 | 92 | @Injectable() 93 | export class OpensearchConfigService implements OpensearchClientOptionsFactory { 94 | public async createOpensearchClientOptions(): Promise { 95 | const configs = await fetch(...); 96 | return { 97 | node: configs.node, 98 | }; 99 | } 100 | } 101 | 102 | @Module({ 103 | imports: [ 104 | OpensearchModule.forRootAsync({ 105 | clientName: 'qux', 106 | useClass: OpensearchConfigService, 107 | }), 108 | ], 109 | providers: (...), 110 | }) 111 | export class SearchModule { } 112 | ``` 113 | 114 | ## Client usage 115 | ```typescript 116 | import { InjectOpensearchClient, OpensearchClient } from 'nestjs-opensearch'; 117 | 118 | @Injectable() 119 | export class SearchService { 120 | public constructor( 121 | // Inject the default client 122 | private readonly searchClient: OpensearchClient, 123 | 124 | // Also inject the default client 125 | @InjectOpensearchClient() 126 | private readonly alsoSearchClient: OpensearchClient, 127 | 128 | // Inject the 'foo' named client 129 | @InjectOpensearchClient('foo') 130 | private readonly fooSearchClient: OpensearchClient, 131 | ) { } 132 | } 133 | ``` 134 | -------------------------------------------------------------------------------- /lib/decorators/InjectOpensearchClient.ts: -------------------------------------------------------------------------------- 1 | import { Inject } from '@nestjs/common'; 2 | import { buildInjectionToken } from '../helpers'; 3 | import { OpensearchClient } from '../opensearch-client'; 4 | 5 | export const InjectOpensearchClient = (clientName?: string | symbol) => 6 | Inject(clientName ? buildInjectionToken(clientName) : OpensearchClient); 7 | -------------------------------------------------------------------------------- /lib/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './InjectOpensearchClient'; 2 | -------------------------------------------------------------------------------- /lib/helpers.ts: -------------------------------------------------------------------------------- 1 | import type { OpensearchClient } from './opensearch-client'; 2 | import { clientNameSym } from './symbols'; 3 | 4 | export function buildInjectionToken(clientName: string | symbol) { 5 | return `OPENSEARCH_CLIENT_${String(clientName)}`; 6 | } 7 | 8 | export function getClientName(client: OpensearchClient) { 9 | return client[clientNameSym]; 10 | } 11 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from './decorators'; 2 | export * from './interfaces'; 3 | export * from './opensearch-client'; 4 | export * from './opensearch.module'; 5 | -------------------------------------------------------------------------------- /lib/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module-options'; 2 | -------------------------------------------------------------------------------- /lib/interfaces/module-options.ts: -------------------------------------------------------------------------------- 1 | import type { ModuleMetadata, Type } from '@nestjs/common'; 2 | import type { ClientOptions } from '@opensearch-project/opensearch'; 3 | /* eslint-disable @typescript-eslint/no-explicit-any */ 4 | 5 | export interface OpensearchClientOptions extends ClientOptions { 6 | clientName?: string | symbol; 7 | } 8 | 9 | type OpensearchAsyncClientOptionsBase = OpensearchClientOptions & Pick; 10 | 11 | interface OpensearchAsyncClientOptionsUseFactory extends OpensearchAsyncClientOptionsBase { 12 | inject?: any[]; 13 | useFactory: (...args: any[]) => ClientOptions | Promise; 14 | } 15 | 16 | export interface OpensearchClientOptionsFactory { 17 | createOpensearchClientOptions: () => ClientOptions | Promise; 18 | } 19 | 20 | interface OpensearchAsyncClientOptionsUseClass extends OpensearchAsyncClientOptionsBase { 21 | useClass: Type; 22 | } 23 | 24 | export type OpensearchAsyncClientOptions = OpensearchAsyncClientOptionsUseFactory | OpensearchAsyncClientOptionsUseClass; 25 | -------------------------------------------------------------------------------- /lib/opensearch-client.ts: -------------------------------------------------------------------------------- 1 | import { Client } from '@opensearch-project/opensearch'; 2 | import type { OpensearchClientOptions } from './interfaces'; 3 | import { clientNameSym } from './symbols'; 4 | 5 | export class OpensearchClient extends Client { 6 | public readonly [clientNameSym]?: string | symbol; 7 | 8 | public constructor({ clientName, ...clientOptions }: OpensearchClientOptions) { 9 | super(clientOptions); 10 | this[clientNameSym] = clientName; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/opensearch.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Inject, Module, OnApplicationShutdown, Provider } from '@nestjs/common'; 2 | import { buildInjectionToken } from './helpers'; 3 | import type { 4 | OpensearchClientOptions, 5 | OpensearchClientOptionsFactory, 6 | OpensearchAsyncClientOptions, 7 | } from './interfaces'; 8 | import { OpensearchClient } from './opensearch-client'; 9 | import { clientMapSym } from './symbols'; 10 | /* eslint-disable @typescript-eslint/no-explicit-any */ 11 | 12 | type ClientMap = Map; 13 | interface BuildAsyncProviderResult { 14 | internalProviders: Provider[]; 15 | externalProviders: Provider[]; 16 | } 17 | 18 | @Module({ 19 | providers: [ 20 | { 21 | provide: clientMapSym, 22 | useValue: new Map(), 23 | }, 24 | ], 25 | }) 26 | export class OpensearchModule implements OnApplicationShutdown { 27 | public static forRoot(options: OpensearchClientOptions): DynamicModule; 28 | /** @deprecated Please call forRoot() multiple times instead of using an array */ 29 | public static forRoot(options: OpensearchClientOptions[]): DynamicModule; 30 | public static forRoot(options: OpensearchClientOptions | OpensearchClientOptions[]): DynamicModule { 31 | const providers = OpensearchModule.buildProviders(options); 32 | return { 33 | module: OpensearchModule, 34 | exports: providers, 35 | providers, 36 | }; 37 | } 38 | 39 | public static forRootAsync(options: OpensearchAsyncClientOptions): DynamicModule; 40 | /** @deprecated Please call forRootAsync() multiple times instead of using an array */ 41 | public static forRootAsync(options: OpensearchAsyncClientOptions[]): DynamicModule; 42 | public static forRootAsync(options: OpensearchAsyncClientOptions | OpensearchAsyncClientOptions[]): DynamicModule { 43 | const { internalProviders, externalProviders } = OpensearchModule.buildAsyncProviders(options); 44 | return { 45 | module: OpensearchModule, 46 | imports: Array.isArray(options) ? undefined : options.imports, 47 | exports: externalProviders, 48 | providers: internalProviders.concat(externalProviders), 49 | }; 50 | } 51 | 52 | private static buildProviders(options: OpensearchClientOptions | OpensearchClientOptions[]): Provider[] { 53 | if (!Array.isArray(options)) { 54 | return OpensearchModule.buildProviders([ options ]); 55 | } 56 | 57 | return options.map((option) => ({ 58 | provide: option.clientName ? buildInjectionToken(option.clientName) : OpensearchClient, 59 | inject: [ clientMapSym ], 60 | useFactory: (clientMap: ClientMap) => { 61 | const client = new OpensearchClient(option); 62 | clientMap.set(option.clientName, client); 63 | return client; 64 | }, 65 | })); 66 | } 67 | 68 | private static buildAsyncProviders(options: OpensearchAsyncClientOptions | OpensearchAsyncClientOptions[]): BuildAsyncProviderResult { 69 | if (!Array.isArray(options)) { 70 | return OpensearchModule.buildAsyncProviders([ options ]); 71 | } 72 | 73 | const internalProviders: Provider[] = []; 74 | const externalProviders: Provider[] = []; 75 | 76 | options.forEach((option) => { 77 | const inject: any[] = [ clientMapSym ]; 78 | const isUseClass = 'useClass' in option; 79 | 80 | if (isUseClass) { 81 | internalProviders.push({ 82 | provide: option.useClass, 83 | useClass: option.useClass, 84 | }); 85 | inject.push(option.useClass); 86 | } else if (Array.isArray(option.inject)) { 87 | inject.push(...option.inject); 88 | } 89 | 90 | externalProviders.push({ 91 | provide: option.clientName ? buildInjectionToken(option.clientName) : OpensearchClient, 92 | inject, 93 | useFactory: async (clientMap: ClientMap, ...args: any[]) => { 94 | const clientOptions = await ( 95 | isUseClass 96 | ? (args[0] as OpensearchClientOptionsFactory).createOpensearchClientOptions() 97 | : option.useFactory(...args) 98 | ); 99 | const client = new OpensearchClient({ 100 | ...clientOptions, 101 | clientName: option.clientName, 102 | }); 103 | clientMap.set(option.clientName, client); 104 | return client; 105 | }, 106 | }); 107 | }); 108 | 109 | return { 110 | internalProviders, 111 | externalProviders, 112 | }; 113 | } 114 | 115 | public constructor( 116 | @Inject(clientMapSym) 117 | private readonly clientMap: ClientMap, 118 | ) { } 119 | 120 | public async onApplicationShutdown() { 121 | const promises: Promise[] = []; 122 | 123 | this.clientMap.forEach((client, clientName) => { 124 | promises.push((async () => { 125 | try { 126 | await client.close(); 127 | } catch { 128 | /* Ignore */ 129 | } 130 | this.clientMap.delete(clientName); 131 | })()); 132 | }); 133 | 134 | await Promise.all(promises); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /lib/symbols.ts: -------------------------------------------------------------------------------- 1 | export const clientMapSym = Symbol('clientMap'); 2 | export const clientNameSym = Symbol('clientName'); 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-opensearch", 3 | "version": "1.4.1", 4 | "author": "neoatlan", 5 | "license": "MIT", 6 | "description": "OpenSearch module for NestJS framework", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/neoatlan/nestjs-opensearch.git" 10 | }, 11 | "packageManager": "yarn@4.6.0", 12 | "scripts": { 13 | "build": "yarn clean && tsc", 14 | "clean": "rimraf dist", 15 | "test": "yarn build && node scripts/sync-tests && yarn workspaces foreach --all -v --include 'test-*' run test" 16 | }, 17 | "keywords": [ 18 | "opensearch", 19 | "elasticsearch", 20 | "nestjs", 21 | "nest", 22 | "typescript", 23 | "nodejs", 24 | "node" 25 | ], 26 | "workspaces": [ 27 | "test/*" 28 | ], 29 | "peerDependencies": { 30 | "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", 31 | "@opensearch-project/opensearch": "^1.0.0 || ^2.0.0 || ^3.0.0" 32 | }, 33 | "devDependencies": { 34 | "@nestjs/common": "^11.0.9", 35 | "@opensearch-project/opensearch": "^3.3.0", 36 | "@typescript-eslint/eslint-plugin": "^8.24.0", 37 | "@typescript-eslint/parser": "^8.24.0", 38 | "eslint": "^9.20.1", 39 | "reflect-metadata": "^0.2.2", 40 | "rimraf": "^6.0.1", 41 | "rxjs": "^7.8.1", 42 | "typescript": "^5.7.3" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /scripts/sync-tests.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const { copyFile, cp, readdir } = require('fs/promises'); 3 | const { join } = require('path'); 4 | const { rimraf } = require('rimraf'); 5 | 6 | const NON_COPYING_BASE_FILES = [ 'package.json' ]; 7 | 8 | async function main() { 9 | const distDir = join(__dirname, '..', 'dist'); 10 | const testRoot = join(__dirname, '..', 'test'); 11 | const testDirs = (await readdir(testRoot, { withFileTypes: true })) 12 | .filter((dir) => dir.isDirectory() && dir.name !== 'base') 13 | .map((dir) => dir.name); 14 | 15 | const testBaseDir = join(testRoot, 'base'); 16 | const baseFiles = (await readdir(testBaseDir, { withFileTypes: true })) 17 | .filter((file) => file.isFile()) 18 | .filter((file) => !NON_COPYING_BASE_FILES.includes(file.name)) 19 | .map((file) => file.name); 20 | 21 | const promises = []; 22 | for (const testDir of testDirs) { 23 | for (const baseFile of baseFiles) { 24 | promises.push( 25 | copyFile( 26 | join(testBaseDir, baseFile), 27 | join(testRoot, testDir, baseFile), 28 | ), 29 | ); 30 | } 31 | promises.push((async () => { 32 | const testDistDir = join(testRoot, testDir, 'dist'); 33 | await rimraf(testDistDir); 34 | await cp(distDir, testDistDir, { recursive: true }); 35 | })()); 36 | } 37 | 38 | await Promise.all(promises); 39 | } 40 | 41 | main() 42 | .then(() => process.exit(0)) 43 | .catch((e) => { 44 | console.error(e); 45 | process.exit(-1); 46 | }); 47 | -------------------------------------------------------------------------------- /test/base/app.test.ts: -------------------------------------------------------------------------------- 1 | // Disable for tests 2 | /* eslint-disable @typescript-eslint/no-non-null-assertion */ 3 | 4 | import { Injectable, Module, Optional } from '@nestjs/common'; 5 | import { Test, TestingModule } from '@nestjs/testing'; 6 | import type { ClientOptions } from '@opensearch-project/opensearch'; 7 | import { 8 | InjectOpensearchClient, 9 | OpensearchClient, 10 | OpensearchModule, 11 | OpensearchClientOptionsFactory, 12 | } from 'nestjs-opensearch'; 13 | import { getClientName } from 'nestjs-opensearch/helpers'; 14 | 15 | @Injectable() 16 | class SearchService { 17 | public constructor( 18 | @Optional() 19 | public readonly defaultClient?: OpensearchClient, 20 | 21 | @Optional() 22 | @InjectOpensearchClient() 23 | public readonly defaultClient1?: OpensearchClient, 24 | 25 | @Optional() 26 | @InjectOpensearchClient('foo') 27 | public readonly fooClient?: OpensearchClient, 28 | 29 | @Optional() 30 | @InjectOpensearchClient('bar') 31 | public readonly barClient?: OpensearchClient, 32 | ) { } 33 | } 34 | 35 | @Module({ 36 | providers: [{ 37 | provide: 'node', 38 | useValue: 'http://localhost:9201', 39 | }], 40 | exports: [ 'node' ], 41 | }) 42 | class ConfigModuleA { } 43 | 44 | @Module({ 45 | providers: [{ 46 | provide: 'node', 47 | useValue: 'http://localhost:9202', 48 | }], 49 | exports: [ 'node' ], 50 | }) 51 | class ConfigModuleB { } 52 | 53 | @Injectable() 54 | class ConfigServiceA implements OpensearchClientOptionsFactory { 55 | public createOpensearchClientOptions(): ClientOptions { 56 | return { 57 | node: 'http://localhost:9201', 58 | }; 59 | } 60 | } 61 | 62 | @Injectable() 63 | class ConfigServiceB implements OpensearchClientOptionsFactory { 64 | public createOpensearchClientOptions(): ClientOptions { 65 | return { 66 | node: 'http://localhost:9202', 67 | }; 68 | } 69 | } 70 | 71 | describe('Client injections', () => { 72 | let _tm: TestingModule | null = null; 73 | 74 | afterEach(async () => { 75 | await _tm?.close(); 76 | }); 77 | 78 | test('Only default client with sync module', async () => { 79 | const testModule = _tm = await Test.createTestingModule({ 80 | imports: [ 81 | OpensearchModule.forRoot({ 82 | node: 'http://localhost:9200', 83 | }), 84 | ], 85 | providers: [ SearchService ], 86 | }).compile(); 87 | 88 | const ss = testModule.get(SearchService); 89 | expect(ss.defaultClient).not.toBeUndefined(); 90 | expect(ss.defaultClient1).not.toBeUndefined(); 91 | expect(ss.fooClient).toBeUndefined(); 92 | expect(ss.barClient).toBeUndefined(); 93 | expect(getClientName(ss.defaultClient!)).toBeUndefined(); 94 | expect(getClientName(ss.defaultClient1!)).toBeUndefined(); 95 | }); 96 | 97 | test('Only foo named client with sync module', async () => { 98 | const testModule = _tm = await Test.createTestingModule({ 99 | imports: [ 100 | OpensearchModule.forRoot({ 101 | clientName: 'foo', 102 | node: 'http://localhost:9200', 103 | }), 104 | ], 105 | providers: [ SearchService ], 106 | }).compile(); 107 | 108 | const ss = testModule.get(SearchService); 109 | expect(ss.defaultClient).toBeUndefined(); 110 | expect(ss.defaultClient1).toBeUndefined(); 111 | expect(ss.fooClient).not.toBeUndefined(); 112 | expect(ss.barClient).toBeUndefined(); 113 | expect(getClientName(ss.fooClient!)).toEqual('foo'); 114 | }); 115 | 116 | test('Only named clients with sync module', async () => { 117 | const testModule = _tm = await Test.createTestingModule({ 118 | imports: [ 119 | OpensearchModule.forRoot({ 120 | clientName: 'foo', 121 | node: 'http://localhost:9200', 122 | }), 123 | OpensearchModule.forRoot({ 124 | clientName: 'bar', 125 | node: 'http://localhost:9200', 126 | }), 127 | ], 128 | providers: [ SearchService ], 129 | }).compile(); 130 | 131 | const ss = testModule.get(SearchService); 132 | expect(ss.defaultClient).toBeUndefined(); 133 | expect(ss.defaultClient1).toBeUndefined(); 134 | expect(ss.fooClient).not.toBeUndefined(); 135 | expect(ss.barClient).not.toBeUndefined(); 136 | expect(getClientName(ss.fooClient!)).toEqual('foo'); 137 | expect(getClientName(ss.barClient!)).toEqual('bar'); 138 | }); 139 | 140 | test('Only named clients with legacy style sync module', async () => { 141 | const testModule = _tm = await Test.createTestingModule({ 142 | imports: [ 143 | OpensearchModule.forRoot([ 144 | { 145 | clientName: 'foo', 146 | node: 'http://localhost:9200', 147 | }, 148 | { 149 | clientName: 'bar', 150 | node: 'http://localhost:9200', 151 | }, 152 | ]), 153 | ], 154 | providers: [ SearchService ], 155 | }).compile(); 156 | 157 | const ss = testModule.get(SearchService); 158 | expect(ss.defaultClient).toBeUndefined(); 159 | expect(ss.defaultClient1).toBeUndefined(); 160 | expect(ss.fooClient).not.toBeUndefined(); 161 | expect(ss.barClient).not.toBeUndefined(); 162 | expect(getClientName(ss.fooClient!)).toEqual('foo'); 163 | expect(getClientName(ss.barClient!)).toEqual('bar'); 164 | }); 165 | 166 | test('Import config through async module imports', async () => { 167 | let nodeA, nodeB; 168 | 169 | const testModule = _tm = await Test.createTestingModule({ 170 | imports: [ 171 | OpensearchModule.forRootAsync({ 172 | imports: [ ConfigModuleA ], 173 | inject: [ 'node' ], 174 | useFactory: async (node: string) => { 175 | nodeA = node; 176 | return { node }; 177 | }, 178 | }), 179 | OpensearchModule.forRootAsync({ 180 | clientName: 'bar', 181 | imports: [ ConfigModuleB ], 182 | inject: [ 'node' ], 183 | useFactory: async (node: string) => { 184 | nodeB = node; 185 | return { node }; 186 | }, 187 | }), 188 | ], 189 | providers: [ SearchService ], 190 | }).compile(); 191 | 192 | expect(nodeA).toEqual('http://localhost:9201'); 193 | expect(nodeB).toEqual('http://localhost:9202'); 194 | 195 | const ss = testModule.get(SearchService); 196 | expect(ss.defaultClient).not.toBeUndefined(); 197 | expect(ss.defaultClient1).not.toBeUndefined(); 198 | expect(ss.fooClient).toBeUndefined(); 199 | expect(ss.barClient).not.toBeUndefined(); 200 | expect(getClientName(ss.defaultClient!)).toBeUndefined(); 201 | expect(getClientName(ss.defaultClient1!)).toBeUndefined(); 202 | expect(getClientName(ss.barClient!)).toEqual('bar'); 203 | }); 204 | 205 | test('Only default and bar named clients with async module', async () => { 206 | const testModule = _tm = await Test.createTestingModule({ 207 | imports: [ 208 | OpensearchModule.forRootAsync({ 209 | useFactory: async () => ({ 210 | node: 'http://localhost:9200', 211 | }), 212 | }), 213 | OpensearchModule.forRootAsync({ 214 | clientName: 'bar', 215 | useFactory: async () => ({ 216 | node: 'http://localhost:9200', 217 | }), 218 | }), 219 | ], 220 | providers: [ SearchService ], 221 | }).compile(); 222 | 223 | const ss = testModule.get(SearchService); 224 | expect(ss.defaultClient).not.toBeUndefined(); 225 | expect(ss.defaultClient1).not.toBeUndefined(); 226 | expect(ss.fooClient).toBeUndefined(); 227 | expect(ss.barClient).not.toBeUndefined(); 228 | expect(getClientName(ss.defaultClient!)).toBeUndefined(); 229 | expect(getClientName(ss.defaultClient1!)).toBeUndefined(); 230 | expect(getClientName(ss.barClient!)).toEqual('bar'); 231 | }); 232 | 233 | test('Only default and bar named clients with legacy style async module', async () => { 234 | const testModule = _tm = await Test.createTestingModule({ 235 | imports: [ 236 | OpensearchModule.forRootAsync([ 237 | { 238 | useFactory: async () => ({ 239 | node: 'http://localhost:9200', 240 | }), 241 | }, 242 | { 243 | clientName: 'bar', 244 | useFactory: async () => ({ 245 | node: 'http://localhost:9200', 246 | }), 247 | }, 248 | ]), 249 | ], 250 | providers: [ SearchService ], 251 | }).compile(); 252 | 253 | const ss = testModule.get(SearchService); 254 | expect(ss.defaultClient).not.toBeUndefined(); 255 | expect(ss.defaultClient1).not.toBeUndefined(); 256 | expect(ss.fooClient).toBeUndefined(); 257 | expect(ss.barClient).not.toBeUndefined(); 258 | expect(getClientName(ss.defaultClient!)).toBeUndefined(); 259 | expect(getClientName(ss.defaultClient1!)).toBeUndefined(); 260 | expect(getClientName(ss.barClient!)).toEqual('bar'); 261 | }); 262 | 263 | test('default client and bar named client by async module with useClass', async () => { 264 | const testModule = _tm = await Test.createTestingModule({ 265 | imports: [ 266 | OpensearchModule.forRootAsync({ 267 | useClass: ConfigServiceA, 268 | }), 269 | OpensearchModule.forRootAsync({ 270 | clientName: 'foo', 271 | useClass: ConfigServiceB, 272 | }), 273 | ], 274 | providers: [ SearchService ], 275 | }).compile(); 276 | 277 | const ss = testModule.get(SearchService); 278 | expect(ss.defaultClient).not.toBeUndefined(); 279 | expect(ss.defaultClient1).not.toBeUndefined(); 280 | expect(ss.fooClient).not.toBeUndefined(); 281 | expect(ss.barClient).toBeUndefined(); 282 | expect(getClientName(ss.defaultClient!)).toBeUndefined(); 283 | expect(getClientName(ss.defaultClient1!)).toBeUndefined(); 284 | expect(getClientName(ss.fooClient!)).toEqual('foo'); 285 | }); 286 | }); 287 | -------------------------------------------------------------------------------- /test/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testbase", 3 | "private": true, 4 | "devDependencies": { 5 | "@nestjs/common": "^10.0.0", 6 | "@nestjs/core": "^10.0.0", 7 | "@nestjs/testing": "^10.0.0", 8 | "@opensearch-project/opensearch": "^2.0.0", 9 | "@types/jest": "^29.5.0", 10 | "jest": "^29.5.0", 11 | "nestjs-opensearch": "link:../../dist", 12 | "reflect-metadata": "^0.1.13", 13 | "rxjs": "^7.8.1", 14 | "ts-jest": "^29.1.0", 15 | "typescript": "^5.1.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | "outDir": "dist", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 68 | 69 | /* Interop Constraints */ 70 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 71 | "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 72 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 73 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 74 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 75 | 76 | /* Type Checking */ 77 | "strict": true, /* Enable all strict type-checking options. */ 78 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 79 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 80 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 81 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 82 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 83 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 84 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 85 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 86 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 87 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 88 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 89 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 90 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 91 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 92 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 93 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 94 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 95 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 96 | 97 | /* Completeness */ 98 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 99 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /test/nestjs10-opensearch2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs10-opensearch2", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^10.0.0", 14 | "@nestjs/core": "^10.0.0", 15 | "@nestjs/testing": "^10.0.0", 16 | "@opensearch-project/opensearch": "^2.0.0", 17 | "@types/jest": "^29.5.0", 18 | "jest": "^29.5.0", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.1.13", 21 | "rxjs": "^7.8.1", 22 | "ts-jest": "^29.1.0", 23 | "typescript": "^5.1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs10-opensearch3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs10-opensearch3", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^10.0.0", 14 | "@nestjs/core": "^10.0.0", 15 | "@nestjs/testing": "^10.0.0", 16 | "@opensearch-project/opensearch": "^3.0.0", 17 | "@types/jest": "^29.5.0", 18 | "jest": "^29.5.0", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.1.13", 21 | "rxjs": "^7.8.1", 22 | "ts-jest": "^29.1.0", 23 | "typescript": "^5.1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs11-opensearch2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs11-opensearch2", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^11.0.0", 14 | "@nestjs/core": "^11.0.0", 15 | "@nestjs/testing": "^11.0.0", 16 | "@opensearch-project/opensearch": "^2.0.0", 17 | "@types/jest": "^29.5.0", 18 | "jest": "^29.5.0", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.2.2", 21 | "rxjs": "^7.8.1", 22 | "ts-jest": "^29.1.0", 23 | "typescript": "^5.7.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs11-opensearch3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs11-opensearch3", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^11.0.0", 14 | "@nestjs/core": "^11.0.0", 15 | "@nestjs/testing": "^11.0.0", 16 | "@opensearch-project/opensearch": "^3.0.0", 17 | "@types/jest": "^29.5.0", 18 | "jest": "^29.5.0", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.2.2", 21 | "rxjs": "^7.8.1", 22 | "ts-jest": "^29.1.0", 23 | "typescript": "^5.7.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs8-opensearch1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs8-opensearch1", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^8.0.0", 14 | "@nestjs/core": "^8.0.0", 15 | "@nestjs/testing": "^8.0.0", 16 | "@opensearch-project/opensearch": "^1.0.0", 17 | "@types/jest": "^28.1.6", 18 | "jest": "^28.1.3", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.1.13", 21 | "rxjs": "^7.5.6", 22 | "ts-jest": "^28.0.8", 23 | "typescript": "^4.7.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs9-opensearch2-ts5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs9-opensearch2-ts5", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^9.3.12", 14 | "@nestjs/core": "^9.3.12", 15 | "@nestjs/testing": "^9.3.12", 16 | "@opensearch-project/opensearch": "^2.0.0", 17 | "@types/jest": "^29.5.0", 18 | "jest": "^29.5.0", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.1.13", 21 | "rxjs": "^7.5.6", 22 | "ts-jest": "^29.1.0", 23 | "typescript": "^5.0.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/nestjs9-opensearch2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-nestjs9-opensearch2", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "jest": { 8 | "preset": "ts-jest", 9 | "rootDir": ".", 10 | "testEnvironment": "node" 11 | }, 12 | "devDependencies": { 13 | "@nestjs/common": "^9.0.0", 14 | "@nestjs/core": "^9.0.0", 15 | "@nestjs/testing": "^9.0.0", 16 | "@opensearch-project/opensearch": "^2.0.0", 17 | "@types/jest": "^28.1.6", 18 | "jest": "^28.1.3", 19 | "nestjs-opensearch": "link:dist", 20 | "reflect-metadata": "^0.1.13", 21 | "rxjs": "^7.5.6", 22 | "ts-jest": "^28.0.8", 23 | "typescript": "^4.7.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["lib"], 3 | "compilerOptions": { 4 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 5 | 6 | /* Projects */ 7 | // "incremental": true, /* Enable incremental compilation */ 8 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 9 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 10 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 11 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 12 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 13 | 14 | /* Language and Environment */ 15 | "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 16 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 17 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 18 | "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 19 | "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 23 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "resolveJsonModule": true, /* Enable importing .json files */ 38 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 39 | 40 | /* JavaScript Support */ 41 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 42 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 43 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 44 | 45 | /* Emit */ 46 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 47 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 48 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 49 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 50 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 51 | "outDir": "dist", /* Specify an output folder for all emitted files. */ 52 | // "removeComments": true, /* Disable emitting comments. */ 53 | // "noEmit": true, /* Disable emitting files from a compilation. */ 54 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 55 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 56 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 57 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 60 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 61 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 62 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 63 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 64 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 65 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 66 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 67 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 68 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 69 | 70 | /* Interop Constraints */ 71 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 72 | "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 73 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 74 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 75 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 76 | 77 | /* Type Checking */ 78 | "strict": true, /* Enable all strict type-checking options. */ 79 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 80 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 81 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 82 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 83 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 84 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 85 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 86 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 87 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 88 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 89 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 90 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 91 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 92 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 93 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 94 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 95 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 96 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 97 | 98 | /* Completeness */ 99 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 100 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 101 | } 102 | } 103 | --------------------------------------------------------------------------------