├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── 10-feature.md │ ├── 20-bug.md │ ├── 30-docs.md │ ├── 99-something-else.md │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── actions │ └── setup │ │ └── action.yml ├── renovate.json └── workflows │ ├── pr.yml │ ├── release.yml │ ├── test.yml │ └── trunk.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.cjs ├── .vscode ├── extensions.json └── settings.json ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ ├── plugin-outdated.cjs │ │ └── plugin-typescript.cjs └── releases │ └── yarn-berry.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── SECURITY.md ├── jest.config.ts ├── package.json ├── src ├── Client │ ├── api.ts │ ├── controller.ts │ ├── helpers.ts │ ├── index.ts │ ├── model.ts │ └── run.ts ├── ConnectionString │ └── index.ts ├── Constants.ts ├── Engines.ts ├── Errors │ └── index.ts ├── Schema │ ├── create.ts │ ├── datasource.ts │ ├── helpers.ts │ ├── index.ts │ ├── previewFeatures.ts │ └── referentialIntegrity.ts ├── index.ts ├── index_.ts └── lib │ ├── base64 │ ├── Base64.ts │ └── index.ts │ └── helpers.ts ├── tests └── Schema │ ├── __snapshots__ │ └── schema.spec.ts.snap │ └── schema.spec.ts ├── tsconfig.cjs.json ├── tsconfig.esm.json ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | .yalc 2 | .vscode 3 | .github 4 | node_modules 5 | dist-cjs 6 | dist-esm 7 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "project": ["tsconfig.json"] 6 | }, 7 | "plugins": [ 8 | // This enables using new lint rules powered by the TypeScript compiler API. 9 | // https://github.com/typescript-eslint/typescript-eslint 10 | "@typescript-eslint", 11 | // This makes it so the IDE reports lint rejections as warnings only. This is 12 | // better than errors because most lint rejections are not runtime errors. This 13 | // allows IDE errors to be exclusive for e.g. static type errors which often are 14 | // reflective of real runtime errors. 15 | // https://github.com/bfanger/eslint-plugin-only-warn 16 | "only-warn", 17 | // This enables the use of a lint rule to reject function declarations. This is 18 | // preferable as a way to encourage higher order function usage. For example it is not 19 | // possible to wrap a function declaration with Open Telemetry instrumentation but it is 20 | // possible to wrap an arrow function since its an expression. 21 | // https://github.com/TristonJ/eslint-plugin-prefer-arrow 22 | "prefer-arrow", 23 | // This enables the use of a lint rule to reject use of @deprecated functions. 24 | // https://github.com/gund/eslint-plugin-deprecation 25 | "deprecation", 26 | // Import sorting integrated into ESLint. 27 | // https://github.com/lydell/eslint-plugin-simple-import-sort 28 | "simple-import-sort", 29 | // https://github.com/microsoft/tsdoc/tree/master/eslint-plugin 30 | "tsdoc" 31 | ], 32 | "extends": [ 33 | "eslint:recommended", 34 | "plugin:@typescript-eslint/eslint-recommended", 35 | "plugin:@typescript-eslint/recommended", 36 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 37 | "prettier" 38 | ], 39 | "overrides": [], 40 | "rules": { 41 | "tsdoc/syntax": "warn", 42 | "simple-import-sort/imports": [ 43 | "warn", 44 | { 45 | "groups": [] 46 | } 47 | ], 48 | "simple-import-sort/exports": "warn", 49 | "deprecation/deprecation": "warn", 50 | "prefer-arrow/prefer-arrow-functions": "warn", 51 | // TypeScript makes these safe & effective 52 | "no-case-declarations": "off", 53 | // Same approach used by TypeScript noUnusedLocals 54 | "@typescript-eslint/no-unused-vars": ["warn", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | For **questions**, please use the repo's [GitHub Discussions](https://github.com/graphql-nexus/nexus/discussions) 2 | 3 | --- 4 | 5 | For **feature requests**, please fill out the [feature request template](https://github.com/graphql-nexus/nexus/issues/new?template=1-feature.md) 6 | 7 | --- 8 | 9 | For **bug reports**, please fill out the [bug report issue template](https://github.com/graphql-nexus/nexus/issues/new?template=2-bug.md) 10 | 11 | --- 12 | 13 | For **documentation issues**, please fill out the [documentation issue template](https://github.com/graphql-nexus/nexus/issues/new?template=3-docs.md) 14 | 15 | --- 16 | 17 | For **something else**, please fill out the [something else template](https://github.com/graphql-nexus/nexus/issues/new?template=5-other.md) 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/10-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature 3 | about: You have an idea for a new capability or a refinement to an existing one 4 | title: '' 5 | labels: type/feat 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | #### Perceived Problem 15 | 16 | #### Ideas / Proposed Solution(s) 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/20-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug 3 | about: You encountered something that is not working the way it should 4 | title: '' 5 | labels: type/bug 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | #### Screenshot 15 | 16 | #### Description 17 | 18 | #### Repro Steps/Link 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/30-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 📗 Docs 3 | about: You have feedback or ideas about the documentation 4 | title: '' 5 | labels: type/docs 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | #### Perceived Problem 15 | 16 | #### Ideas / Proposed Solution(s) 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/99-something-else.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🤷‍♂️ Something Else 3 | about: You have something to say that doesn't obviously fit another category here 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | #### What 15 | 16 | #### Why 17 | 18 | #### How 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: ✋ Question 4 | about: You have a question about something you're not sure about 5 | url: https://github.com/prisma/utils-node/discussions/new 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | closes #... 2 | 3 | #### TASKS 4 | 5 | - [ ] docs external 6 | - [ ] docs jsdoc 7 | - [ ] tests 8 | -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | inputs: 3 | node-version: 4 | type: string 5 | require: false 6 | default: 16.x 7 | install-deps: 8 | type: boolean 9 | require: false 10 | default: true 11 | runs: 12 | using: composite 13 | steps: 14 | - name: Use Node.js ${{inputs.node-version}} 15 | uses: actions/setup-node@v3 16 | with: 17 | node-version: ${{inputs.node-version}} 18 | cache: 'yarn' 19 | - uses: prisma/action-node-cache-dependencies@main 20 | if: inputs.install-deps 21 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:js-lib"], 4 | "labels": ["type/deps"], 5 | "major": { 6 | "semanticCommitType": "deps", 7 | "semanticCommitScope": "" 8 | }, 9 | "semanticCommits": "enabled", 10 | "packageRules": [ 11 | { 12 | "groupName": "renovate-meta", 13 | "updateTypes": ["lockFileMaintenance", "pin"], 14 | "labels": ["type/chore"], 15 | "semanticCommitType": "chore", 16 | "semanticCommitScope": "deps" 17 | }, 18 | { 19 | "groupName": "dependencies (non-major)", 20 | "depTypeList": ["dependencies"], 21 | "updateTypes": ["patch", "minor"], 22 | "labels": ["type/deps"], 23 | "semanticCommitType": "deps" 24 | }, 25 | { 26 | "groupName": "devDependencies (major)", 27 | "depTypeList": ["devDependencies"], 28 | "updateTypes": ["major"], 29 | "labels": ["type/chore"], 30 | "semanticCommitType": "chore", 31 | "semanticCommitScope": "deps" 32 | }, 33 | { 34 | "groupName": "devDependencies (non-major)", 35 | "depTypeList": ["devDependencies"], 36 | "updateTypes": ["patch", "minor"], 37 | "labels": ["type/chore"], 38 | "semanticCommitType": "chore", 39 | "semanticCommitScope": "deps" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: pr 2 | on: 3 | - pull_request 4 | jobs: 5 | setup: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: ./.github/actions/setup 10 | prettier: 11 | needs: [setup] 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: ./.github/actions/setup 16 | - run: yarn format:check:prettier 17 | eslint: 18 | needs: [setup] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v2 22 | - uses: ./.github/actions/setup 23 | - run: yarn lint:check 24 | type-check: 25 | needs: [setup] 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v2 29 | - uses: ./.github/actions/setup 30 | - run: yarn type-check 31 | test: 32 | needs: [setup] 33 | uses: ./.github/workflows/test.yml 34 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: workflow_dispatch 3 | jobs: 4 | run: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: prisma-labs/dripip@master 8 | with: 9 | isStable: true 10 | npmToken: ${{secrets.NPM_TOKEN}} 11 | githubToken: ${{secrets.GITHUB_TOKEN}} 12 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | - workflow_call 4 | jobs: 5 | test: 6 | strategy: 7 | matrix: 8 | os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] 9 | node-version: [14.x, 16.x] 10 | runs-on: ${{ matrix.os }} 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: ./.github/actions/setup 14 | with: 15 | node-version: ${{matrix.node-version}} 16 | - run: yarn build 17 | - run: yarn test 18 | -------------------------------------------------------------------------------- /.github/workflows/trunk.yml: -------------------------------------------------------------------------------- 1 | name: trunk 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | setup: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: ./.github/actions/setup 13 | test: 14 | needs: [setup] 15 | uses: ./.github/workflows/test.yml 16 | release-canary: 17 | needs: [test] 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: prisma-labs/dripip@master 21 | with: 22 | npmToken: ${{secrets.NPM_TOKEN}} 23 | githubToken: ${{secrets.GITHUB_TOKEN}} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # macOS 107 | .DS_Store 108 | 109 | # This library 110 | dist-esm 111 | dist-cjs 112 | 113 | # Yarn 2 114 | .pnp.* 115 | .yarn/* 116 | !.yarn/patches 117 | !.yarn/plugins 118 | !.yarn/releases 119 | !.yarn/sdks 120 | !.yarn/versions 121 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist-cjs 2 | dist-esm 3 | .yarn 4 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://prettier.io/docs/en/configuration.html 3 | */ 4 | module.exports = { 5 | ...require('@prisma-labs/prettier-config'), 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/dist-cjs": true, 4 | "**/dist-esm": true, 5 | "**/__snapshots__": true, 6 | "**/.yarn": true, 7 | "yarn.lock": true 8 | }, 9 | "typescript.tsdk": "node_modules/typescript/lib", 10 | "typescript.enablePromptUseWorkspaceTsdk": true, 11 | "editor.codeActionsOnSave": { 12 | "source.addMissingImports": true, 13 | "source.fixAll.eslint": true, 14 | // Disable this because it will conflict with ESLint based import organizing. 15 | "source.organizeImports": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.yarn/plugins/@yarnpkg/plugin-outdated.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | //prettier-ignore 3 | module.exports = { 4 | name: "@yarnpkg/plugin-outdated", 5 | factory: function (require) { 6 | var plugin=(()=>{var Cr=Object.create,ge=Object.defineProperty,Er=Object.defineProperties,_r=Object.getOwnPropertyDescriptor,xr=Object.getOwnPropertyDescriptors,br=Object.getOwnPropertyNames,et=Object.getOwnPropertySymbols,Sr=Object.getPrototypeOf,tt=Object.prototype.hasOwnProperty,vr=Object.prototype.propertyIsEnumerable;var rt=(e,t,r)=>t in e?ge(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,k=(e,t)=>{for(var r in t||(t={}))tt.call(t,r)&&rt(e,r,t[r]);if(et)for(var r of et(t))vr.call(t,r)&&rt(e,r,t[r]);return e},q=(e,t)=>Er(e,xr(t)),Hr=e=>ge(e,"__esModule",{value:!0});var W=e=>{if(typeof require!="undefined")return require(e);throw new Error('Dynamic require of "'+e+'" is not supported')};var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),wr=(e,t)=>{for(var r in t)ge(e,r,{get:t[r],enumerable:!0})},Tr=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of br(t))!tt.call(e,n)&&n!=="default"&&ge(e,n,{get:()=>t[n],enumerable:!(r=_r(t,n))||r.enumerable});return e},re=e=>Tr(Hr(ge(e!=null?Cr(Sr(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var ve=U(V=>{"use strict";V.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;V.find=(e,t)=>e.nodes.find(r=>r.type===t);V.exceedsLimit=(e,t,r=1,n)=>n===!1||!V.isInteger(e)||!V.isInteger(t)?!1:(Number(t)-Number(e))/Number(r)>=n;V.escapeNode=(e,t=0,r)=>{let n=e.nodes[t];!n||(r&&n.type===r||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};V.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0==0?(e.invalid=!0,!0):!1;V.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0==0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;V.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;V.reduce=e=>e.reduce((t,r)=>(r.type==="text"&&t.push(r.value),r.type==="range"&&(r.type="text"),t),[]);V.flatten=(...e)=>{let t=[],r=n=>{for(let s=0;s{"use strict";var nt=ve();st.exports=(e,t={})=>{let r=(n,s={})=>{let a=t.escapeInvalid&&nt.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o="";if(n.value)return(a||i)&&nt.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let d of n.nodes)o+=r(d);return o};return r(e)}});var it=U((es,at)=>{"use strict";at.exports=function(e){return typeof e=="number"?e-e==0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var gt=U((ts,dt)=>{"use strict";var ot=it(),ce=(e,t,r)=>{if(ot(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(t===void 0||e===t)return String(e);if(ot(t)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n=k({relaxZeros:!0},r);typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),a=String(n.shorthand),i=String(n.capture),o=String(n.wrap),d=e+":"+t+"="+s+a+i+o;if(ce.cache.hasOwnProperty(d))return ce.cache[d].result;let y=Math.min(e,t),f=Math.max(e,t);if(Math.abs(y-f)===1){let A=e+"|"+t;return n.capture?`(${A})`:n.wrap===!1?A:`(?:${A})`}let R=ht(e)||ht(t),p={min:e,max:t,a:y,b:f},H=[],m=[];if(R&&(p.isPadded=R,p.maxLen=String(p.max).length),y<0){let A=f<0?Math.abs(f):1;m=ut(A,Math.abs(y),p,n),y=p.a=0}return f>=0&&(H=ut(y,f,p,n)),p.negatives=m,p.positives=H,p.result=$r(m,H,n),n.capture===!0?p.result=`(${p.result})`:n.wrap!==!1&&H.length+m.length>1&&(p.result=`(?:${p.result})`),ce.cache[d]=p,p.result};function $r(e,t,r){let n=Ne(e,t,"-",!1,r)||[],s=Ne(t,e,"",!1,r)||[],a=Ne(e,t,"-?",!0,r)||[];return n.concat(a).concat(s).join("|")}function Lr(e,t){let r=1,n=1,s=lt(e,r),a=new Set([t]);for(;e<=s&&s<=t;)a.add(s),r+=1,s=lt(e,r);for(s=pt(t+1,n)-1;e1&&o.count.pop(),o.count.push(f.count[0]),o.string=o.pattern+ft(o.count),i=y+1;continue}r.isPadded&&(R=Dr(y,r,n)),f.string=R+f.pattern+ft(f.count),a.push(f),i=y+1,o=f}return a}function Ne(e,t,r,n,s){let a=[];for(let i of e){let{string:o}=i;!n&&!ct(t,"string",o)&&a.push(r+o),n&&ct(t,"string",o)&&a.push(r+o)}return a}function kr(e,t){let r=[];for(let n=0;nt?1:t>e?-1:0}function ct(e,t,r){return e.some(n=>n[t]===r)}function lt(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function pt(e,t){return e-e%Math.pow(10,t)}function ft(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function Ir(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function ht(e){return/^-?(0+)\d/.test(e)}function Dr(e,t,r){if(!t.isPadded)return e;let n=Math.abs(t.maxLen-String(e).length),s=r.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}ce.cache={};ce.clearCache=()=>ce.cache={};dt.exports=ce});var Pe=U((rs,xt)=>{"use strict";var Pr=W("util"),yt=gt(),Rt=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Mr=e=>t=>e===!0?Number(t):String(t),Ie=e=>typeof e=="number"||typeof e=="string"&&e!=="",ye=e=>Number.isInteger(+e),De=e=>{let t=`${e}`,r=-1;if(t[0]==="-"&&(t=t.slice(1)),t==="0")return!1;for(;t[++r]==="0";);return r>0},Br=(e,t,r)=>typeof e=="string"||typeof t=="string"?!0:r.stringify===!0,Ur=(e,t,r)=>{if(t>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?t-1:t,"0")}return r===!1?String(e):e},At=(e,t)=>{let r=e[0]==="-"?"-":"";for(r&&(e=e.slice(1),t--);e.length{e.negatives.sort((i,o)=>io?1:0),e.positives.sort((i,o)=>io?1:0);let r=t.capture?"":"?:",n="",s="",a;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${r}${e.negatives.join("|")})`),n&&s?a=`${n}|${s}`:a=n||s,t.wrap?`(${r}${a})`:a},mt=(e,t,r,n)=>{if(r)return yt(e,t,k({wrap:!1},n));let s=String.fromCharCode(e);if(e===t)return s;let a=String.fromCharCode(t);return`[${s}-${a}]`},Ct=(e,t,r)=>{if(Array.isArray(e)){let n=r.wrap===!0,s=r.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return yt(e,t,r)},Et=(...e)=>new RangeError("Invalid range arguments: "+Pr.inspect(...e)),_t=(e,t,r)=>{if(r.strictRanges===!0)throw Et([e,t]);return[]},Fr=(e,t)=>{if(t.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},Kr=(e,t,r=1,n={})=>{let s=Number(e),a=Number(t);if(!Number.isInteger(s)||!Number.isInteger(a)){if(n.strictRanges===!0)throw Et([e,t]);return[]}s===0&&(s=0),a===0&&(a=0);let i=s>a,o=String(e),d=String(t),y=String(r);r=Math.max(Math.abs(r),1);let f=De(o)||De(d)||De(y),R=f?Math.max(o.length,d.length,y.length):0,p=f===!1&&Br(e,t,n)===!1,H=n.transform||Mr(p);if(n.toRegex&&r===1)return mt(At(e,R),At(t,R),!0,n);let m={negatives:[],positives:[]},A=O=>m[O<0?"negatives":"positives"].push(Math.abs(O)),E=[],b=0;for(;i?s>=a:s<=a;)n.toRegex===!0&&r>1?A(s):E.push(Ur(H(s,b),R,p)),s=i?s-r:s+r,b++;return n.toRegex===!0?r>1?Gr(m,n):Ct(E,null,k({wrap:!1},n)):E},jr=(e,t,r=1,n={})=>{if(!ye(e)&&e.length>1||!ye(t)&&t.length>1)return _t(e,t,n);let s=n.transform||(p=>String.fromCharCode(p)),a=`${e}`.charCodeAt(0),i=`${t}`.charCodeAt(0),o=a>i,d=Math.min(a,i),y=Math.max(a,i);if(n.toRegex&&r===1)return mt(d,y,!1,n);let f=[],R=0;for(;o?a>=i:a<=i;)f.push(s(a,R)),a=o?a-r:a+r,R++;return n.toRegex===!0?Ct(f,null,{wrap:!1,options:n}):f},we=(e,t,r,n={})=>{if(t==null&&Ie(e))return[e];if(!Ie(e)||!Ie(t))return _t(e,t,n);if(typeof r=="function")return we(e,t,1,{transform:r});if(Rt(r))return we(e,t,0,r);let s=k({},n);return s.capture===!0&&(s.wrap=!0),r=r||s.step||1,ye(r)?ye(e)&&ye(t)?Kr(e,t,r,s):jr(e,t,Math.max(Math.abs(r),1),s):r!=null&&!Rt(r)?Fr(r,s):we(e,t,1,r)};xt.exports=we});var vt=U((ns,St)=>{"use strict";var qr=Pe(),bt=ve(),Wr=(e,t={})=>{let r=(n,s={})=>{let a=bt.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o=a===!0||i===!0,d=t.escapeInvalid===!0?"\\":"",y="";if(n.isOpen===!0||n.isClose===!0)return d+n.value;if(n.type==="open")return o?d+n.value:"(";if(n.type==="close")return o?d+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":o?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let f=bt.reduce(n.nodes),R=qr(...f,q(k({},t),{wrap:!1,toRegex:!0}));if(R.length!==0)return f.length>1&&R.length>1?`(${R})`:R}if(n.nodes)for(let f of n.nodes)y+=r(f,n);return y};return r(e)};St.exports=Wr});var Tt=U((ss,wt)=>{"use strict";var Qr=Pe(),Ht=He(),pe=ve(),le=(e="",t="",r=!1)=>{let n=[];if(e=[].concat(e),t=[].concat(t),!t.length)return e;if(!e.length)return r?pe.flatten(t).map(s=>`{${s}}`):t;for(let s of e)if(Array.isArray(s))for(let a of s)n.push(le(a,t,r));else for(let a of t)r===!0&&typeof a=="string"&&(a=`{${a}}`),n.push(Array.isArray(a)?le(s,a,r):s+a);return pe.flatten(n)},Xr=(e,t={})=>{let r=t.rangeLimit===void 0?1e3:t.rangeLimit,n=(s,a={})=>{s.queue=[];let i=a,o=a.queue;for(;i.type!=="brace"&&i.type!=="root"&&i.parent;)i=i.parent,o=i.queue;if(s.invalid||s.dollar){o.push(le(o.pop(),Ht(s,t)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){o.push(le(o.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let R=pe.reduce(s.nodes);if(pe.exceedsLimit(...R,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let p=Qr(...R,t);p.length===0&&(p=Ht(s,t)),o.push(le(o.pop(),p)),s.nodes=[];return}let d=pe.encloseBrace(s),y=s.queue,f=s;for(;f.type!=="brace"&&f.type!=="root"&&f.parent;)f=f.parent,y=f.queue;for(let R=0;R{"use strict";$t.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` 7 | `,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Dt=U((is,It)=>{"use strict";var zr=He(),{MAX_LENGTH:Ot,CHAR_BACKSLASH:Me,CHAR_BACKTICK:Zr,CHAR_COMMA:Vr,CHAR_DOT:Yr,CHAR_LEFT_PARENTHESES:Jr,CHAR_RIGHT_PARENTHESES:en,CHAR_LEFT_CURLY_BRACE:tn,CHAR_RIGHT_CURLY_BRACE:rn,CHAR_LEFT_SQUARE_BRACKET:kt,CHAR_RIGHT_SQUARE_BRACKET:Nt,CHAR_DOUBLE_QUOTE:nn,CHAR_SINGLE_QUOTE:sn,CHAR_NO_BREAK_SPACE:an,CHAR_ZERO_WIDTH_NOBREAK_SPACE:on}=Lt(),un=(e,t={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let r=t||{},n=typeof r.maxLength=="number"?Math.min(Ot,r.maxLength):Ot;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},a=[s],i=s,o=s,d=0,y=e.length,f=0,R=0,p,H={},m=()=>e[f++],A=E=>{if(E.type==="text"&&o.type==="dot"&&(o.type="text"),o&&o.type==="text"&&E.type==="text"){o.value+=E.value;return}return i.nodes.push(E),E.parent=i,E.prev=o,o=E,E};for(A({type:"bos"});f0){if(i.ranges>0){i.ranges=0;let E=i.nodes.shift();i.nodes=[E,{type:"text",value:zr(i)}]}A({type:"comma",value:p}),i.commas++;continue}if(p===Yr&&R>0&&i.commas===0){let E=i.nodes;if(R===0||E.length===0){A({type:"text",value:p});continue}if(o.type==="dot"){if(i.range=[],o.value+=p,o.type="range",i.nodes.length!==3&&i.nodes.length!==5){i.invalid=!0,i.ranges=0,o.type="text";continue}i.ranges++,i.args=[];continue}if(o.type==="range"){E.pop();let b=E[E.length-1];b.value+=o.value+p,o=b,i.ranges--;continue}A({type:"dot",value:p});continue}A({type:"text",value:p})}do if(i=a.pop(),i.type!=="root"){i.nodes.forEach(O=>{O.nodes||(O.type==="open"&&(O.isOpen=!0),O.type==="close"&&(O.isClose=!0),O.nodes||(O.type="text"),O.invalid=!0)});let E=a[a.length-1],b=E.nodes.indexOf(i);E.nodes.splice(b,1,...i.nodes)}while(a.length>0);return A({type:"eos"}),s};It.exports=un});var Bt=U((os,Mt)=>{"use strict";var Pt=He(),cn=vt(),ln=Tt(),pn=Dt(),z=(e,t={})=>{let r=[];if(Array.isArray(e))for(let n of e){let s=z.create(n,t);Array.isArray(s)?r.push(...s):r.push(s)}else r=[].concat(z.create(e,t));return t&&t.expand===!0&&t.nodupes===!0&&(r=[...new Set(r)]),r};z.parse=(e,t={})=>pn(e,t);z.stringify=(e,t={})=>typeof e=="string"?Pt(z.parse(e,t),t):Pt(e,t);z.compile=(e,t={})=>(typeof e=="string"&&(e=z.parse(e,t)),cn(e,t));z.expand=(e,t={})=>{typeof e=="string"&&(e=z.parse(e,t));let r=ln(e,t);return t.noempty===!0&&(r=r.filter(Boolean)),t.nodupes===!0&&(r=[...new Set(r)]),r};z.create=(e,t={})=>e===""||e.length<3?[e]:t.expand!==!0?z.compile(e,t):z.expand(e,t);Mt.exports=z});var Re=U((us,jt)=>{"use strict";var fn=W("path"),ne="\\\\/",Ut=`[^${ne}]`,ae="\\.",hn="\\+",dn="\\?",Te="\\/",gn="(?=.)",Gt="[^/]",Be=`(?:${Te}|$)`,Ft=`(?:^|${Te})`,Ue=`${ae}{1,2}${Be}`,yn=`(?!${ae})`,Rn=`(?!${Ft}${Ue})`,An=`(?!${ae}{0,1}${Be})`,mn=`(?!${Ue})`,Cn=`[^.${Te}]`,En=`${Gt}*?`,Kt={DOT_LITERAL:ae,PLUS_LITERAL:hn,QMARK_LITERAL:dn,SLASH_LITERAL:Te,ONE_CHAR:gn,QMARK:Gt,END_ANCHOR:Be,DOTS_SLASH:Ue,NO_DOT:yn,NO_DOTS:Rn,NO_DOT_SLASH:An,NO_DOTS_SLASH:mn,QMARK_NO_DOT:Cn,STAR:En,START_ANCHOR:Ft},_n=q(k({},Kt),{SLASH_LITERAL:`[${ne}]`,QMARK:Ut,STAR:`${Ut}*?`,DOTS_SLASH:`${ae}{1,2}(?:[${ne}]|$)`,NO_DOT:`(?!${ae})`,NO_DOTS:`(?!(?:^|[${ne}])${ae}{1,2}(?:[${ne}]|$))`,NO_DOT_SLASH:`(?!${ae}{0,1}(?:[${ne}]|$))`,NO_DOTS_SLASH:`(?!${ae}{1,2}(?:[${ne}]|$))`,QMARK_NO_DOT:`[^.${ne}]`,START_ANCHOR:`(?:^|[${ne}])`,END_ANCHOR:`(?:[${ne}]|$)`}),xn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};jt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:xn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:fn.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?_n:Kt}}});var Ae=U(Q=>{"use strict";var bn=W("path"),Sn=process.platform==="win32",{REGEX_BACKSLASH:vn,REGEX_REMOVE_BACKSLASH:Hn,REGEX_SPECIAL_CHARS:wn,REGEX_SPECIAL_CHARS_GLOBAL:Tn}=Re();Q.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Q.hasRegexChars=e=>wn.test(e);Q.isRegexChar=e=>e.length===1&&Q.hasRegexChars(e);Q.escapeRegex=e=>e.replace(Tn,"\\$1");Q.toPosixSlashes=e=>e.replace(vn,"/");Q.removeBackslashes=e=>e.replace(Hn,t=>t==="\\"?"":t);Q.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Q.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:Sn===!0||bn.sep==="\\";Q.escapeLast=(e,t,r)=>{let n=e.lastIndexOf(t,r);return n===-1?e:e[n-1]==="\\"?Q.escapeLast(e,t,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Q.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r};Q.wrapOutput=(e,t={},r={})=>{let n=r.contains?"":"^",s=r.contains?"":"$",a=`${n}(?:${e})${s}`;return t.negated===!0&&(a=`(?:^(?!${a}).*$)`),a}});var Yt=U((ls,Vt)=>{"use strict";var qt=Ae(),{CHAR_ASTERISK:Ge,CHAR_AT:$n,CHAR_BACKWARD_SLASH:me,CHAR_COMMA:Ln,CHAR_DOT:Fe,CHAR_EXCLAMATION_MARK:Ke,CHAR_FORWARD_SLASH:Wt,CHAR_LEFT_CURLY_BRACE:je,CHAR_LEFT_PARENTHESES:qe,CHAR_LEFT_SQUARE_BRACKET:On,CHAR_PLUS:kn,CHAR_QUESTION_MARK:Qt,CHAR_RIGHT_CURLY_BRACE:Nn,CHAR_RIGHT_PARENTHESES:Xt,CHAR_RIGHT_SQUARE_BRACKET:In}=Re(),zt=e=>e===Wt||e===me,Zt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?Infinity:1)},Dn=(e,t)=>{let r=t||{},n=e.length-1,s=r.parts===!0||r.scanToEnd===!0,a=[],i=[],o=[],d=e,y=-1,f=0,R=0,p=!1,H=!1,m=!1,A=!1,E=!1,b=!1,O=!1,N=!1,J=!1,G=!1,ie=0,F,C,v={value:"",depth:0,isGlob:!1},B=()=>y>=n,l=()=>d.charCodeAt(y+1),$=()=>(F=C,d.charCodeAt(++y));for(;y0&&(oe=d.slice(0,f),d=d.slice(f),R-=f),w&&m===!0&&R>0?(w=d.slice(0,R),u=d.slice(R)):m===!0?(w="",u=d):w=d,w&&w!==""&&w!=="/"&&w!==d&&zt(w.charCodeAt(w.length-1))&&(w=w.slice(0,-1)),r.unescape===!0&&(u&&(u=qt.removeBackslashes(u)),w&&O===!0&&(w=qt.removeBackslashes(w)));let c={prefix:oe,input:e,start:f,base:w,glob:u,isBrace:p,isBracket:H,isGlob:m,isExtglob:A,isGlobstar:E,negated:N,negatedExtglob:J};if(r.tokens===!0&&(c.maxDepth=0,zt(C)||i.push(v),c.tokens=i),r.parts===!0||r.tokens===!0){let K;for(let S=0;S{"use strict";var $e=Re(),Z=Ae(),{MAX_LENGTH:Le,POSIX_REGEX_SOURCE:Pn,REGEX_NON_SPECIAL_CHARS:Mn,REGEX_SPECIAL_CHARS_BACKREF:Bn,REPLACEMENTS:Jt}=$e,Un=(e,t)=>{if(typeof t.expandRange=="function")return t.expandRange(...e,t);e.sort();let r=`[${e.join("-")}]`;try{new RegExp(r)}catch(n){return e.map(s=>Z.escapeRegex(s)).join("..")}return r},fe=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,er=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=Jt[e]||e;let r=k({},t),n=typeof r.maxLength=="number"?Math.min(Le,r.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let a={type:"bos",value:"",output:r.prepend||""},i=[a],o=r.capture?"":"?:",d=Z.isWindows(t),y=$e.globChars(d),f=$e.extglobChars(y),{DOT_LITERAL:R,PLUS_LITERAL:p,SLASH_LITERAL:H,ONE_CHAR:m,DOTS_SLASH:A,NO_DOT:E,NO_DOT_SLASH:b,NO_DOTS_SLASH:O,QMARK:N,QMARK_NO_DOT:J,STAR:G,START_ANCHOR:ie}=y,F=g=>`(${o}(?:(?!${ie}${g.dot?A:R}).)*?)`,C=r.dot?"":E,v=r.dot?N:J,B=r.bash===!0?F(r):G;r.capture&&(B=`(${B})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let l={input:e,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:i};e=Z.removePrefix(e,l),s=e.length;let $=[],w=[],oe=[],u=a,c,K=()=>l.index===s-1,S=l.peek=(g=1)=>e[l.index+g],ee=l.advance=()=>e[++l.index]||"",te=()=>e.slice(l.index+1),X=(g="",T=0)=>{l.consumed+=g,l.index+=T},_e=g=>{l.output+=g.output!=null?g.output:g.value,X(g.value)},Ar=()=>{let g=1;for(;S()==="!"&&(S(2)!=="("||S(3)==="?");)ee(),l.start++,g++;return g%2==0?!1:(l.negated=!0,l.start++,!0)},xe=g=>{l[g]++,oe.push(g)},ue=g=>{l[g]--,oe.pop()},x=g=>{if(u.type==="globstar"){let T=l.braces>0&&(g.type==="comma"||g.type==="brace"),h=g.extglob===!0||$.length&&(g.type==="pipe"||g.type==="paren");g.type!=="slash"&&g.type!=="paren"&&!T&&!h&&(l.output=l.output.slice(0,-u.output.length),u.type="star",u.value="*",u.output=B,l.output+=u.output)}if($.length&&g.type!=="paren"&&($[$.length-1].inner+=g.value),(g.value||g.output)&&_e(g),u&&u.type==="text"&&g.type==="text"){u.value+=g.value,u.output=(u.output||"")+g.value;return}g.prev=u,i.push(g),u=g},be=(g,T)=>{let h=q(k({},f[T]),{conditions:1,inner:""});h.prev=u,h.parens=l.parens,h.output=l.output;let _=(r.capture?"(":"")+h.open;xe("parens"),x({type:g,value:T,output:l.output?"":m}),x({type:"paren",extglob:!0,value:ee(),output:_}),$.push(h)},mr=g=>{let T=g.close+(r.capture?")":""),h;if(g.type==="negate"){let _=B;g.inner&&g.inner.length>1&&g.inner.includes("/")&&(_=F(r)),(_!==B||K()||/^\)+$/.test(te()))&&(T=g.close=`)$))${_}`),g.inner.includes("*")&&(h=te())&&/^\.[^\\/.]+$/.test(h)&&(T=g.close=`)${h})${_})`),g.prev.type==="bos"&&(l.negatedExtglob=!0)}x({type:"paren",extglob:!0,value:c,output:T}),ue("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let g=!1,T=e.replace(Bn,(h,_,I,j,M,ke)=>j==="\\"?(g=!0,h):j==="?"?_?_+j+(M?N.repeat(M.length):""):ke===0?v+(M?N.repeat(M.length):""):N.repeat(I.length):j==="."?R.repeat(I.length):j==="*"?_?_+j+(M?B:""):B:_?h:`\\${h}`);return g===!0&&(r.unescape===!0?T=T.replace(/\\/g,""):T=T.replace(/\\+/g,h=>h.length%2==0?"\\\\":h?"\\":"")),T===e&&r.contains===!0?(l.output=e,l):(l.output=Z.wrapOutput(T,l,t),l)}for(;!K();){if(c=ee(),c==="\0")continue;if(c==="\\"){let h=S();if(h==="/"&&r.bash!==!0||h==="."||h===";")continue;if(!h){c+="\\",x({type:"text",value:c});continue}let _=/^\\+/.exec(te()),I=0;if(_&&_[0].length>2&&(I=_[0].length,l.index+=I,I%2!=0&&(c+="\\")),r.unescape===!0?c=ee():c+=ee(),l.brackets===0){x({type:"text",value:c});continue}}if(l.brackets>0&&(c!=="]"||u.value==="["||u.value==="[^")){if(r.posix!==!1&&c===":"){let h=u.value.slice(1);if(h.includes("[")&&(u.posix=!0,h.includes(":"))){let _=u.value.lastIndexOf("["),I=u.value.slice(0,_),j=u.value.slice(_+2),M=Pn[j];if(M){u.value=I+M,l.backtrack=!0,ee(),!a.output&&i.indexOf(u)===1&&(a.output=m);continue}}}(c==="["&&S()!==":"||c==="-"&&S()==="]")&&(c=`\\${c}`),c==="]"&&(u.value==="["||u.value==="[^")&&(c=`\\${c}`),r.posix===!0&&c==="!"&&u.value==="["&&(c="^"),u.value+=c,_e({value:c});continue}if(l.quotes===1&&c!=='"'){c=Z.escapeRegex(c),u.value+=c,_e({value:c});continue}if(c==='"'){l.quotes=l.quotes===1?0:1,r.keepQuotes===!0&&x({type:"text",value:c});continue}if(c==="("){xe("parens"),x({type:"paren",value:c});continue}if(c===")"){if(l.parens===0&&r.strictBrackets===!0)throw new SyntaxError(fe("opening","("));let h=$[$.length-1];if(h&&l.parens===h.parens+1){mr($.pop());continue}x({type:"paren",value:c,output:l.parens?")":"\\)"}),ue("parens");continue}if(c==="["){if(r.nobracket===!0||!te().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));c=`\\${c}`}else xe("brackets");x({type:"bracket",value:c});continue}if(c==="]"){if(r.nobracket===!0||u&&u.type==="bracket"&&u.value.length===1){x({type:"text",value:c,output:`\\${c}`});continue}if(l.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(fe("opening","["));x({type:"text",value:c,output:`\\${c}`});continue}ue("brackets");let h=u.value.slice(1);if(u.posix!==!0&&h[0]==="^"&&!h.includes("/")&&(c=`/${c}`),u.value+=c,_e({value:c}),r.literalBrackets===!1||Z.hasRegexChars(h))continue;let _=Z.escapeRegex(u.value);if(l.output=l.output.slice(0,-u.value.length),r.literalBrackets===!0){l.output+=_,u.value=_;continue}u.value=`(${o}${_}|${u.value})`,l.output+=u.value;continue}if(c==="{"&&r.nobrace!==!0){xe("braces");let h={type:"brace",value:c,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};w.push(h),x(h);continue}if(c==="}"){let h=w[w.length-1];if(r.nobrace===!0||!h){x({type:"text",value:c,output:c});continue}let _=")";if(h.dots===!0){let I=i.slice(),j=[];for(let M=I.length-1;M>=0&&(i.pop(),I[M].type!=="brace");M--)I[M].type!=="dots"&&j.unshift(I[M].value);_=Un(j,r),l.backtrack=!0}if(h.comma!==!0&&h.dots!==!0){let I=l.output.slice(0,h.outputIndex),j=l.tokens.slice(h.tokensIndex);h.value=h.output="\\{",c=_="\\}",l.output=I;for(let M of j)l.output+=M.output||M.value}x({type:"brace",value:c,output:_}),ue("braces"),w.pop();continue}if(c==="|"){$.length>0&&$[$.length-1].conditions++,x({type:"text",value:c});continue}if(c===","){let h=c,_=w[w.length-1];_&&oe[oe.length-1]==="braces"&&(_.comma=!0,h="|"),x({type:"comma",value:c,output:h});continue}if(c==="/"){if(u.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",i.pop(),u=a;continue}x({type:"slash",value:c,output:H});continue}if(c==="."){if(l.braces>0&&u.type==="dot"){u.value==="."&&(u.output=R);let h=w[w.length-1];u.type="dots",u.output+=c,u.value+=c,h.dots=!0;continue}if(l.braces+l.parens===0&&u.type!=="bos"&&u.type!=="slash"){x({type:"text",value:c,output:R});continue}x({type:"dot",value:c,output:R});continue}if(c==="?"){if(!(u&&u.value==="(")&&r.noextglob!==!0&&S()==="("&&S(2)!=="?"){be("qmark",c);continue}if(u&&u.type==="paren"){let _=S(),I=c;if(_==="<"&&!Z.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(u.value==="("&&!/[!=<:]/.test(_)||_==="<"&&!/<([!=]|\w+>)/.test(te()))&&(I=`\\${c}`),x({type:"text",value:c,output:I});continue}if(r.dot!==!0&&(u.type==="slash"||u.type==="bos")){x({type:"qmark",value:c,output:J});continue}x({type:"qmark",value:c,output:N});continue}if(c==="!"){if(r.noextglob!==!0&&S()==="("&&(S(2)!=="?"||!/[!=<:]/.test(S(3)))){be("negate",c);continue}if(r.nonegate!==!0&&l.index===0){Ar();continue}}if(c==="+"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){be("plus",c);continue}if(u&&u.value==="("||r.regex===!1){x({type:"plus",value:c,output:p});continue}if(u&&(u.type==="bracket"||u.type==="paren"||u.type==="brace")||l.parens>0){x({type:"plus",value:c});continue}x({type:"plus",value:p});continue}if(c==="@"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){x({type:"at",extglob:!0,value:c,output:""});continue}x({type:"text",value:c});continue}if(c!=="*"){(c==="$"||c==="^")&&(c=`\\${c}`);let h=Mn.exec(te());h&&(c+=h[0],l.index+=h[0].length),x({type:"text",value:c});continue}if(u&&(u.type==="globstar"||u.star===!0)){u.type="star",u.star=!0,u.value+=c,u.output=B,l.backtrack=!0,l.globstar=!0,X(c);continue}let g=te();if(r.noextglob!==!0&&/^\([^?]/.test(g)){be("star",c);continue}if(u.type==="star"){if(r.noglobstar===!0){X(c);continue}let h=u.prev,_=h.prev,I=h.type==="slash"||h.type==="bos",j=_&&(_.type==="star"||_.type==="globstar");if(r.bash===!0&&(!I||g[0]&&g[0]!=="/")){x({type:"star",value:c,output:""});continue}let M=l.braces>0&&(h.type==="comma"||h.type==="brace"),ke=$.length&&(h.type==="pipe"||h.type==="paren");if(!I&&h.type!=="paren"&&!M&&!ke){x({type:"star",value:c,output:""});continue}for(;g.slice(0,3)==="/**";){let Se=e[l.index+4];if(Se&&Se!=="/")break;g=g.slice(3),X("/**",3)}if(h.type==="bos"&&K()){u.type="globstar",u.value+=c,u.output=F(r),l.output=u.output,l.globstar=!0,X(c);continue}if(h.type==="slash"&&h.prev.type!=="bos"&&!j&&K()){l.output=l.output.slice(0,-(h.output+u.output).length),h.output=`(?:${h.output}`,u.type="globstar",u.output=F(r)+(r.strictSlashes?")":"|$)"),u.value+=c,l.globstar=!0,l.output+=h.output+u.output,X(c);continue}if(h.type==="slash"&&h.prev.type!=="bos"&&g[0]==="/"){let Se=g[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(h.output+u.output).length),h.output=`(?:${h.output}`,u.type="globstar",u.output=`${F(r)}${H}|${H}${Se})`,u.value+=c,l.output+=h.output+u.output,l.globstar=!0,X(c+ee()),x({type:"slash",value:"/",output:""});continue}if(h.type==="bos"&&g[0]==="/"){u.type="globstar",u.value+=c,u.output=`(?:^|${H}|${F(r)}${H})`,l.output=u.output,l.globstar=!0,X(c+ee()),x({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-u.output.length),u.type="globstar",u.output=F(r),u.value+=c,l.output+=u.output,l.globstar=!0,X(c);continue}let T={type:"star",value:c,output:B};if(r.bash===!0){T.output=".*?",(u.type==="bos"||u.type==="slash")&&(T.output=C+T.output),x(T);continue}if(u&&(u.type==="bracket"||u.type==="paren")&&r.regex===!0){T.output=c,x(T);continue}(l.index===l.start||u.type==="slash"||u.type==="dot")&&(u.type==="dot"?(l.output+=b,u.output+=b):r.dot===!0?(l.output+=O,u.output+=O):(l.output+=C,u.output+=C),S()!=="*"&&(l.output+=m,u.output+=m)),x(T)}for(;l.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));l.output=Z.escapeLast(l.output,"["),ue("brackets")}for(;l.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing",")"));l.output=Z.escapeLast(l.output,"("),ue("parens")}for(;l.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","}"));l.output=Z.escapeLast(l.output,"{"),ue("braces")}if(r.strictSlashes!==!0&&(u.type==="star"||u.type==="bracket")&&x({type:"maybe_slash",value:"",output:`${H}?`}),l.backtrack===!0){l.output="";for(let g of l.tokens)l.output+=g.output!=null?g.output:g.value,g.suffix&&(l.output+=g.suffix)}return l};er.fastpaths=(e,t)=>{let r=k({},t),n=typeof r.maxLength=="number"?Math.min(Le,r.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=Jt[e]||e;let a=Z.isWindows(t),{DOT_LITERAL:i,SLASH_LITERAL:o,ONE_CHAR:d,DOTS_SLASH:y,NO_DOT:f,NO_DOTS:R,NO_DOTS_SLASH:p,STAR:H,START_ANCHOR:m}=$e.globChars(a),A=r.dot?R:f,E=r.dot?p:f,b=r.capture?"":"?:",O={negated:!1,prefix:""},N=r.bash===!0?".*?":H;r.capture&&(N=`(${N})`);let J=C=>C.noglobstar===!0?N:`(${b}(?:(?!${m}${C.dot?y:i}).)*?)`,G=C=>{switch(C){case"*":return`${A}${d}${N}`;case".*":return`${i}${d}${N}`;case"*.*":return`${A}${N}${i}${d}${N}`;case"*/*":return`${A}${N}${o}${d}${E}${N}`;case"**":return A+J(r);case"**/*":return`(?:${A}${J(r)}${o})?${E}${d}${N}`;case"**/*.*":return`(?:${A}${J(r)}${o})?${E}${N}${i}${d}${N}`;case"**/.*":return`(?:${A}${J(r)}${o})?${i}${d}${N}`;default:{let v=/^(.*?)\.(\w+)$/.exec(C);if(!v)return;let B=G(v[1]);return B?B+i+v[2]:void 0}}},ie=Z.removePrefix(e,O),F=G(ie);return F&&r.strictSlashes!==!0&&(F+=`${o}?`),F};tr.exports=er});var sr=U((fs,nr)=>{"use strict";var Gn=W("path"),Fn=Yt(),We=rr(),Qe=Ae(),Kn=Re(),jn=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,t,r=!1)=>{if(Array.isArray(e)){let f=e.map(p=>D(p,t,r));return p=>{for(let H of f){let m=H(p);if(m)return m}return!1}}let n=jn(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=t||{},a=Qe.isWindows(t),i=n?D.compileRe(e,t):D.makeRe(e,t,!1,!0),o=i.state;delete i.state;let d=()=>!1;if(s.ignore){let f=q(k({},t),{ignore:null,onMatch:null,onResult:null});d=D(s.ignore,f,r)}let y=(f,R=!1)=>{let{isMatch:p,match:H,output:m}=D.test(f,i,t,{glob:e,posix:a}),A={glob:e,state:o,regex:i,posix:a,input:f,output:m,match:H,isMatch:p};return typeof s.onResult=="function"&&s.onResult(A),p===!1?(A.isMatch=!1,R?A:!1):d(f)?(typeof s.onIgnore=="function"&&s.onIgnore(A),A.isMatch=!1,R?A:!1):(typeof s.onMatch=="function"&&s.onMatch(A),R?A:!0)};return r&&(y.state=o),y};D.test=(e,t,r,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let a=r||{},i=a.format||(s?Qe.toPosixSlashes:null),o=e===n,d=o&&i?i(e):e;return o===!1&&(d=i?i(e):e,o=d===n),(o===!1||a.capture===!0)&&(a.matchBase===!0||a.basename===!0?o=D.matchBase(e,t,r,s):o=t.exec(d)),{isMatch:Boolean(o),match:o,output:d}};D.matchBase=(e,t,r,n=Qe.isWindows(r))=>(t instanceof RegExp?t:D.makeRe(t,r)).test(Gn.basename(e));D.isMatch=(e,t,r)=>D(t,r)(e);D.parse=(e,t)=>Array.isArray(e)?e.map(r=>D.parse(r,t)):We(e,q(k({},t),{fastpaths:!1}));D.scan=(e,t)=>Fn(e,t);D.compileRe=(e,t,r=!1,n=!1)=>{if(r===!0)return e.output;let s=t||{},a=s.contains?"":"^",i=s.contains?"":"$",o=`${a}(?:${e.output})${i}`;e&&e.negated===!0&&(o=`^(?!${o}).*$`);let d=D.toRegex(o,t);return n===!0&&(d.state=e),d};D.makeRe=(e,t={},r=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return t.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=We.fastpaths(e,t)),s.output||(s=We(e,t)),D.compileRe(s,t,r,n)};D.toRegex=(e,t)=>{try{let r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(r){if(t&&t.debug===!0)throw r;return/$^/}};D.constants=Kn;nr.exports=D});var ir=U((hs,ar)=>{"use strict";ar.exports=sr()});var pr=U((ds,lr)=>{"use strict";var or=W("util"),ur=Bt(),se=ir(),Xe=Ae(),cr=e=>e===""||e==="./",L=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let n=new Set,s=new Set,a=new Set,i=0,o=f=>{a.add(f.output),r&&r.onResult&&r.onResult(f)};for(let f=0;f!n.has(f));if(r&&y.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${t.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?t.map(f=>f.replace(/\\/g,"")):t}return y};L.match=L;L.matcher=(e,t)=>se(e,t);L.isMatch=(e,t,r)=>se(t,r)(e);L.any=L.isMatch;L.not=(e,t,r={})=>{t=[].concat(t).map(String);let n=new Set,s=[],a=o=>{r.onResult&&r.onResult(o),s.push(o.output)},i=L(e,t,q(k({},r),{onResult:a}));for(let o of s)i.includes(o)||n.add(o);return[...n]};L.contains=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${or.inspect(e)}"`);if(Array.isArray(t))return t.some(n=>L.contains(e,n,r));if(typeof t=="string"){if(cr(e)||cr(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return L.isMatch(e,t,q(k({},r),{contains:!0}))};L.matchKeys=(e,t,r)=>{if(!Xe.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=L(Object.keys(e),t,r),s={};for(let a of n)s[a]=e[a];return s};L.some=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(n.some(i=>a(i)))return!0}return!1};L.every=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(!n.every(i=>a(i)))return!1}return!0};L.all=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${or.inspect(e)}"`);return[].concat(t).every(n=>se(n,r)(e))};L.capture=(e,t,r)=>{let n=Xe.isWindows(r),a=se.makeRe(String(e),q(k({},r),{capture:!0})).exec(n?Xe.toPosixSlashes(t):t);if(a)return a.slice(1).map(i=>i===void 0?"":i)};L.makeRe=(...e)=>se.makeRe(...e);L.scan=(...e)=>se.scan(...e);L.parse=(e,t)=>{let r=[];for(let n of[].concat(e||[]))for(let s of ur(String(n),t))r.push(se.parse(s,t));return r};L.braces=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return t&&t.nobrace===!0||!/\{.*\}/.test(e)?[e]:ur(e,t)};L.braceExpand=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return L.braces(e,q(k({},t),{expand:!0}))};lr.exports=L});var Zn={};wr(Zn,{default:()=>zn});var Oe=re(W("@yarnpkg/cli")),P=re(W("@yarnpkg/core")),Y=re(W("clipanion")),Rr=re(pr()),Ye=re(W("semver")),Je=re(W("typanion"));var he=re(W("@yarnpkg/core")),gr=re(W("@yarnpkg/plugin-essentials"));var Ce=re(W("semver")),fr=Boolean;function qn(e){var s;let[t,r,n]=(s=e.match(/(github|bitbucket|gitlab):(.+)/))!=null?s:[];return r?`https://${r}.${r==="bitbucket"?"org":"com"}/${n}`:`https://github.com/${e}`}function hr(e){let{homepage:t,repository:r}=e.raw;return t||(typeof r=="string"?qn(r):r==null?void 0:r.url)}function dr(e,t){return Ce.default.parse(t).prerelease.length?Ce.default.lt(e,t):Ce.default.lt(Ce.default.coerce(e),t)}var ze=class{constructor(t,r,n,s){this.configuration=t;this.project=r;this.workspace=n;this.cache=s}async fetch({pkg:t,range:r,url:n}){let s=gr.suggestUtils.fetchDescriptorFrom(t,r,{cache:this.cache,preserveModifier:!1,project:this.project,workspace:this.workspace}),a=n?this.fetchURL(t):Promise.resolve(void 0),[i,o]=await Promise.all([s,a]);if(!i){let d=he.structUtils.prettyIdent(this.configuration,t);throw new Error(`Could not fetch candidate for ${d}.`)}return{url:o,version:i.range}}async fetchURL(t){var a;let r=this.configuration.makeFetcher(),n=await r.fetch(t,{cache:this.cache,checksums:this.project.storedChecksums,fetcher:r,project:this.project,report:new he.ThrowReport,skipIntegrityCheck:!0}),s;try{s=await he.Manifest.find(n.prefixPath,{baseFs:n.packageFs})}finally{(a=n.releaseFs)==null||a.call(n)}return hr(s)}};var de=re(W("@yarnpkg/core")),Wn=/^([0-9]+\.)([0-9]+\.)(.+)$/,Qn=["name","current","latest","workspace","type","url"],Ze=class{constructor(t,r,n,s){this.report=t;this.configuration=r;this.dependencies=n;this.extraColumns=s;this.sizes=null;this.headers={current:"Current",latest:"Latest",name:"Package",type:"Package Type",url:"URL",workspace:"Workspace"}}print(){this.sizes=this.getColumnSizes(),this.printHeader(),this.dependencies.forEach(t=>{var n,s;let r=this.getDiffColor(t);this.printRow({current:t.current.padEnd(this.sizes.current),latest:this.formatVersion(t,"latest",r),name:this.applyColor(t.name.padEnd(this.sizes.name),r),type:t.type.padEnd(this.sizes.type),url:(n=t.url)==null?void 0:n.padEnd(this.sizes.url),workspace:(s=t.workspace)==null?void 0:s.padEnd(this.sizes.workspace)})})}applyColor(t,r){return de.formatUtils.pretty(this.configuration,t,r)}formatVersion(t,r,n){let s=t[r].padEnd(this.sizes[r]),a=s.match(Wn);if(!a)return s;let i=["red","yellow","green"].indexOf(n)+1,o=a.slice(1,i).join(""),d=a.slice(i).join("");return o+de.formatUtils.pretty(this.configuration,this.applyColor(d,n),"bold")}getDiffColor(t){return{major:"red",minor:"yellow",patch:"green"}[t.severity]}getColumnSizes(){let t={current:this.headers.current.length,latest:this.headers.latest.length,name:this.headers.name.length,type:this.headers.type.length,url:this.headers.url.length,workspace:this.headers.workspace.length};for(let r of this.dependencies)for(let[n,s]of Object.entries(r)){let a=t[n],i=(s||"").length;t[n]=a>i?a:i}return t}formatColumnHeader(t){return de.formatUtils.pretty(this.configuration,this.headers[t].padEnd(this.sizes[t]),"bold")}printHeader(){this.printRow({current:this.formatColumnHeader("current"),latest:this.formatColumnHeader("latest"),name:this.formatColumnHeader("name"),type:this.formatColumnHeader("type"),url:this.formatColumnHeader("url"),workspace:this.formatColumnHeader("workspace")})}printRow(t){let r=Qn.filter(n=>{var s;return(s=this.extraColumns[n])!=null?s:!0}).map(n=>t[n]).join(" ").trim();this.report.reportInfo(de.MessageName.UNNAMED,r)}};var Ve=["dependencies","devDependencies"],yr=["major","minor","patch"];var Ee=class extends Oe.BaseCommand{constructor(){super(...arguments);this.patterns=Y.Option.Rest();this.all=Y.Option.Boolean("-a,--all",!1,{description:"Include outdated dependencies from all workspaces"});this.check=Y.Option.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when outdated dependencies are found"});this.json=Y.Option.Boolean("--json",!1,{description:"Format the output as JSON"});this.severity=Y.Option.String("-s,--severity",{description:"Filter results based on the severity of the update",validator:Je.default.isEnum(yr)});this.type=Y.Option.String("-t,--type",{description:"Filter results based on the dependency type",validator:Je.default.isEnum(Ve)});this.url=Y.Option.Boolean("--url",!1,{description:"Include the homepage URL of each package in the output"})}async execute(){let{cache:t,configuration:r,project:n,workspace:s}=await this.loadProject(),a=new ze(r,n,s,t),i=this.getWorkspaces(n,s),o=this.getDependencies(r,i);if(this.json){let y=await this.getOutdatedDependencies(a,o);this.context.stdout.write(JSON.stringify(y)+` 8 | `);return}return(await P.StreamReport.start({configuration:r,stdout:this.context.stdout},async y=>{await this.checkOutdatedDependencies(r,o,a,y)})).exitCode()}async checkOutdatedDependencies(t,r,n,s){let a=null;await s.startTimerPromise("Checking for outdated dependencies",async()=>{let i=r.length,o=P.StreamReport.progressViaCounter(i);s.reportProgress(o),a=await this.getOutdatedDependencies(n,r,o)}),s.reportSeparator(),a.length?(new Ze(s,t,a,{url:this.url,workspace:this.all}).print(),s.reportSeparator(),this.printOutdatedCount(s,a.length)):this.printUpToDate(t,s)}async loadProject(){let t=await P.Configuration.find(this.context.cwd,this.context.plugins),[r,{project:n,workspace:s}]=await Promise.all([P.Cache.find(t),P.Project.find(t,this.context.cwd)]);if(await n.restoreInstallState(),!s)throw new Oe.WorkspaceRequiredError(n.cwd,this.context.cwd);return{cache:r,configuration:t,project:n,workspace:s}}getWorkspaces(t,r){return this.all?t.workspaces:[r]}get dependencyTypes(){return this.type?[this.type]:Ve}getDependencies(t,r){let n=[];for(let a of r){let{anchoredLocator:i,project:o}=a,d=o.storedPackages.get(i.locatorHash);d||this.throw(t,i);for(let y of this.dependencyTypes)for(let f of a.manifest[y].values()){let{range:R}=f;if(R.includes(":")&&!R.startsWith("npm:"))continue;let p=d.dependencies.get(f.identHash);p||this.throw(t,f);let H=o.storedResolutions.get(p.descriptorHash);H||this.throw(t,p);let m=o.storedPackages.get(H);m||this.throw(t,p),n.push({dependencyType:y,name:P.structUtils.stringifyIdent(f),pkg:m,workspace:a})}}if(!this.patterns.length)return n;let s=n.filter(({name:a})=>Rr.default.isMatch(a,this.patterns));if(!s.length)throw new Y.UsageError(`Pattern ${P.formatUtils.prettyList(t,this.patterns,P.FormatType.CODE)} doesn't match any packages referenced by any workspace`);return s}throw(t,r){let n=P.structUtils.prettyIdent(t,r);throw new Error(`Package for ${n} not found in the project`)}getSeverity(t,r){let n=Ye.default.coerce(t),s=Ye.default.coerce(r);return s.major>n.major?"major":s.minor>n.minor?"minor":"patch"}async getOutdatedDependencies(t,r,n){let s=r.map(async({dependencyType:a,name:i,pkg:o,workspace:d})=>{if(d.project.tryWorkspaceByLocator(o))return;let{url:y,version:f}=await t.fetch({pkg:o,range:"latest",url:this.url});if(n==null||n.tick(),dr(o.version,f))return{current:o.version,latest:f,name:i,severity:this.getSeverity(o.version,f),type:a,url:y,workspace:this.all?this.getWorkspaceName(d):void 0}});return(await Promise.all(s)).filter(fr).filter(({severity:a})=>!this.severity||a===this.severity).sort((a,i)=>a.name.localeCompare(i.name))}getWorkspaceName(t){return t.manifest.name?P.structUtils.stringifyIdent(t.manifest.name):t.computeCandidateName()}printOutdatedCount(t,r){let n=[P.MessageName.UNNAMED,r===1?"1 dependency is out of date":`${r} dependencies are out of date`];this.check?t.reportError(...n):t.reportWarning(...n)}printUpToDate(t,r){let n="\u2728 All your dependencies are up to date!";r.reportInfo(P.MessageName.UNNAMED,P.formatUtils.pretty(t,n,"green"))}};Ee.paths=[["outdated"]],Ee.usage=Y.Command.Usage({description:"view outdated dependencies",details:` 9 | This command finds outdated dependencies in a project and prints the result in a table or JSON format. 10 | 11 | This command accepts glob patterns as arguments to filter the output. Make sure to escape the patterns, to prevent your own shell from trying to expand them. 12 | `,examples:[["View outdated dependencies","yarn outdated"],["View outdated dependencies with the `@babel` scope","yarn outdated '@babel/*'"],["Filter results to only include devDependencies","yarn outdated --type devDependencies"],["Filter results to only include major version updates","yarn outdated --severity major"]]});var Xn={commands:[Ee]},zn=Xn;return Zn;})(); 13 | /*! 14 | * fill-range 15 | * 16 | * Copyright (c) 2014-present, Jon Schlinkert. 17 | * Licensed under the MIT License. 18 | */ 19 | /*! 20 | * is-number 21 | * 22 | * Copyright (c) 2014-present, Jon Schlinkert. 23 | * Released under the MIT License. 24 | */ 25 | /*! 26 | * to-regex-range 27 | * 28 | * Copyright (c) 2015-present, Jon Schlinkert. 29 | * Released under the MIT License. 30 | */ 31 | return plugin; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /.yarn/plugins/@yarnpkg/plugin-typescript.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | //prettier-ignore 3 | module.exports = { 4 | name: "@yarnpkg/plugin-typescript", 5 | factory: function (require) { 6 | var plugin=(()=>{var Ft=Object.create,H=Object.defineProperty,Bt=Object.defineProperties,Kt=Object.getOwnPropertyDescriptor,zt=Object.getOwnPropertyDescriptors,Gt=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,$t=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?H(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))ne.call(t,r)&&Re(e,r,t[r]);if(Q)for(var r of Q(t))De.call(t,r)&&Re(e,r,t[r]);return e},g=(e,t)=>Bt(e,zt(t)),Lt=e=>H(e,"__esModule",{value:!0});var R=(e,t)=>{var r={};for(var s in e)ne.call(e,s)&&t.indexOf(s)<0&&(r[s]=e[s]);if(e!=null&&Q)for(var s of Q(e))t.indexOf(s)<0&&De.call(e,s)&&(r[s]=e[s]);return r};var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Vt=(e,t)=>{for(var r in t)H(e,r,{get:t[r],enumerable:!0})},Qt=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gt(t))!ne.call(e,s)&&s!=="default"&&H(e,s,{get:()=>t[s],enumerable:!(r=Kt(t,s))||r.enumerable});return e},C=e=>Qt(Lt(H(e!=null?Ft($t(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var xe=I(J=>{"use strict";Object.defineProperty(J,"__esModule",{value:!0});function _(e){let t=[...e.caches],r=t.shift();return r===void 0?ve():{get(s,n,a={miss:()=>Promise.resolve()}){return r.get(s,n,a).catch(()=>_({caches:t}).get(s,n,a))},set(s,n){return r.set(s,n).catch(()=>_({caches:t}).set(s,n))},delete(s){return r.delete(s).catch(()=>_({caches:t}).delete(s))},clear(){return r.clear().catch(()=>_({caches:t}).clear())}}}function ve(){return{get(e,t,r={miss:()=>Promise.resolve()}){return t().then(n=>Promise.all([n,r.miss(n)])).then(([n])=>n)},set(e,t){return Promise.resolve(t)},delete(e){return Promise.resolve()},clear(){return Promise.resolve()}}}J.createFallbackableCache=_;J.createNullCache=ve});var Ee=I(($s,qe)=>{qe.exports=xe()});var Te=I(ae=>{"use strict";Object.defineProperty(ae,"__esModule",{value:!0});function Jt(e={serializable:!0}){let t={};return{get(r,s,n={miss:()=>Promise.resolve()}){let a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);let o=s(),d=n&&n.miss||(()=>Promise.resolve());return o.then(y=>d(y)).then(()=>o)},set(r,s){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(s):s,Promise.resolve(s)},delete(r){return delete t[JSON.stringify(r)],Promise.resolve()},clear(){return t={},Promise.resolve()}}}ae.createInMemoryCache=Jt});var we=I((Vs,Me)=>{Me.exports=Te()});var Ce=I(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});function Xt(e,t,r){let s={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers(){return e===oe.WithinHeaders?s:{}},queryParameters(){return e===oe.WithinQueryParameters?s:{}}}}function Yt(e){let t=0,r=()=>(t++,new Promise(s=>{setTimeout(()=>{s(e(r))},Math.min(100*t,1e3))}));return e(r)}function ke(e,t=(r,s)=>Promise.resolve()){return Object.assign(e,{wait(r){return ke(e.then(s=>Promise.all([t(s,r),s])).then(s=>s[1]))}})}function Zt(e){let t=e.length-1;for(t;t>0;t--){let r=Math.floor(Math.random()*(t+1)),s=e[t];e[t]=e[r],e[r]=s}return e}function er(e,t){return Object.keys(t!==void 0?t:{}).forEach(r=>{e[r]=t[r](e)}),e}function tr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}var rr="4.2.0",sr=e=>()=>e.transporter.requester.destroy(),oe={WithinQueryParameters:0,WithinHeaders:1};M.AuthMode=oe;M.addMethods=er;M.createAuth=Xt;M.createRetryablePromise=Yt;M.createWaitablePromise=ke;M.destroy=sr;M.encode=tr;M.shuffle=Zt;M.version=rr});var F=I((Js,Ue)=>{Ue.exports=Ce()});var Ne=I(ie=>{"use strict";Object.defineProperty(ie,"__esModule",{value:!0});var nr={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};ie.MethodEnum=nr});var B=I((Ys,We)=>{We.exports=Ne()});var Ze=I(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});var He=B();function ce(e,t){let r=e||{},s=r.data||{};return Object.keys(r).forEach(n=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(n)===-1&&(s[n]=r[n])}),{data:Object.entries(s).length>0?s:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var X={Read:1,Write:2,Any:3},U={Up:1,Down:2,Timeouted:3},_e=2*60*1e3;function ue(e,t=U.Up){return g(u({},e),{status:t,lastUpdate:Date.now()})}function Fe(e){return e.status===U.Up||Date.now()-e.lastUpdate>_e}function Be(e){return e.status===U.Timeouted&&Date.now()-e.lastUpdate<=_e}function le(e){return{protocol:e.protocol||"https",url:e.url,accept:e.accept||X.Any}}function ar(e,t){return Promise.all(t.map(r=>e.get(r,()=>Promise.resolve(ue(r))))).then(r=>{let s=r.filter(d=>Fe(d)),n=r.filter(d=>Be(d)),a=[...s,...n],o=a.length>0?a.map(d=>le(d)):t;return{getTimeout(d,y){return(n.length===0&&d===0?1:n.length+3+d)*y},statelessHosts:o}})}var or=({isTimedOut:e,status:t})=>!e&&~~t==0,ir=e=>{let t=e.status;return e.isTimedOut||or(e)||~~(t/100)!=2&&~~(t/100)!=4},cr=({status:e})=>~~(e/100)==2,ur=(e,t)=>ir(e)?t.onRetry(e):cr(e)?t.onSucess(e):t.onFail(e);function Qe(e,t,r,s){let n=[],a=$e(r,s),o=Le(e,s),d=r.method,y=r.method!==He.MethodEnum.Get?{}:u(u({},r.data),s.data),b=u(u(u({"x-algolia-agent":e.userAgent.value},e.queryParameters),y),s.queryParameters),f=0,p=(h,S)=>{let O=h.pop();if(O===void 0)throw Ve(de(n));let P={data:a,headers:o,method:d,url:Ge(O,r.path,b),connectTimeout:S(f,e.timeouts.connect),responseTimeout:S(f,s.timeout)},x=j=>{let T={request:P,response:j,host:O,triesLeft:h.length};return n.push(T),T},v={onSucess:j=>Ke(j),onRetry(j){let T=x(j);return j.isTimedOut&&f++,Promise.all([e.logger.info("Retryable failure",pe(T)),e.hostsCache.set(O,ue(O,j.isTimedOut?U.Timeouted:U.Down))]).then(()=>p(h,S))},onFail(j){throw x(j),ze(j,de(n))}};return e.requester.send(P).then(j=>ur(j,v))};return ar(e.hostsCache,t).then(h=>p([...h.statelessHosts].reverse(),h.getTimeout))}function lr(e){let{hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,hosts:y,queryParameters:b,headers:f}=e,p={hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,headers:f,queryParameters:b,hosts:y.map(h=>le(h)),read(h,S){let O=ce(S,p.timeouts.read),P=()=>Qe(p,p.hosts.filter(j=>(j.accept&X.Read)!=0),h,O);if((O.cacheable!==void 0?O.cacheable:h.cacheable)!==!0)return P();let v={request:h,mappedRequestOptions:O,transporter:{queryParameters:p.queryParameters,headers:p.headers}};return p.responsesCache.get(v,()=>p.requestsCache.get(v,()=>p.requestsCache.set(v,P()).then(j=>Promise.all([p.requestsCache.delete(v),j]),j=>Promise.all([p.requestsCache.delete(v),Promise.reject(j)])).then(([j,T])=>T)),{miss:j=>p.responsesCache.set(v,j)})},write(h,S){return Qe(p,p.hosts.filter(O=>(O.accept&X.Write)!=0),h,ce(S,p.timeouts.write))}};return p}function dr(e){let t={value:`Algolia for JavaScript (${e})`,add(r){let s=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return t.value.indexOf(s)===-1&&(t.value=`${t.value}${s}`),t}};return t}function Ke(e){try{return JSON.parse(e.content)}catch(t){throw Je(t.message,e)}}function ze({content:e,status:t},r){let s=e;try{s=JSON.parse(e).message}catch(n){}return Xe(s,t,r)}function pr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}function Ge(e,t,r){let s=Ye(r),n=`${e.protocol}://${e.url}/${t.charAt(0)==="/"?t.substr(1):t}`;return s.length&&(n+=`?${s}`),n}function Ye(e){let t=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(e).map(r=>pr("%s=%s",r,t(e[r])?JSON.stringify(e[r]):e[r])).join("&")}function $e(e,t){if(e.method===He.MethodEnum.Get||e.data===void 0&&t.data===void 0)return;let r=Array.isArray(e.data)?e.data:u(u({},e.data),t.data);return JSON.stringify(r)}function Le(e,t){let r=u(u({},e.headers),t.headers),s={};return Object.keys(r).forEach(n=>{let a=r[n];s[n.toLowerCase()]=a}),s}function de(e){return e.map(t=>pe(t))}function pe(e){let t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return g(u({},e),{request:g(u({},e.request),{headers:u(u({},e.request.headers),t)})})}function Xe(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}function Je(e,t){return{name:"DeserializationError",message:e,response:t}}function Ve(e){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:e}}A.CallEnum=X;A.HostStatusEnum=U;A.createApiError=Xe;A.createDeserializationError=Je;A.createMappedRequestOptions=ce;A.createRetryError=Ve;A.createStatefulHost=ue;A.createStatelessHost=le;A.createTransporter=lr;A.createUserAgent=dr;A.deserializeFailure=ze;A.deserializeSuccess=Ke;A.isStatefulHostTimeouted=Be;A.isStatefulHostUp=Fe;A.serializeData=$e;A.serializeHeaders=Le;A.serializeQueryParameters=Ye;A.serializeUrl=Ge;A.stackFrameWithoutCredentials=pe;A.stackTraceWithoutCredentials=de});var K=I((en,et)=>{et.exports=Ze()});var tt=I(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});var N=F(),mr=K(),z=B(),hr=e=>{let t=e.region||"us",r=N.createAuth(N.AuthMode.WithinHeaders,e.appId,e.apiKey),s=mr.createTransporter(g(u({hosts:[{url:`analytics.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n=e.appId;return N.addMethods({appId:n,transporter:s},e.methods)},yr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:"2/abtests",data:t},r),gr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Delete,path:N.encode("2/abtests/%s",t)},r),fr=e=>(t,r)=>e.transporter.read({method:z.MethodEnum.Get,path:N.encode("2/abtests/%s",t)},r),br=e=>t=>e.transporter.read({method:z.MethodEnum.Get,path:"2/abtests"},t),Pr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:N.encode("2/abtests/%s/stop",t)},r);w.addABTest=yr;w.createAnalyticsClient=hr;w.deleteABTest=gr;w.getABTest=fr;w.getABTests=br;w.stopABTest=Pr});var st=I((rn,rt)=>{rt.exports=tt()});var at=I(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});var me=F(),jr=K(),nt=B(),Or=e=>{let t=e.region||"us",r=me.createAuth(me.AuthMode.WithinHeaders,e.appId,e.apiKey),s=jr.createTransporter(g(u({hosts:[{url:`recommendation.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)}));return me.addMethods({appId:e.appId,transporter:s},e.methods)},Ir=e=>t=>e.transporter.read({method:nt.MethodEnum.Get,path:"1/strategies/personalization"},t),Ar=e=>(t,r)=>e.transporter.write({method:nt.MethodEnum.Post,path:"1/strategies/personalization",data:t},r);G.createRecommendationClient=Or;G.getPersonalizationStrategy=Ir;G.setPersonalizationStrategy=Ar});var it=I((nn,ot)=>{ot.exports=at()});var jt=I(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});var l=F(),q=K(),m=B(),Sr=require("crypto");function Y(e){let t=r=>e.request(r).then(s=>{if(e.batch!==void 0&&e.batch(s.hits),!e.shouldStop(s))return s.cursor?t({cursor:s.cursor}):t({page:(r.page||0)+1})});return t({})}var Dr=e=>{let t=e.appId,r=l.createAuth(e.authMode!==void 0?e.authMode:l.AuthMode.WithinHeaders,t,e.apiKey),s=q.createTransporter(g(u({hosts:[{url:`${t}-dsn.algolia.net`,accept:q.CallEnum.Read},{url:`${t}.algolia.net`,accept:q.CallEnum.Write}].concat(l.shuffle([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}]))},e),{headers:u(g(u({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n={transporter:s,appId:t,addAlgoliaAgent(a,o){s.userAgent.add({segment:a,version:o})},clearCache(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then(()=>{})}};return l.addMethods(n,e.methods)};function ct(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function ut(){return{name:"ObjectNotFoundError",message:"Object not found."}}function lt(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Rr=e=>(t,r)=>{let d=r||{},{queryParameters:s}=d,n=R(d,["queryParameters"]),a=u({acl:t},s!==void 0?{queryParameters:s}:{}),o=(y,b)=>l.createRetryablePromise(f=>$(e)(y.key,b).catch(p=>{if(p.status!==404)throw p;return f()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/keys",data:a},n),o)},vr=e=>(t,r,s)=>{let n=q.createMappedRequestOptions(s);return n.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},n)},xr=e=>(t,r,s)=>e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:t,cluster:r}},s),Z=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"copy",destination:r}},s),n)},qr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Rules]})),Er=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Settings]})),Tr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Synonyms]})),Mr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).then(o).catch(d=>{if(d.status!==404)throw d}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/keys/%s",t)},r),s)},wr=()=>(e,t)=>{let r=q.serializeQueryParameters(t),s=Sr.createHmac("sha256",e).update(r).digest("hex");return Buffer.from(s+r).toString("base64")},$=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/keys/%s",t)},r),kr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/logs"},t),Cr=()=>e=>{let t=Buffer.from(e,"base64").toString("ascii"),r=/validUntil=(\d+)/,s=t.match(r);if(s===null)throw lt();return parseInt(s[1],10)-Math.round(new Date().getTime()/1e3)},Ur=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/top"},t),Nr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/clusters/mapping/%s",t)},r),Wr=e=>t=>{let n=t||{},{retrieveMappings:r}=n,s=R(n,["retrieveMappings"]);return r===!0&&(s.getClusters=!0),e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/pending"},s)},L=e=>(t,r={})=>{let s={transporter:e.transporter,appId:e.appId,indexName:t};return l.addMethods(s,r.methods)},Hr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/keys"},t),_r=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters"},t),Fr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/indexes"},t),Br=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping"},t),Kr=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"move",destination:r}},s),n)},zr=e=>(t,r)=>{let s=(n,a)=>Promise.all(Object.keys(n.taskID).map(o=>L(e)(o,{methods:{waitTask:D}}).waitTask(n.taskID[o],a)));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:t}},r),s)},Gr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},r),$r=e=>(t,r)=>{let s=t.map(n=>g(u({},n),{params:q.serializeQueryParameters(n.params||{})}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:s},cacheable:!0},r)},Lr=e=>(t,r)=>Promise.all(t.map(s=>{let d=s.params,{facetName:n,facetQuery:a}=d,o=R(d,["facetName","facetQuery"]);return L(e)(s.indexName,{methods:{searchForFacetValues:dt}}).searchForFacetValues(n,a,u(u({},r),o))})),Vr=e=>(t,r)=>{let s=q.createMappedRequestOptions(r);return s.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Delete,path:"1/clusters/mapping"},s)},Qr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).catch(d=>{if(d.status!==404)throw d;return o()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/keys/%s/restore",t)},r),s)},Jr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:t}},r),Xr=e=>(t,r)=>{let s=Object.assign({},r),f=r||{},{queryParameters:n}=f,a=R(f,["queryParameters"]),o=n?{queryParameters:n}:{},d=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],y=p=>Object.keys(s).filter(h=>d.indexOf(h)!==-1).every(h=>p[h]===s[h]),b=(p,h)=>l.createRetryablePromise(S=>$(e)(t,h).then(O=>y(O)?Promise.resolve():S()));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/keys/%s",t),data:o},a),b)},pt=e=>(t,r)=>{let s=(n,a)=>D(e)(n.taskID,a);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/batch",e.indexName),data:{requests:t}},r),s)},Yr=e=>t=>Y(g(u({},t),{shouldStop:r=>r.cursor===void 0,request:r=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/browse",e.indexName),data:r},t)})),Zr=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},es=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},te=e=>(t,r,s)=>{let y=s||{},{batchSize:n}=y,a=R(y,["batchSize"]),o={taskIDs:[],objectIDs:[]},d=(b=0)=>{let f=[],p;for(p=b;p({action:r,body:h})),a).then(h=>(o.objectIDs=o.objectIDs.concat(h.objectIDs),o.taskIDs.push(h.taskID),p++,d(p)))};return l.createWaitablePromise(d(),(b,f)=>Promise.all(b.taskIDs.map(p=>D(e)(p,f))))},ts=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/clear",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),rs=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ss=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ns=e=>(t,r)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/deleteByQuery",e.indexName),data:t},r),(s,n)=>D(e)(s.taskID,n)),as=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),os=e=>(t,r)=>l.createWaitablePromise(yt(e)([t],r).then(s=>({taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),yt=e=>(t,r)=>{let s=t.map(n=>({objectID:n}));return te(e)(s,k.DeleteObject,r)},is=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},cs=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},us=e=>t=>gt(e)(t).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),ls=e=>(t,r)=>{let y=r||{},{query:s,paginate:n}=y,a=R(y,["query","paginate"]),o=0,d=()=>ft(e)(s||"",g(u({},a),{page:o})).then(b=>{for(let[f,p]of Object.entries(b.hits))if(t(p))return{object:p,position:parseInt(f,10),page:o};if(o++,n===!1||o>=b.nbPages)throw ut();return d()});return d()},ds=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/%s",e.indexName,t)},r),ps=()=>(e,t)=>{for(let[r,s]of Object.entries(e.hits))if(s.objectID===t)return parseInt(r,10);return-1},ms=e=>(t,r)=>{let o=r||{},{attributesToRetrieve:s}=o,n=R(o,["attributesToRetrieve"]),a=t.map(d=>u({indexName:e.indexName,objectID:d},s?{attributesToRetrieve:s}:{}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:a}},n)},hs=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},r),gt=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/settings",e.indexName),data:{getVersion:2}},t),ys=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},r),bt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/task/%s",e.indexName,t.toString())},r),gs=e=>(t,r)=>l.createWaitablePromise(Pt(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),Pt=e=>(t,r)=>{let o=r||{},{createIfNotExists:s}=o,n=R(o,["createIfNotExists"]),a=s?k.PartialUpdateObject:k.PartialUpdateObjectNoCreate;return te(e)(t,a,n)},fs=e=>(t,r)=>{let O=r||{},{safe:s,autoGenerateObjectIDIfNotExist:n,batchSize:a}=O,o=R(O,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),d=(P,x,v,j)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",P),data:{operation:v,destination:x}},j),(T,V)=>D(e)(T.taskID,V)),y=Math.random().toString(36).substring(7),b=`${e.indexName}_tmp_${y}`,f=he({appId:e.appId,transporter:e.transporter,indexName:b}),p=[],h=d(e.indexName,b,"copy",g(u({},o),{scope:["settings","synonyms","rules"]}));p.push(h);let S=(s?h.wait(o):h).then(()=>{let P=f(t,g(u({},o),{autoGenerateObjectIDIfNotExist:n,batchSize:a}));return p.push(P),s?P.wait(o):P}).then(()=>{let P=d(b,e.indexName,"move",o);return p.push(P),s?P.wait(o):P}).then(()=>Promise.all(p)).then(([P,x,v])=>({objectIDs:x.objectIDs,taskIDs:[P.taskID,...x.taskIDs,v.taskID]}));return l.createWaitablePromise(S,(P,x)=>Promise.all(p.map(v=>v.wait(x))))},bs=e=>(t,r)=>ye(e)(t,g(u({},r),{clearExistingRules:!0})),Ps=e=>(t,r)=>ge(e)(t,g(u({},r),{replaceExistingSynonyms:!0})),js=e=>(t,r)=>l.createWaitablePromise(he(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),he=e=>(t,r)=>{let o=r||{},{autoGenerateObjectIDIfNotExist:s}=o,n=R(o,["autoGenerateObjectIDIfNotExist"]),a=s?k.AddObject:k.UpdateObject;if(a===k.UpdateObject){for(let d of t)if(d.objectID===void 0)return l.createWaitablePromise(Promise.reject(ct()))}return te(e)(t,a,n)},Os=e=>(t,r)=>ye(e)([t],r),ye=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,clearExistingRules:n}=d,a=R(d,["forwardToReplicas","clearExistingRules"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.clearExistingRules=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},Is=e=>(t,r)=>ge(e)([t],r),ge=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,replaceExistingSynonyms:n}=d,a=R(d,["forwardToReplicas","replaceExistingSynonyms"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.replaceExistingSynonyms=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},ft=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),dt=e=>(t,r,s)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},s),mt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/search",e.indexName),data:{query:t}},r),ht=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/search",e.indexName),data:{query:t}},r),As=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/indexes/%s/settings",e.indexName),data:t},a),(d,y)=>D(e)(d.taskID,y))},D=e=>(t,r)=>l.createRetryablePromise(s=>bt(e)(t,r).then(n=>n.status!=="published"?s():void 0)),Ss={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},k={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},ee={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},Ds={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},Rs={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};i.ApiKeyACLEnum=Ss;i.BatchActionEnum=k;i.ScopeEnum=ee;i.StrategyEnum=Ds;i.SynonymEnum=Rs;i.addApiKey=Rr;i.assignUserID=vr;i.assignUserIDs=xr;i.batch=pt;i.browseObjects=Yr;i.browseRules=Zr;i.browseSynonyms=es;i.chunkedBatch=te;i.clearObjects=ts;i.clearRules=rs;i.clearSynonyms=ss;i.copyIndex=Z;i.copyRules=qr;i.copySettings=Er;i.copySynonyms=Tr;i.createBrowsablePromise=Y;i.createMissingObjectIDError=ct;i.createObjectNotFoundError=ut;i.createSearchClient=Dr;i.createValidUntilNotFoundError=lt;i.deleteApiKey=Mr;i.deleteBy=ns;i.deleteIndex=as;i.deleteObject=os;i.deleteObjects=yt;i.deleteRule=is;i.deleteSynonym=cs;i.exists=us;i.findObject=ls;i.generateSecuredApiKey=wr;i.getApiKey=$;i.getLogs=kr;i.getObject=ds;i.getObjectPosition=ps;i.getObjects=ms;i.getRule=hs;i.getSecuredApiKeyRemainingValidity=Cr;i.getSettings=gt;i.getSynonym=ys;i.getTask=bt;i.getTopUserIDs=Ur;i.getUserID=Nr;i.hasPendingMappings=Wr;i.initIndex=L;i.listApiKeys=Hr;i.listClusters=_r;i.listIndices=Fr;i.listUserIDs=Br;i.moveIndex=Kr;i.multipleBatch=zr;i.multipleGetObjects=Gr;i.multipleQueries=$r;i.multipleSearchForFacetValues=Lr;i.partialUpdateObject=gs;i.partialUpdateObjects=Pt;i.removeUserID=Vr;i.replaceAllObjects=fs;i.replaceAllRules=bs;i.replaceAllSynonyms=Ps;i.restoreApiKey=Qr;i.saveObject=js;i.saveObjects=he;i.saveRule=Os;i.saveRules=ye;i.saveSynonym=Is;i.saveSynonyms=ge;i.search=ft;i.searchForFacetValues=dt;i.searchRules=mt;i.searchSynonyms=ht;i.searchUserIDs=Jr;i.setSettings=As;i.updateApiKey=Xr;i.waitTask=D});var It=I((on,Ot)=>{Ot.exports=jt()});var At=I(re=>{"use strict";Object.defineProperty(re,"__esModule",{value:!0});function vs(){return{debug(e,t){return Promise.resolve()},info(e,t){return Promise.resolve()},error(e,t){return Promise.resolve()}}}var xs={Debug:1,Info:2,Error:3};re.LogLevelEnum=xs;re.createNullLogger=vs});var Dt=I((un,St)=>{St.exports=At()});var xt=I(fe=>{"use strict";Object.defineProperty(fe,"__esModule",{value:!0});var Rt=require("http"),vt=require("https"),qs=require("url");function Es(){let e={keepAlive:!0},t=new Rt.Agent(e),r=new vt.Agent(e);return{send(s){return new Promise(n=>{let a=qs.parse(s.url),o=a.query===null?a.pathname:`${a.pathname}?${a.query}`,d=u({agent:a.protocol==="https:"?r:t,hostname:a.hostname,path:o,method:s.method,headers:s.headers},a.port!==void 0?{port:a.port||""}:{}),y=(a.protocol==="https:"?vt:Rt).request(d,h=>{let S="";h.on("data",O=>S+=O),h.on("end",()=>{clearTimeout(f),clearTimeout(p),n({status:h.statusCode||0,content:S,isTimedOut:!1})})}),b=(h,S)=>setTimeout(()=>{y.abort(),n({status:0,content:S,isTimedOut:!0})},h*1e3),f=b(s.connectTimeout,"Connection timeout"),p;y.on("error",h=>{clearTimeout(f),clearTimeout(p),n({status:0,content:h.message,isTimedOut:!1})}),y.once("response",()=>{clearTimeout(f),p=b(s.responseTimeout,"Socket timeout")}),s.data!==void 0&&y.write(s.data),y.end()})},destroy(){return t.destroy(),r.destroy(),Promise.resolve()}}}fe.createNodeHttpRequester=Es});var Et=I((dn,qt)=>{qt.exports=xt()});var kt=I((pn,Tt)=>{"use strict";var Mt=Ee(),Ts=we(),W=st(),be=F(),Pe=it(),c=It(),Ms=Dt(),ws=Et(),ks=K();function wt(e,t,r){let s={appId:e,apiKey:t,timeouts:{connect:2,read:5,write:30},requester:ws.createNodeHttpRequester(),logger:Ms.createNullLogger(),responsesCache:Mt.createNullCache(),requestsCache:Mt.createNullCache(),hostsCache:Ts.createInMemoryCache(),userAgent:ks.createUserAgent(be.version).add({segment:"Node.js",version:process.versions.node})};return c.createSearchClient(g(u(u({},s),r),{methods:{search:c.multipleQueries,searchForFacetValues:c.multipleSearchForFacetValues,multipleBatch:c.multipleBatch,multipleGetObjects:c.multipleGetObjects,multipleQueries:c.multipleQueries,copyIndex:c.copyIndex,copySettings:c.copySettings,copyRules:c.copyRules,copySynonyms:c.copySynonyms,moveIndex:c.moveIndex,listIndices:c.listIndices,getLogs:c.getLogs,listClusters:c.listClusters,multipleSearchForFacetValues:c.multipleSearchForFacetValues,getApiKey:c.getApiKey,addApiKey:c.addApiKey,listApiKeys:c.listApiKeys,updateApiKey:c.updateApiKey,deleteApiKey:c.deleteApiKey,restoreApiKey:c.restoreApiKey,assignUserID:c.assignUserID,assignUserIDs:c.assignUserIDs,getUserID:c.getUserID,searchUserIDs:c.searchUserIDs,listUserIDs:c.listUserIDs,getTopUserIDs:c.getTopUserIDs,removeUserID:c.removeUserID,hasPendingMappings:c.hasPendingMappings,generateSecuredApiKey:c.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:c.getSecuredApiKeyRemainingValidity,destroy:be.destroy,initIndex:n=>a=>c.initIndex(n)(a,{methods:{batch:c.batch,delete:c.deleteIndex,getObject:c.getObject,getObjects:c.getObjects,saveObject:c.saveObject,saveObjects:c.saveObjects,search:c.search,searchForFacetValues:c.searchForFacetValues,waitTask:c.waitTask,setSettings:c.setSettings,getSettings:c.getSettings,partialUpdateObject:c.partialUpdateObject,partialUpdateObjects:c.partialUpdateObjects,deleteObject:c.deleteObject,deleteObjects:c.deleteObjects,deleteBy:c.deleteBy,clearObjects:c.clearObjects,browseObjects:c.browseObjects,getObjectPosition:c.getObjectPosition,findObject:c.findObject,exists:c.exists,saveSynonym:c.saveSynonym,saveSynonyms:c.saveSynonyms,getSynonym:c.getSynonym,searchSynonyms:c.searchSynonyms,browseSynonyms:c.browseSynonyms,deleteSynonym:c.deleteSynonym,clearSynonyms:c.clearSynonyms,replaceAllObjects:c.replaceAllObjects,replaceAllSynonyms:c.replaceAllSynonyms,searchRules:c.searchRules,getRule:c.getRule,deleteRule:c.deleteRule,saveRule:c.saveRule,saveRules:c.saveRules,replaceAllRules:c.replaceAllRules,browseRules:c.browseRules,clearRules:c.clearRules}}),initAnalytics:()=>n=>W.createAnalyticsClient(g(u(u({},s),n),{methods:{addABTest:W.addABTest,getABTest:W.getABTest,getABTests:W.getABTests,stopABTest:W.stopABTest,deleteABTest:W.deleteABTest}})),initRecommendation:()=>n=>Pe.createRecommendationClient(g(u(u({},s),n),{methods:{getPersonalizationStrategy:Pe.getPersonalizationStrategy,setPersonalizationStrategy:Pe.setPersonalizationStrategy}}))}}))}wt.version=be.version;Tt.exports=wt});var Ut=I((mn,je)=>{var Ct=kt();je.exports=Ct;je.exports.default=Ct});var Ws={};Vt(Ws,{default:()=>Ks});var Oe=C(require("@yarnpkg/core")),E=C(require("@yarnpkg/core")),Ie=C(require("@yarnpkg/plugin-essentials")),Ht=C(require("semver"));var se=C(require("@yarnpkg/core")),Nt=C(Ut()),Cs="e8e1bd300d860104bb8c58453ffa1eb4",Us="OFCNCOG2CU",Wt=async(e,t)=>{var a;let r=se.structUtils.stringifyIdent(e),n=Ns(t).initIndex("npm-search");try{return((a=(await n.getObject(r,{attributesToRetrieve:["types"]})).types)==null?void 0:a.ts)==="definitely-typed"}catch(o){return!1}},Ns=e=>(0,Nt.default)(Us,Cs,{requester:{async send(r){try{let s=await se.httpUtils.request(r.url,r.data||null,{configuration:e,headers:r.headers});return{content:s.body,isTimedOut:!1,status:s.statusCode}}catch(s){return{content:s.response.body,isTimedOut:!1,status:s.response.statusCode}}}}});var _t=e=>e.scope?`${e.scope}__${e.name}`:`${e.name}`,Hs=async(e,t,r,s)=>{if(r.scope==="types")return;let{project:n}=e,{configuration:a}=n,o=a.makeResolver(),d={project:n,resolver:o,report:new E.ThrowReport};if(!await Wt(r,a))return;let b=_t(r),f=E.structUtils.parseRange(r.range).selector;if(!E.semverUtils.validRange(f)){let P=await o.getCandidates(r,new Map,d);f=E.structUtils.parseRange(P[0].reference).selector}let p=Ht.default.coerce(f);if(p===null)return;let h=`${Ie.suggestUtils.Modifier.CARET}${p.major}`,S=E.structUtils.makeDescriptor(E.structUtils.makeIdent("types",b),h),O=E.miscUtils.mapAndFind(n.workspaces,P=>{var T,V;let x=(T=P.manifest.dependencies.get(r.identHash))==null?void 0:T.descriptorHash,v=(V=P.manifest.devDependencies.get(r.identHash))==null?void 0:V.descriptorHash;if(x!==r.descriptorHash&&v!==r.descriptorHash)return E.miscUtils.mapAndFind.skip;let j=[];for(let Ae of Oe.Manifest.allDependencies){let Se=P.manifest[Ae].get(S.identHash);typeof Se!="undefined"&&j.push([Ae,Se])}return j.length===0?E.miscUtils.mapAndFind.skip:j});if(typeof O!="undefined")for(let[P,x]of O)e.manifest[P].set(x.identHash,x);else{try{if((await o.getCandidates(S,new Map,d)).length===0)return}catch{return}e.manifest[Ie.suggestUtils.Target.DEVELOPMENT].set(S.identHash,S)}},_s=async(e,t,r)=>{if(r.scope==="types")return;let s=_t(r),n=E.structUtils.makeIdent("types",s);for(let a of Oe.Manifest.allDependencies)typeof e.manifest[a].get(n.identHash)!="undefined"&&e.manifest[a].delete(n.identHash)},Fs=(e,t)=>{t.publishConfig&&t.publishConfig.typings&&(t.typings=t.publishConfig.typings),t.publishConfig&&t.publishConfig.types&&(t.types=t.publishConfig.types)},Bs={hooks:{afterWorkspaceDependencyAddition:Hs,afterWorkspaceDependencyRemoval:_s,beforeWorkspacePacking:Fs}},Ks=Bs;return Ws;})(); 7 | return plugin; 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 5 | spec: '@yarnpkg/plugin-interactive-tools' 6 | - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs 7 | spec: '@yarnpkg/plugin-typescript' 8 | - path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs 9 | spec: 'https://mskelton.dev/yarn-outdated/v2' 10 | 11 | yarnPath: .yarn/releases/yarn-berry.cjs 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jason Kuhrt 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 | # @prisma-spectrum/reflector 2 | 3 | Utilities for meta-level interactions with the Prisma toolkit in Node.js. 4 | 5 | ⚠️ **Warning**: This is not a formal Prisma product like `prisma`, `@prisma/client`, etc. If you get value from it great, but there are no guarantees about the vision of this package. That said this package will honour semantic versioning. It is used within Prisma in some projects but also outside such as `nexus-prisma`. 6 | 7 | [![trunk](https://github.com/prisma/utils-node/actions/workflows/trunk.yml/badge.svg)](https://github.com/prisma/utils-node/actions/workflows/trunk.yml) 8 | 9 | [Documentation](https://paka.dev/npm/@prisma-spectrum/reflector) 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | If you have a security issue to report, please contact us at [security@prisma.io](mailto:security@prisma.io). 4 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import * as Fs from 'fs' 2 | import { pathsToModuleNameMapper } from 'ts-jest' 3 | import * as TypeScript from 'typescript' 4 | 5 | const tsconfig: { 6 | config?: { compilerOptions?: { paths?: Record } } 7 | error?: TypeScript.Diagnostic 8 | } = TypeScript.readConfigFile('tsconfig.json', (path) => Fs.readFileSync(path, { encoding: 'utf-8' })) 9 | 10 | const config = { 11 | preset: 'ts-jest', 12 | moduleNameMapper: pathsToModuleNameMapper(tsconfig.config?.compilerOptions?.paths ?? {}, { 13 | prefix: '', 14 | }), 15 | watchPlugins: [ 16 | 'jest-watch-typeahead/filename', 17 | 'jest-watch-typeahead/testname', 18 | 'jest-watch-select-projects', 19 | 'jest-watch-suspend', 20 | ], 21 | } 22 | 23 | export default config 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@prisma-spectrum/reflector", 3 | "version": "0.0.0-dripip", 4 | "repository": "git@github.com:prisma/reflector.git", 5 | "author": "Jason Kuhrt", 6 | "license": "MIT", 7 | "files": [ 8 | "src", 9 | "dist-cjs", 10 | "dist-esm" 11 | ], 12 | "main": "./dist-cjs/index.js", 13 | "module": "./dist-esm/index.js", 14 | "scripts": { 15 | "reflect:toc": "markdown-toc README.md -i --maxdepth 4 && prettier --write README.md", 16 | "format": "yarn format:prettier", 17 | "format:prettier": "prettier --write .", 18 | "format:check": "yarn format:check:prettier", 19 | "format:check:prettier": "prettier --check .", 20 | "lint": "eslint . --ext .ts,.tsx --fix", 21 | "lint:check": "eslint . --ext .ts,.tsx --max-warnings 0", 22 | "type-check": "yarn tsc --noEmit", 23 | "dev": "yarn clean && tsc --build --watch tsconfig.cjs.json tsconfig.esm.json", 24 | "build": "yarn clean && yarn build:cjs && yarn build:esm", 25 | "build:cjs": "tsc --project tsconfig.cjs.json", 26 | "build:esm": "tsc --project tsconfig.esm.json", 27 | "test": "jest", 28 | "clean": "rm -rf dist-cjs dist-esm node_modules/.cache", 29 | "release:pr": "dripip pr", 30 | "release:canary": "dripip preview", 31 | "release:stable": "dripip stable", 32 | "prepack": "yarn build", 33 | "prepare": "ts-patch install -s" 34 | }, 35 | "dependencies": { 36 | "@opentelemetry/api": "^1.1.0", 37 | "remeda": "^0.0.35", 38 | "tslib": "^2.4.0", 39 | "zod": "^3.17.3" 40 | }, 41 | "devDependencies": { 42 | "@prisma-labs/prettier-config": "0.1.0", 43 | "@prisma/client": "4.4.0", 44 | "@prisma/internals": "4.4.0", 45 | "@swc/core": "1.2.194", 46 | "@swc/helpers": "0.3.16", 47 | "@swc/jest": "^0.2.21", 48 | "@tsconfig/recommended": "1.0.1", 49 | "@types/jest": "^27.5.1", 50 | "@types/node": "17.0.35", 51 | "@typescript-eslint/eslint-plugin": "5.26.0", 52 | "@typescript-eslint/parser": "5.26.0", 53 | "dripip": "0.10.0", 54 | "eslint": "8.16.0", 55 | "eslint-config-prettier": "8.5.0", 56 | "eslint-plugin-deprecation": "1.3.2", 57 | "eslint-plugin-only-warn": "1.0.3", 58 | "eslint-plugin-prefer-arrow": "1.2.3", 59 | "eslint-plugin-simple-import-sort": "7.0.0", 60 | "eslint-plugin-tsdoc": "0.2.16", 61 | "jest": "27", 62 | "jest-watch-select-projects": "^2.0.0", 63 | "jest-watch-suspend": "^1.1.2", 64 | "jest-watch-typeahead": "^1.1.0", 65 | "konn": "^0.7.0", 66 | "markdown-toc": "1.2.0", 67 | "prettier": "2.6.2", 68 | "regenerator-runtime": "^0.13.9", 69 | "ts-jest": "^28.0.3", 70 | "ts-node": "10.8.0", 71 | "ts-patch": "2.0.1", 72 | "tsconfig-paths": "4.0.0", 73 | "typescript": "4.7.2", 74 | "typescript-snapshots-plugin": "1.7.0", 75 | "typescript-transform-paths": "3.3.1" 76 | }, 77 | "peerDependencies": { 78 | "@prisma/client": "*", 79 | "@prisma/internals": "*" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Client/api.ts: -------------------------------------------------------------------------------- 1 | import { EngineEventType } from './helpers' 2 | import { SomeDatasourceRecord, SomeModel } from './model' 3 | import * as Remeda from 'remeda' 4 | import { z } from 'zod' 5 | 6 | // TODO Use this Base client once its good enough 7 | // export type ClientBase = ReturnTypeClassInstance> 8 | 9 | /** 10 | * Raw Operations 11 | * ------------------------------------------------------------------------------------------- 12 | */ 13 | 14 | const operationRawNamesEnum = { 15 | $executeRaw: '$executeRaw', 16 | $queryRaw: '$queryRaw', 17 | $executeRawUnsafe: '$executeRawUnsafe', 18 | $queryRawUnsafe: '$queryRawUnsafe', 19 | } as const 20 | 21 | const OperationRawNames = z.nativeEnum(operationRawNamesEnum) 22 | 23 | export type OperationRawName = z.infer 24 | 25 | export interface OperationRawInfo { 26 | $queryRaw: { 27 | output: DatasourceRecord[] 28 | } 29 | $queryRawUnsafe: { 30 | output: DatasourceRecord[] 31 | } 32 | $executeRaw: { 33 | output: number 34 | } 35 | $executeRawUnsafe: { 36 | output: number 37 | } 38 | } 39 | 40 | export type OperationRawOutput = OperationRawInfo[keyof OperationRawInfo]['output'] 41 | 42 | type RawApi = { 43 | [operation in keyof OperationRawInfo]: ( 44 | ...args: unknown[] 45 | ) => Promise 46 | } 47 | 48 | /** 49 | * Model Operations 50 | * ------------------------------------------------------------------------------------------- 51 | */ 52 | 53 | const operationModelNamesEnum = { 54 | create: 'create', 55 | createMany: 'createMany', 56 | findMany: 'findMany', 57 | findUnique: 'findUnique', 58 | findFirst: 'findFirst', 59 | update: 'update', 60 | updateMany: 'updateMany', 61 | upsert: 'upsert', 62 | delete: 'delete', 63 | deleteMany: 'deleteMany', 64 | aggregate: 'aggregate', 65 | groupBy: 'groupBy', 66 | count: 'count', 67 | } as const 68 | 69 | const OperationModelName = z.nativeEnum(operationModelNamesEnum) 70 | 71 | export type OperationModelName = z.infer 72 | 73 | export const operationModelReadOnlyEnum = Remeda.pick(operationModelNamesEnum, [ 74 | 'findMany', 75 | 'findUnique', 76 | 'findFirst', 77 | 'aggregate', 78 | 'groupBy', 79 | 'count', 80 | ]) 81 | 82 | export const OperationModelReadOnly = z.nativeEnum(operationModelReadOnlyEnum) 83 | 84 | export type OperationModelReadOnly = z.infer 85 | 86 | export interface OperationModelInfo { 87 | count: { 88 | output: number 89 | } 90 | findUnique: { 91 | output: null | Model 92 | } 93 | findFirst: { 94 | output: null | Model 95 | } 96 | findMany: { 97 | output: Model[] 98 | } 99 | create: { 100 | output: Model 101 | } 102 | createMany: { 103 | output: { count: number } 104 | } 105 | update: { 106 | output: Model 107 | } 108 | updateMany: { 109 | output: Model[] 110 | } 111 | upsert: { 112 | output: Model 113 | } 114 | delete: { 115 | output: Model 116 | } 117 | deleteMany: { 118 | output: Model[] 119 | } 120 | aggregate: { 121 | output: { 122 | _avg?: Record 123 | _count?: Record 124 | } 125 | } 126 | /** 127 | * @see https://www.prisma.io/docs/concepts/components/prisma-client/aggregation-grouping-summarizing#group-by 128 | */ 129 | groupBy: { 130 | output: (Partial & { _sum: Record })[] 131 | } 132 | } 133 | 134 | export type OperationModelOutput = OperationModelInfo[keyof OperationModelInfo]['output'] 135 | 136 | type ModelApi = { 137 | [operation in keyof OperationModelInfo]: ( 138 | input: unknown 139 | ) => Promise 140 | } 141 | 142 | /** 143 | * Other Methods 144 | * ------------------------------------------------------------------------------------------- 145 | */ 146 | 147 | export interface OperationOtherInfo { 148 | /** 149 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#transaction 150 | */ 151 | $transaction: { 152 | input: [promises: Array>] 153 | output: Promise> 154 | } 155 | /** 156 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#connect-1 157 | */ 158 | $connect: { 159 | input: [] 160 | output: Promise 161 | } 162 | /** 163 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#disconnect-1 164 | */ 165 | $disconnect: { 166 | input: [] 167 | output: Promise 168 | } 169 | /** 170 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#on 171 | */ 172 | $on: { 173 | input: [event: EngineEventType, callback: (event: unknown) => void] 174 | output: void 175 | } 176 | } 177 | 178 | type OtherApi = { 179 | [method in keyof OperationOtherInfo]: ( 180 | ...args: OperationOtherInfo[method]['input'] 181 | ) => Promise 182 | } 183 | 184 | /** 185 | * Groupings 186 | * ------------------------------------------------------------------------------------------- 187 | */ 188 | 189 | export type OperationTransactionOutput = OperationOtherInfo['$transaction']['output'] 190 | 191 | export type OperationOutput = OperationRawOutput | OperationModelOutput | OperationTransactionOutput 192 | 193 | /** 194 | * Overall API 195 | * ------------------------------------------------------------------------------------------- 196 | */ 197 | 198 | export interface ClientStaticBase extends RawApi, OtherApi {} 199 | 200 | export interface ClientDynamicBase { 201 | [modelName: string]: ModelApi 202 | } 203 | 204 | export type ClientBase = ClientDynamicBase & ClientStaticBase 205 | -------------------------------------------------------------------------------- /src/Client/controller.ts: -------------------------------------------------------------------------------- 1 | import { Engines, Schema } from '../index_' 2 | import { Base64 } from '../lib/base64' 3 | import { ClientBase, DMMF, OperationOutput, RequestInput, runRequest } from '.' 4 | // @ts-expect-error This is a private API of the Prisma Client package. 5 | import * as PrismaClientGenerator from '@prisma/client/generator-build' 6 | import * as PrismaClientRuntime from '@prisma/client/runtime' 7 | import { getDMMF } from '@prisma/internals' 8 | import * as Crypto from 'crypto' 9 | import * as fs from 'fs-jetpack' 10 | import * as Path from 'path' 11 | 12 | export const getPrismaClient = async (params: { 13 | schema: { 14 | contents: string 15 | /** 16 | * The path to where the prisma schema file should be written to disk. When NOT using the Data Proxy then the 17 | * schema file will be written to this path. By default a schema.prisma file will be written to a temporary 18 | * directory provided by the operating system. 19 | */ 20 | path?: string 21 | } 22 | connectionString: string 23 | useDataProxy: boolean 24 | }): Promise => { 25 | /** 26 | * About programmatically passing the connection string. 27 | * 28 | * The only way to pass to Proxy Runtime is via inlineDatasources configuration (A). 29 | * 30 | * The only way to pass to Local Runtime is via the constructor (B). 31 | * 32 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#programmatically-override-a-datasource-url 33 | */ 34 | const datasource = Schema.parseDatasourceOrThrow(params.schema.contents) 35 | const prismaClientDmmf = await getDmmf(params.schema.contents) 36 | const schemaContentsBase64 = Base64.to(params.schema.contents) 37 | const schemaContentsHashed = Crypto.createHash('sha256').update(schemaContentsBase64).digest('hex') 38 | const schemaPath = params.schema.path ?? Path.join((await fs.tmpDirAsync()).cwd(), 'schema.prisma') 39 | // eslint-disable-next-line 40 | const prismaClientVersion = require('@prisma/client').Prisma.prismaVersion.client as string 41 | /** 42 | * Currently the query engine always needs the schema on disk even if its not being used. 43 | * 44 | * @see https://github.com/prisma/prisma/issues/11599 45 | */ 46 | if (!params.useDataProxy) { 47 | await fs.writeAsync(schemaPath, params.schema.contents) 48 | } 49 | const PrismaClient = PrismaClientRuntime.getPrismaClient({ 50 | /** 51 | * (A) 52 | */ 53 | dataProxy: params.useDataProxy, 54 | inlineDatasources: { 55 | [datasource.name]: { 56 | url: { 57 | fromEnvVar: null, 58 | value: params.connectionString, 59 | }, 60 | }, 61 | }, 62 | inlineSchema: schemaContentsBase64, 63 | inlineSchemaHash: schemaContentsHashed, 64 | document: prismaClientDmmf, 65 | generator: { 66 | name: 'client', 67 | provider: { 68 | value: 'prisma-client-js', 69 | fromEnvVar: null, 70 | }, 71 | config: { engineType: 'library' }, 72 | output: null, 73 | binaryTargets: [], 74 | previewFeatures: [], 75 | }, 76 | clientVersion: prismaClientVersion, 77 | // TODO remove this once https://github.com/prisma/prisma/issues/11599 is resolved. 78 | dirname: Path.dirname(schemaPath), 79 | activeProvider: datasource.provider, 80 | datasourceNames: [datasource.name], 81 | // TODO What are these for? SQLite-specific options? Why required then? 82 | relativePath: '', 83 | relativeEnvPaths: { 84 | rootEnvPath: '', 85 | schemaEnvPath: '', 86 | }, 87 | }) 88 | 89 | /** 90 | * (B) 91 | */ 92 | // @ts-expect-error TODO 93 | return params.useDataProxy 94 | ? new PrismaClient() 95 | : new PrismaClient({ 96 | datasources: { 97 | [datasource.name]: { 98 | url: params.connectionString, 99 | }, 100 | }, 101 | }) 102 | } 103 | 104 | export const request = async (prisma: ClientBase, request: RequestInput): Promise => { 105 | try { 106 | await prisma.$connect() 107 | const result = await runRequest(prisma, request) 108 | return result 109 | } finally { 110 | await prisma.$disconnect() 111 | } 112 | } 113 | 114 | export const getDmmf = async (schema: string): Promise => { 115 | const libQueryFileName = await Engines.getFileName('query', 'library') 116 | const prismaClientGeneratedDirPath = Path.join(process.cwd(), 'node_modules/.prisma/client') 117 | const libQueryEnginePath = Path.join(prismaClientGeneratedDirPath, libQueryFileName) 118 | 119 | const genericDmmf = await getDMMF({ 120 | datamodel: schema, 121 | prismaPath: libQueryEnginePath, 122 | }) 123 | 124 | // eslint-disable-next-line 125 | const prismaClientDmmf: DMMF.Document = 126 | // eslint-disable-next-line 127 | PrismaClientGenerator.externalToInternalDmmf(genericDmmf) 128 | 129 | return prismaClientDmmf 130 | } 131 | -------------------------------------------------------------------------------- /src/Client/helpers.ts: -------------------------------------------------------------------------------- 1 | import { ReturnTypeClassInstance } from '../lib/helpers' 2 | // @ts-expect-error This is a private API of the Prisma Client package. 3 | import * as PrismaClientGenerator from '@prisma/client/generator-build' 4 | import { DMMF, getPrismaClient } from '@prisma/client/runtime' 5 | import { DatasourceProviderNormalized } from '~/Schema' 6 | 7 | export { DMMF } 8 | 9 | /** 10 | * Prisma Client's methods are not === the actual model name. For example, when the model has a name that starts with an uppercase alphabet, it is lowercased 11 | * So we calculate this "transformed" model name to be able to access the correct key in the `prisma` object. 12 | */ 13 | export const modelNameToClientPropertyName = (modelName: string): string => { 14 | return modelName.charAt(0).toLowerCase() + modelName.slice(1) 15 | } 16 | 17 | /** 18 | * Transform the DMMF into the Prisma Client TypeScript declaration module. 19 | */ 20 | export const dmmfToTypes = (prismaClientDmmf: DMMF.Document): Promise => 21 | // eslint-disable-next-line 22 | PrismaClientGenerator.dmmfToTypes(prismaClientDmmf) 23 | 24 | /** 25 | * While the Client Base from core is not fully typed there are many good bits we can already extract and benefit from. 26 | * The following exports do just that. 27 | */ 28 | type ClientBase = ReturnTypeClassInstance> 29 | 30 | export type EngineEventType = Parameters[0] 31 | 32 | const globalBackticks = /\u0060/g 33 | 34 | /** 35 | * Converts a migration script (e.g. as generated by prisma migrate diff) into something that 36 | * Prisma Client could execute with execute raw. 37 | */ 38 | export const prepareMigrationScriptForClientExecution = (params: { 39 | script: string 40 | dataSource: DatasourceProviderNormalized 41 | }): string[] => { 42 | let script_ = params.script 43 | 44 | if (params.dataSource === 'sqlserver') { 45 | const subStringStartText = 'BEGIN TRAN' 46 | const subStringEndText = 'COMMIT TRAN' 47 | const subStringStartIndex = script_.indexOf(subStringStartText) + subStringStartText.length 48 | const subStringEndIndex = script_.indexOf(subStringEndText) 49 | script_ = params.script.slice(subStringStartIndex, subStringEndIndex) 50 | } 51 | 52 | return script_ 53 | .trim() 54 | .replace(globalBackticks, '') 55 | .split(';') 56 | .map((s) => s.trim()) 57 | .filter((s) => s !== '') 58 | } 59 | -------------------------------------------------------------------------------- /src/Client/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './controller' 3 | export * from './helpers' 4 | export * from './run' 5 | -------------------------------------------------------------------------------- /src/Client/model.ts: -------------------------------------------------------------------------------- 1 | export type SomeModel = Record 2 | export type SomeDatasourceRecord = Record 3 | -------------------------------------------------------------------------------- /src/Client/run.ts: -------------------------------------------------------------------------------- 1 | import { casesHandled } from '../lib/helpers' 2 | import { 3 | OperationModelName, 4 | OperationModelOutput, 5 | OperationOutput, 6 | OperationRawName, 7 | OperationRawOutput, 8 | } from '.' 9 | import { ClientBase } from './api' 10 | import { modelNameToClientPropertyName, prepareMigrationScriptForClientExecution } from './helpers' 11 | import { DatasourceProviderNormalized } from '~/Schema' 12 | 13 | export type RequestInput = RequestTransactionInput | RequestModelInput | RequestRawInput 14 | 15 | export interface RequestTransactionInput { 16 | _tag: 'RequestTransactionInput' 17 | singulars: (RequestModelInput | RequestRawInput)[] 18 | } 19 | export interface RequestRawInput { 20 | _tag: 'RequestRawInput' 21 | operationName: OperationRawName 22 | operationInput: unknown 23 | } 24 | export interface RequestModelInput { 25 | _tag: 'RequestModelInput' 26 | modelName: string 27 | operationName: OperationModelName 28 | operationInput: unknown 29 | } 30 | 31 | export const runRequest = ( 32 | prismaClient: Client, 33 | requestInput: RequestInput 34 | ): Promise => { 35 | return requestInput._tag === 'RequestTransactionInput' 36 | ? prismaClient.$transaction( 37 | requestInput.singulars.map((_) => 38 | _._tag === 'RequestRawInput' ? runRequestRaw(prismaClient, _) : runRequestModel(prismaClient, _) 39 | ) 40 | ) 41 | : requestInput._tag === 'RequestModelInput' 42 | ? runRequestModel(prismaClient, requestInput) 43 | : requestInput._tag === 'RequestRawInput' 44 | ? runRequestRaw(prismaClient, requestInput) 45 | : casesHandled(requestInput) 46 | } 47 | 48 | const runRequestRaw = ( 49 | prismaClient: Client, 50 | requestSingularInput: RequestRawInput 51 | ): Promise => { 52 | return prismaClient[requestSingularInput.operationName](requestSingularInput.operationInput) 53 | } 54 | 55 | const runRequestModel = ( 56 | prismaClient: Client, 57 | requestSingularInput: RequestModelInput 58 | ): Promise => { 59 | const prismaOrmModelPropertyName = modelNameToClientPropertyName(requestSingularInput.modelName) 60 | 61 | const prismaClientModel = prismaClient[prismaOrmModelPropertyName] 62 | 63 | if (!prismaClientModel) { 64 | throw new Error( 65 | `The Prisma client instance has no property of name \`${prismaOrmModelPropertyName}\`. This means that the Prisma client instance was generated from a prisma schema that does not have the model named \`${requestSingularInput.modelName}\`.` 66 | ) 67 | } 68 | 69 | const prismaClientModelOperation = prismaClientModel[requestSingularInput.operationName] 70 | 71 | return prismaClientModelOperation(requestSingularInput.operationInput) 72 | } 73 | 74 | /** 75 | * Execute a series of SQL statements in a transaction. Beware, uses `$executeRawUnsafe` internally. 76 | */ 77 | export const runSqlStatements = async ( 78 | prismaClient: Client, 79 | sqlStatements: string[] 80 | ) => 81 | prismaClient.$transaction(sqlStatements.map((sqlStatement) => prismaClient.$executeRawUnsafe(sqlStatement))) 82 | 83 | /** 84 | * Execute a migration script as produced by migrate diff via the prisma client. 85 | * 86 | * @remarks One reason you might want to do this is if you want to run your migration via the PDP Data Plane. 87 | * Currently it has a Client Proxy and Introspection Proxy but no Migration Proxy. 88 | * 89 | * A reason you might want to use the PDP Data Plane is if the user has allow-listed the static egress IPs of 90 | * PDP Data Plane proxy services. 91 | */ 92 | export const runMigrationScript = async ( 93 | prismaClient: Client, 94 | script: string, 95 | dataSource: DatasourceProviderNormalized 96 | ) => runSqlStatements(prismaClient, prepareMigrationScriptForClientExecution({ script, dataSource })) 97 | -------------------------------------------------------------------------------- /src/ConnectionString/index.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from '../index_' 2 | 3 | /** 4 | * @returns A valid dummy connection string for the given datasource provider. 5 | */ 6 | export const generate = (datasourceProvider: Schema.DatasourceProviderNormalized) => { 7 | switch (datasourceProvider) { 8 | case 'cockroachdb': 9 | case 'postgres': 10 | return 'postgresql://prisma:prisma@localhost:5444/does_not_exist' 11 | case 'mysql': 12 | return 'mysql://prisma:prisma@localhost:5444/does_not_exist' 13 | case 'sqlserver': 14 | return 'sqlserver://localhost:5444;database=does_not_exist;user=prisma;password=prisma;encrypt=true' 15 | case 'sqlite': 16 | return 'file:./dev.db' 17 | default: 18 | return '' 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://www.prisma.io/docs/concepts/components/prisma-data-platform#step-5-generate-the-client 3 | */ 4 | export const prismaClientEngineTypeEnvironmentVariableName = `PRISMA_CLIENT_ENGINE_TYPE` 5 | 6 | /** 7 | * @see https://www.prisma.io/docs/concepts/components/prisma-data-platform#step-5-generate-the-client 8 | */ 9 | export type PrismaClientEngineType = 'dataproxy' 10 | 11 | /** 12 | * @see https://www.prisma.io/docs/concepts/components/prisma-data-platform#step-5-generate-the-client 13 | */ 14 | export const PrismaClientEngineTypeEnum = { 15 | dataproxy: `dataproxy`, 16 | } as const 17 | -------------------------------------------------------------------------------- /src/Engines.ts: -------------------------------------------------------------------------------- 1 | import { casesHandled } from './lib/helpers' 2 | import { getNodeAPIName, getPlatform } from '@prisma/internals' 3 | 4 | export type Kind = 'query' 5 | 6 | /** 7 | * `binary` is legacy system where a child process is spawned. 8 | * `library` uses the new Node API system. 9 | */ 10 | export type EmbedStrategy = 'binary' | 'library' 11 | 12 | /** 13 | * Get the file name of a Prisma engine binary 14 | */ 15 | export const getFileName = async (engineKind: Kind, embedStrategy: EmbedStrategy): Promise => { 16 | const platform = await getPlatform() 17 | const extension = platform === 'windows' ? '.exe' : '' 18 | 19 | if (embedStrategy === 'library') { 20 | return getNodeAPIName(platform, 'fs') 21 | } else if (embedStrategy === 'binary') { 22 | return `${engineKind}-engine-${platform}${extension}` 23 | } else { 24 | // TODO TS is complaining that casesHandled will somehow not terminate here even though it has never return type??? 25 | throw casesHandled(embedStrategy) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Errors/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod' 2 | 3 | /** 4 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference#error-codes 5 | */ 6 | export const code = { 7 | /** 8 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference#common 9 | */ 10 | common: { 11 | authenticationFailed: 'P1000', 12 | cannotReachDatabaseServer: 'P1001', 13 | databaseServerTimedOut: 'P1002', 14 | databaseDoesNotExistAtPath: 'P1003', 15 | operationTimedOut: 'P1008', 16 | databaseAlreadyExists: 'P1009', 17 | databaseUserDeniedAccess: 'P1010', 18 | failedToOpenTLSConnection: 'P1011', 19 | problemWithPrismaSchemaEvaluation: 'P1012', 20 | invalidDatabaseString: 'P1013', 21 | underlyingKindForModelDoesNotExist: 'P1014', 22 | prismaSchemaUsingFeaturesNotSupportedByCurrentDatabaseVersion: 'P1015', 23 | invalidRawQueryParameterCount: 'P1016', 24 | databaseServerClosedTheConnection: 'P1017', 25 | }, 26 | /** 27 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference#prisma-client-query-engine 28 | */ 29 | queryEngine: { 30 | valueExceedsColumnLength: `P2000`, 31 | whereConditionRecordIsMissing: `P2001`, 32 | uniqueConstraintFailed: 'P2002', 33 | //... TODO more 34 | }, 35 | /** 36 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference#prisma-migrate-migration-engine 37 | */ 38 | migrateEngine: { 39 | databaseCreateFailed: 'P3000', 40 | //... TODO more 41 | }, 42 | /** 43 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference#prisma-db-pull-introspection-engine 44 | */ 45 | introspectionEngine: { 46 | failedToCreatePrisaSchemaFile: 'P4000', 47 | introspectedDatabaseWasEmpty: 'P4001', 48 | inconsistentSchema: 'P4002', 49 | }, 50 | dataProxy: { 51 | dataProxyUnauthorized: 'P5007', 52 | }, 53 | } as const 54 | 55 | export const codes = { 56 | ...code.common, 57 | ...code.queryEngine, 58 | ...code.migrateEngine, 59 | ...code.introspectionEngine, 60 | ...code.dataProxy, 61 | } 62 | 63 | /** 64 | * @see https://www.prisma.io/docs/reference/api-reference/error-reference 65 | */ 66 | export const ErrorCodes = z.nativeEnum(codes) 67 | 68 | export type ErrorCodes = z.infer 69 | -------------------------------------------------------------------------------- /src/Schema/create.ts: -------------------------------------------------------------------------------- 1 | import { DatasourceProviderInput } from './datasource' 2 | import endent from 'endent' 3 | 4 | export const createEmpty = ({ 5 | database, 6 | previewFlags, 7 | }: { 8 | /** 9 | * Enable preview feature flags. If any are enabled then a client generator block gets added to the empty PSL. 10 | * Otherwise no client generator block appears. 11 | * 12 | * @defaultValue // All false. 13 | */ 14 | previewFlags?: { 15 | mongoDb: boolean 16 | } 17 | database: { 18 | type: DatasourceProviderInput 19 | url: string 20 | } 21 | }) => { 22 | const previewFlagsEnabled = Object.entries(previewFlags ?? {}) 23 | .filter(([_, enabled]) => enabled) 24 | .map(([previewFlag]) => previewFlag) 25 | 26 | const datasource = endent` 27 | datasource db { 28 | provider = ${createValue(database.type)} 29 | url = ${createValue(database.url)} 30 | } 31 | ` 32 | 33 | const generatorClient = 34 | previewFlagsEnabled.length > 0 35 | ? endent` 36 | generator client { 37 | provider = "prisma-client-js" 38 | previewFeatures = [${previewFlagsEnabled.map((_) => `"${_}"`).join(', ')}] 39 | } 40 | ` 41 | : `` 42 | return `${datasource}\n${generatorClient}`.trim() 43 | } 44 | 45 | /** 46 | * Build a prisma value suitable for the left hand side of an `=` in prisma schema. 47 | */ 48 | export const createValue = (value: string): string => { 49 | if (value.startsWith('env(')) return value 50 | return `"${value}"` 51 | } 52 | 53 | export const createEnvValue = (environmentVariableName: string): string => { 54 | return `env("${environmentVariableName}")` 55 | } 56 | -------------------------------------------------------------------------------- /src/Schema/datasource.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Logic related to the datasource Block. 3 | * 4 | * @see https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#datasource 5 | */ 6 | 7 | import { replaceContent } from '../lib/helpers' 8 | import { createEnvValue, createValue } from './create' 9 | import { SchemaTransformer } from './helpers' 10 | import { z } from 'zod' 11 | 12 | const datasourceProviderInput = { 13 | sqlite: 'sqlite', 14 | postgresql: 'postgresql', 15 | postgres: 'postgres', 16 | mysql: 'mysql', 17 | sqlserver: 'sqlserver', 18 | mongodb: 'mongodb', 19 | 'mongodb+srv': 'mongodb+srv', 20 | cockroachdb: 'cockroachdb', 21 | } as const 22 | 23 | export const DatasourceProviderInput = z.nativeEnum(datasourceProviderInput) 24 | 25 | export type DatasourceProviderInput = z.infer 26 | 27 | const datasourceProviderNormalized = { 28 | sqlite: 'sqlite', 29 | postgres: 'postgres', 30 | mysql: 'mysql', 31 | sqlserver: 'sqlserver', 32 | mongodb: 'mongodb', 33 | cockroachdb: 'cockroachdb', 34 | } as const 35 | 36 | export const DatasourceProviderNormalized = z.nativeEnum(datasourceProviderNormalized) 37 | 38 | export type DatasourceProviderNormalized = z.infer 39 | 40 | const datasourceProviderTypeInputNormalizedMapping: Record< 41 | DatasourceProviderInput, 42 | DatasourceProviderNormalized 43 | > = { 44 | sqlite: 'sqlite', 45 | postgresql: 'postgres', 46 | postgres: 'postgres', 47 | mysql: 'mysql', 48 | sqlserver: 'sqlserver', 49 | mongodb: 'mongodb', 50 | 'mongodb+srv': 'mongodb', 51 | cockroachdb: 'cockroachdb', 52 | } 53 | 54 | const normalizeDatasourceProvider = (a: DatasourceProviderInput): DatasourceProviderNormalized => { 55 | return datasourceProviderTypeInputNormalizedMapping[a] 56 | } 57 | 58 | /** 59 | * @see https://regex101.com/r/LpShvf/5 60 | */ 61 | const datasourceBlockPattern = /^(?!\/\/)\s*(datasource\s+([^{\s]+)\s*{(?:\s|[^}])*})/gm 62 | 63 | /** 64 | * This expression is safe to use on match group 1 from {@link datasourceBlockPattern}. 65 | */ 66 | const datasourceBlockFieldProviderPattern = new RegExp( 67 | `^\\s*provider\\s*=\\s*"(${Object.values(DatasourceProviderInput._def.values).join('|')})"`, 68 | 'gm' 69 | ) 70 | 71 | /** 72 | * This pattern is safe to use on match group 1 from {@link datasourceBlockPattern}. 73 | * 74 | * @see https://regex101.com/r/Cv6qth/2 75 | */ 76 | const datasourceBlockFieldUrlPattern = /^\s*url\s*=\s*([^\n]+)\s*$/gm 77 | 78 | /** 79 | * This pattern is safe to use on match group 1 from {@link datasourceBlockFieldUrlPattern}. 80 | * 81 | * @see https://regex101.com/r/TmEuzw/2 82 | */ 83 | const datasourceBlockFieldUrlEnvPattern = /env\(\s*"([^"]+)"\s*\)/ 84 | 85 | /** 86 | * This pattern is safe to use on match group 1 from {@link datasourceBlockFieldUrlPattern}. 87 | * 88 | * @see https://regex101.com/r/OQTF4m/3 89 | */ 90 | const datasourceBlockFieldUrlLiteralPattern = /"([^"]+)"/ 91 | 92 | /** 93 | * Parse the datasource url from the Prisma schema. 94 | * 95 | * Throws if no valid datasource block is found 96 | * Throws if multiple valid datasource url blocks are found. 97 | */ 98 | export const parseDatasourceOrThrow = (schema: string): ParsedDatasource => { 99 | const blockResults = Array.from(schema.matchAll(datasourceBlockPattern)) 100 | if (blockResults.length === 0) { 101 | throw new Error(`Failed to parse datasource: No datasource block found.`) 102 | } 103 | if (blockResults.length > 1) { 104 | throw new Error(`Failed to parse datasource: Multiple datasource blocks found.`) 105 | } 106 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 107 | const blockResult = blockResults[0]! 108 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 109 | const blockCode = blockResult[1]! 110 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 111 | const blockName = blockResult[2]! 112 | 113 | const fieldProviderResults = Array.from(blockCode.matchAll(datasourceBlockFieldProviderPattern)) 114 | if (fieldProviderResults.length === 0) { 115 | throw new Error(`Failed to parse datasource: No valid provder property set.`) 116 | } 117 | if (fieldProviderResults.length > 1) { 118 | throw new Error(`Failed to parse datasource: Multiple provder properties set.`) 119 | } 120 | // @ts-expect-error The regexp guarantees that this string is "parsed" into an expected value. 121 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 122 | const provider = normalizeDatasourceProvider(fieldProviderResults[0]![1]!) 123 | 124 | const fieldUrlResults = Array.from(blockCode.matchAll(datasourceBlockFieldUrlPattern)) 125 | if (fieldUrlResults.length === 0) { 126 | throw new Error( 127 | `Failed to parse datasource: No url property found:\n\nPattern:\n${String( 128 | datasourceBlockFieldUrlPattern 129 | )}\n\nCode:\n${blockCode}` 130 | ) 131 | } 132 | if (fieldUrlResults.length > 1) { 133 | throw new Error(`Failed to parse datasource: Multiple url properties found.`) 134 | } 135 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 136 | const urlValue = fieldUrlResults[0]![1]! 137 | 138 | const urlEnvResult = urlValue.match(datasourceBlockFieldUrlEnvPattern) 139 | if (urlEnvResult) { 140 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 141 | const environmentVariableName = urlEnvResult[1]! 142 | return { 143 | _tag: 'ParsedDatasourceUrlEnvironmentVariable', 144 | environmentVariableName, 145 | name: blockName, 146 | provider: provider, 147 | sources: { 148 | url: urlValue, 149 | }, 150 | } 151 | } 152 | 153 | const urlLiteralResult = urlValue.match(datasourceBlockFieldUrlLiteralPattern) 154 | if (urlLiteralResult) { 155 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 156 | const connectionString = urlLiteralResult[1]! 157 | return { 158 | _tag: 'ParsedDatasourceUrlInline', 159 | connectionString, 160 | name: blockName, 161 | provider: provider, 162 | sources: { 163 | url: urlValue, 164 | }, 165 | } 166 | } 167 | 168 | // This is impossible because group1 match to begin with necessitates that either the env or inline pattern is present. 169 | throw new Error(`Failed to parse datasource url property: ${urlValue}`) 170 | } 171 | 172 | /** 173 | * @returns File contents with replaced datasource. File path and content parameters do not need to match. 174 | */ 175 | export const setDatasourceProvider: SchemaTransformer<{ value: DatasourceProviderInput }> = ( 176 | params 177 | ): string => { 178 | return replaceContent({ 179 | content: params.prismaSchemaContent, 180 | pattern: datasourceBlockFieldProviderPattern, 181 | replacement: `provider = "${params.value}"`, 182 | }) 183 | } 184 | 185 | /** 186 | * Change the datasource block url field value. 187 | * 188 | * Use the `environmentVariable` parameter to control if the value is set as 189 | * environment variable name or an inline connection string. 190 | * 191 | * By default the value is set as an inline connection string. 192 | * 193 | * No validation is performed on the value. So invalid connection strings will be permitted for example. 194 | * 195 | * @throws If the given schema has no valid datasource block. 196 | * @throws If the given schema has multiple valid datasource blocks. 197 | * 198 | * @example 199 | * 200 | * ```ts 201 | * const prismaSchemaContent = ` 202 | * datasource db { 203 | * url = "postgres://user:pass@localhost:5432/db" 204 | * } 205 | * ` 206 | * setDatasourceUrlOrThrow({ 207 | * environmentVariable: true, 208 | * value: 'DB_URL', 209 | * prismaSchemaContent, 210 | * }) // -> 211 | * // datasource db { 212 | * // url = env("DB_URL") 213 | * // } 214 | * 215 | * setDatasourceUrlOrThrow({ 216 | * value: 'foobar', 217 | * prismaSchemaContent, 218 | * }) // -> 219 | * // datasource db { 220 | * // url = "foobar" 221 | * // } 222 | * ``` 223 | */ 224 | export const setDatasourceUrlOrThrow: SchemaTransformer<{ 225 | /** 226 | * Should the value be treated as an environment variable name? 227 | * 228 | * @defaultValue false 229 | */ 230 | environmentVariable?: boolean 231 | value: string 232 | }> = (params): string => { 233 | const result = parseDatasourceOrThrow(params.prismaSchemaContent) 234 | if (params.environmentVariable) { 235 | return params.prismaSchemaContent.replace(result.sources.url, createEnvValue(params.value)) 236 | } else { 237 | return params.prismaSchemaContent.replace(result.sources.url, createValue(params.value)) 238 | } 239 | } 240 | 241 | export type ParsedDatasource = 242 | | { 243 | _tag: 'ParsedDatasourceUrlInline' 244 | sources: { 245 | url: string 246 | } 247 | /** 248 | * The name of the block. 249 | */ 250 | name: string 251 | provider: DatasourceProviderNormalized 252 | connectionString: string 253 | } 254 | | { 255 | _tag: 'ParsedDatasourceUrlEnvironmentVariable' 256 | /** 257 | * The source code snippet 258 | */ 259 | sources: { 260 | url: string 261 | } 262 | /** 263 | * The name of the block. 264 | */ 265 | name: string 266 | provider: DatasourceProviderNormalized 267 | environmentVariableName: string 268 | } 269 | -------------------------------------------------------------------------------- /src/Schema/helpers.ts: -------------------------------------------------------------------------------- 1 | import { getDMMF } from '@prisma/internals' 2 | 3 | export type SchemaTransformer> = ( 4 | params: { prismaSchemaContent: string } & Parameters 5 | ) => string 6 | 7 | export type DMMFDocument = Awaited> 8 | -------------------------------------------------------------------------------- /src/Schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create' 2 | export * from './datasource' 3 | export * from './helpers' 4 | export * from './previewFeatures' 5 | export * from './referentialIntegrity' 6 | -------------------------------------------------------------------------------- /src/Schema/previewFeatures.ts: -------------------------------------------------------------------------------- 1 | import { replaceContent } from '../lib/helpers' 2 | 3 | /** 4 | * @see https://www.prisma.io/docs/concepts/components/preview-features/client-preview-features 5 | */ 6 | export const PreviewFeatureFlag = { 7 | /** 8 | * @see https://www.prisma.io/docs/concepts/database-connectors/mongodb 9 | */ 10 | mongoDb: 'mongoDb', 11 | /** 12 | * @see https://www.prisma.io/docs/concepts/components/prisma-data-platform#step-3-enable-the-feature-flag-in-the-prisma-schema-file 13 | */ 14 | dataProxy: 'dataProxy', 15 | /** 16 | * @see https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity 17 | */ 18 | referentialIntegrity: 'referentialIntegrity', 19 | } as const 20 | 21 | /** 22 | * @see https://www.prisma.io/docs/concepts/components/preview-features/client-preview-features 23 | */ 24 | export const previewFeaturesPattern = /previewFeatures *= *\[([^\]]+)\]/ 25 | 26 | export type PreviewFeatureFlag = keyof typeof PreviewFeatureFlag 27 | 28 | export const addPreviewFeatureFlag = (params: { 29 | prismaSchemaContent: string 30 | previewFlag: PreviewFeatureFlag 31 | }) => { 32 | const existingPreviewFeatures = params.prismaSchemaContent.match(previewFeaturesPattern) 33 | if (existingPreviewFeatures) { 34 | // If the preview flag is already present then return the schema content as is. 35 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- match guarantees this is not null 36 | if (existingPreviewFeatures[1]!.includes(PreviewFeatureFlag[params.previewFlag])) { 37 | return params.prismaSchemaContent 38 | } 39 | // Add the preview flag to the existing preview features field. 40 | return replaceContent({ 41 | content: params.prismaSchemaContent, 42 | pattern: /previewFeatures(.*)=(.*)\[(.+)]/, 43 | replacement: `previewFeatures$1=$2[$3, "${params.previewFlag}"]`, 44 | }) 45 | } else { 46 | // Add the preview flag to a newly added preview features field. 47 | return replaceContent({ 48 | content: params.prismaSchemaContent, 49 | pattern: /(provider *= *"prisma-client-js")/, 50 | replacement: `$1\n previewFeatures = ["${params.previewFlag}"]`, 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Schema/referentialIntegrity.ts: -------------------------------------------------------------------------------- 1 | import { replaceContent } from '../lib/helpers' 2 | import { SchemaTransformer } from './helpers' 3 | import { addPreviewFeatureFlag, PreviewFeatureFlag } from './previewFeatures' 4 | 5 | /** 6 | * @see https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity 7 | */ 8 | export const ReferentialIntegritySettingValue = { 9 | prisma: 'prisma', 10 | foreignKeys: 'foreignKeys', 11 | } as const 12 | 13 | /** 14 | * @see https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity 15 | */ 16 | export type ReferentialIntegritySettingValue = keyof typeof ReferentialIntegritySettingValue 17 | 18 | /** 19 | * @see https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity 20 | */ 21 | export const referentialIntegritySettingValueDefault = ReferentialIntegritySettingValue.foreignKeys 22 | 23 | /** 24 | * @see https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-integrity 25 | */ 26 | export const setReferentialIntegrity: SchemaTransformer<{ value: ReferentialIntegritySettingValue }> = ( 27 | params 28 | ): string => { 29 | if (params.value === referentialIntegritySettingValueDefault) { 30 | // TODO removePreviewFlag({...}) 31 | return params.prismaSchemaContent 32 | } 33 | 34 | const content1 = addPreviewFeatureFlag({ 35 | prismaSchemaContent: params.prismaSchemaContent, 36 | previewFlag: PreviewFeatureFlag.referentialIntegrity, 37 | }) 38 | 39 | const content2 = replaceContent({ 40 | content: content1, 41 | pattern: /(url *= *env\(".+"\))/, 42 | replacement: `$1\n referentialIntegrity = "${params.value}"`, 43 | }) 44 | 45 | return content2 46 | } 47 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * as Reflector from './index_' 2 | -------------------------------------------------------------------------------- /src/index_.ts: -------------------------------------------------------------------------------- 1 | export * as Client from './Client' 2 | export * as ConnectionString from './ConnectionString' 3 | export * as Constants from './Constants' 4 | export * as Engines from './Engines' 5 | export * as Errors from './Errors' 6 | export * as Schema from './Schema' 7 | -------------------------------------------------------------------------------- /src/lib/base64/Base64.ts: -------------------------------------------------------------------------------- 1 | export const to = (content: string): string => 2 | // eslint-disable-next-line 3 | isBrowser() ? btoa(content) : Buffer.from(content, 'utf-8').toString('base64') 4 | 5 | export const from = (content: string): string => 6 | // eslint-disable-next-line 7 | isBrowser() ? atob(content) : Buffer.from(content, 'base64').toString('utf-8') 8 | 9 | const isBrowser = () => 10 | // @ts-expect-error `window` is an unknown global 11 | typeof window !== 'undefined' 12 | -------------------------------------------------------------------------------- /src/lib/base64/index.ts: -------------------------------------------------------------------------------- 1 | export * as Base64 from './Base64' 2 | -------------------------------------------------------------------------------- /src/lib/helpers.ts: -------------------------------------------------------------------------------- 1 | import { inspect } from 'util' 2 | 3 | export const replaceContent = (params: { content: string; pattern: RegExp; replacement: string }) => { 4 | const { pattern, content, replacement } = params 5 | 6 | if (!pattern.exec(content)) { 7 | throw new Error(`Pattern ${String(pattern)} does not match on content:\n\n${content}`) 8 | } 9 | 10 | return content.replace(pattern, replacement) 11 | } 12 | 13 | /** 14 | * TypeScript helper to statically enforce that all cases have been handled in a switch (or similar) block. 15 | */ 16 | export const casesHandled = (x: never): never => { 17 | // Should never happen, but in case it does :) 18 | // eslint-disable-next-line 19 | throw new Error(`All cases were not handled:\n${inspect(x)}`) 20 | } 21 | 22 | /** 23 | * A variant of ReturnType that works on classes to to get their instance type. 24 | */ 25 | // prettier-ignore 26 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 27 | export type ReturnTypeClassInstance any> = T extends new (...args: any) => infer R ? R : any 28 | -------------------------------------------------------------------------------- /tests/Schema/__snapshots__/schema.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`parseDatasourceOrThrow success environment variable reference finds when nicely formatted 1`] = ` 4 | Object { 5 | "_tag": "ParsedDatasourceUrlEnvironmentVariable", 6 | "environmentVariableName": "FOOBAR", 7 | "name": "db", 8 | "provider": "postgres", 9 | "sources": Object { 10 | "url": "env(\\"FOOBAR\\")", 11 | }, 12 | } 13 | `; 14 | 15 | exports[`parseDatasourceOrThrow success environment variable reference finds when white space before or after quotes 1`] = ` 16 | Object { 17 | "_tag": "ParsedDatasourceUrlEnvironmentVariable", 18 | "environmentVariableName": "FOOBAR", 19 | "name": "db", 20 | "provider": "postgres", 21 | "sources": Object { 22 | "url": "env( \\"FOOBAR\\" )", 23 | }, 24 | } 25 | `; 26 | 27 | exports[`parseDatasourceOrThrow success finds inline connection string 1`] = ` 28 | Object { 29 | "_tag": "ParsedDatasourceUrlInline", 30 | "connectionString": "...", 31 | "name": "db", 32 | "provider": "postgres", 33 | "sources": Object { 34 | "url": "\\"...\\"", 35 | }, 36 | } 37 | `; 38 | 39 | exports[`parseDatasourceOrThrow success ignores comments a whole datasource block 1`] = ` 40 | Object { 41 | "_tag": "ParsedDatasourceUrlEnvironmentVariable", 42 | "environmentVariableName": "...", 43 | "name": "db", 44 | "provider": "postgres", 45 | "sources": Object { 46 | "url": "env(\\"...\\")", 47 | }, 48 | } 49 | `; 50 | 51 | exports[`parseDatasourceOrThrow success ignores comments single field lines 1`] = ` 52 | Object { 53 | "_tag": "ParsedDatasourceUrlEnvironmentVariable", 54 | "environmentVariableName": "...", 55 | "name": "db", 56 | "provider": "postgres", 57 | "sources": Object { 58 | "url": "env(\\"...\\")", 59 | }, 60 | } 61 | `; 62 | 63 | exports[`parseDatasourceOrThrow thrown errors An invalid provider field causes an error 1`] = `"Failed to parse datasource: No valid provder property set."`; 64 | 65 | exports[`parseDatasourceOrThrow thrown errors Datasource block missing url field causes an error 1`] = `"Failed to parse datasource: No valid provder property set."`; 66 | 67 | exports[`parseDatasourceOrThrow thrown errors Missing a provider field causes an error 1`] = `"Failed to parse datasource: No valid provder property set."`; 68 | 69 | exports[`parseDatasourceOrThrow thrown errors Missing a url field causes an error 1`] = ` 70 | "Failed to parse datasource: No url property found: 71 | 72 | Pattern: 73 | /^\\\\s*url\\\\s*=\\\\s*([^\\\\n]+)\\\\s*$/gm 74 | 75 | Code: 76 | datasource db { 77 | provider = \\"sqlite\\" 78 | }" 79 | `; 80 | 81 | exports[`parseDatasourceOrThrow thrown errors multiple data source blocks causes an error 1`] = `"Failed to parse datasource: Multiple datasource blocks found."`; 82 | -------------------------------------------------------------------------------- /tests/Schema/schema.spec.ts: -------------------------------------------------------------------------------- 1 | import { Reflector } from '~/index' 2 | 3 | describe('parseDatasourceOrThrow', () => { 4 | describe('success', () => { 5 | test('finds inline connection string', () => { 6 | expect( 7 | Reflector.Schema.parseDatasourceOrThrow(` 8 | datasource db { 9 | url = "..." 10 | provider = "postgres" 11 | } 12 | `) 13 | ).toMatchSnapshot() 14 | }) 15 | describe('provider type input is accepted, but normalized upon return', () => { 16 | it('postgresql becomes postgres', () => { 17 | const result1 = Reflector.Schema.parseDatasourceOrThrow(` 18 | datasource db { 19 | provider = "postgres" 20 | url = env("...") 21 | } 22 | `) 23 | const result2 = Reflector.Schema.parseDatasourceOrThrow(` 24 | datasource db { 25 | provider = "postgresql" 26 | url = env("...") 27 | } 28 | `) 29 | expect(result1.provider).toEqual(Reflector.Schema.DatasourceProviderNormalized._def.values.postgres) 30 | expect(result1.provider).toEqual(result2.provider) 31 | }) 32 | }) 33 | describe('ignores comments', () => { 34 | test('a whole datasource block', () => { 35 | expect( 36 | Reflector.Schema.parseDatasourceOrThrow(` 37 | //datasource db_old { 38 | // url = env("...old") 39 | //} 40 | // datasource db_old_2 { 41 | datasource db { 42 | url = env("...") 43 | provider = "postgres" 44 | } 45 | `) 46 | ).toMatchSnapshot() 47 | }) 48 | test('single field lines', () => { 49 | expect( 50 | Reflector.Schema.parseDatasourceOrThrow(` 51 | datasource db { 52 | // url = env("bad1") 53 | url = env("...") 54 | /// url = "bad2" 55 | //blah url = "bad3" 56 | ///blah url = "bad4" 57 | provider = "postgres" 58 | } 59 | `) 60 | ).toMatchSnapshot() 61 | }) 62 | }) 63 | 64 | describe('environment variable reference', () => { 65 | test('finds when nicely formatted', () => { 66 | expect( 67 | Reflector.Schema.parseDatasourceOrThrow(` 68 | datasource db { 69 | url = env("FOOBAR") 70 | provider = "postgres" 71 | } 72 | `) 73 | ).toMatchSnapshot() 74 | }) 75 | 76 | test('finds when white space before or after quotes', () => { 77 | expect( 78 | Reflector.Schema.parseDatasourceOrThrow(` 79 | datasource db { 80 | url = env( "FOOBAR" ) 81 | provider = "postgres" 82 | } 83 | `) 84 | ).toMatchSnapshot() 85 | }) 86 | }) 87 | }) 88 | describe('thrown errors', () => { 89 | test('multiple data source blocks causes an error', () => { 90 | expect(() => 91 | Reflector.Schema.parseDatasourceOrThrow(` 92 | datasource db1 { 93 | url = "..." 94 | } 95 | 96 | datasource db2 { 97 | url = "..." 98 | } 99 | `) 100 | ).toThrowErrorMatchingSnapshot() 101 | }) 102 | 103 | test('Datasource block missing url field causes an error', () => { 104 | expect(() => 105 | Reflector.Schema.parseDatasourceOrThrow(` 106 | datasource db {} 107 | `) 108 | ).toThrowErrorMatchingSnapshot() 109 | }) 110 | test('Missing a url field causes an error', () => { 111 | expect(() => 112 | Reflector.Schema.parseDatasourceOrThrow(` 113 | datasource db { 114 | provider = "sqlite" 115 | } 116 | `) 117 | ).toThrowErrorMatchingSnapshot() 118 | }) 119 | test('Missing a provider field causes an error', () => { 120 | expect(() => 121 | Reflector.Schema.parseDatasourceOrThrow(` 122 | datasource db { 123 | url = "..." 124 | } 125 | `) 126 | ).toThrowErrorMatchingSnapshot() 127 | }) 128 | test('An invalid provider field causes an error', () => { 129 | expect(() => 130 | Reflector.Schema.parseDatasourceOrThrow(` 131 | datasource db { 132 | url = "..." 133 | provider = "sqlitee" 134 | } 135 | `) 136 | ).toThrowErrorMatchingSnapshot() 137 | }) 138 | }) 139 | }) 140 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist-cjs", 5 | "module": "commonjs", 6 | "rootDir": "src", 7 | "sourceMap": true, 8 | "declaration": true, 9 | "declarationMap": true 10 | }, 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist-esm", 5 | "module": "ES2015", 6 | "moduleResolution": "node", 7 | "rootDir": "src", 8 | "sourceMap": true, 9 | "declaration": true, 10 | "declarationMap": true 11 | }, 12 | "include": ["src"] 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node14/tsconfig.json", 3 | "ts-node": { 4 | "swc": true, 5 | "require": ["tsconfig-paths/register"], 6 | "compilerOptions": { 7 | // Sometimes projects (e.g. Nextjs) will want code to emit ESM but ts-node will not work with that. 8 | "module": "CommonJS" 9 | } 10 | }, 11 | "compilerOptions": { 12 | // Until Prisma PDP modernizes its nextjs/webpack versions 13 | "target": "ES5", 14 | // Make the compiler stricter, catch more errors 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "noUncheckedIndexedAccess": true, 18 | "noImplicitOverride": true, 19 | // We handle these with ESLint: 20 | // "noUnusedLocals": false, 21 | // "noUnusedParameters": false, 22 | 23 | // Output 24 | "importHelpers": true, 25 | 26 | // DX 27 | "incremental": true, 28 | "tsBuildInfoFile": "node_modules/.cache/.tsbuildinfo", 29 | "noErrorTruncation": true, 30 | "baseUrl": ".", 31 | "paths": { 32 | "~/*": ["./src/*"] 33 | }, 34 | 35 | // Transformer Plugins made possible by https://github.com/nonara/ts-patch 36 | "plugins": [ 37 | // https://github.com/LeDDGroup/typescript-transform-paths 38 | { "transform": "typescript-transform-paths" }, 39 | { "transform": "typescript-transform-paths", "afterDeclarations": true } 40 | ] 41 | }, 42 | "include": ["src", "tests", "scripts", "jest.*"], 43 | // Prevent unwanted things like auto-import from built modules 44 | "exclude": ["dist-*"], 45 | "plugins": [ 46 | { 47 | "name": "typescript-snapshots-plugin" 48 | } 49 | ] 50 | } 51 | --------------------------------------------------------------------------------