diff --git a/package-lock.json b/package-lock.json index 6c3c867e..c44a3f50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "aws-xray-sdk-mysql": "file:packages/mysql", "aws-xray-sdk-node": "file:", "aws-xray-sdk-postgres": "file:packages/postgres", + "aws-xray-sdk-prisma": "file:sdk_contrib/prisma", "aws-xray-sdk-restify": "file:packages/restify", "test-aws-xray-sdk-express": "file:packages/test_express" }, @@ -67,7 +68,7 @@ "sinon": "^9.0.2", "sinon-chai": "^3.5.0", "tsd": "^0.25.0", - "typescript": "^4.4.4", + "typescript": "^4.9.5", "upath": "^1.2.0" }, "engines": { @@ -4214,6 +4215,10 @@ "resolved": "packages/postgres", "link": true }, + "node_modules/aws-xray-sdk-prisma": { + "resolved": "sdk_contrib/prisma", + "link": true + }, "node_modules/aws-xray-sdk-restify": { "resolved": "packages/restify", "link": true @@ -16212,9 +16217,9 @@ } }, "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -17086,6 +17091,61 @@ "aws-xray-sdk-core": "^3.5.2", "koa": "^2.0.0" } + }, + "sdk_contrib/prisma": { + "name": "@cosva-lab/aws-xray-sdk-prisma", + "version": "3.5.2", + "license": "Apache-2.0", + "devDependencies": { + "@prisma/client": "^5.4.2", + "eslint-plugin-promise": "^6.1.1" + }, + "engines": { + "node": ">= 16.x" + }, + "peerDependencies": { + "@prisma/client": "^4.0.0 || ^5.0.0", + "aws-xray-sdk-core": "^3.5.0" + } + }, + "sdk_contrib/prisma/node_modules/@prisma/client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.4.2.tgz", + "integrity": "sha512-2xsPaz4EaMKj1WS9iW6MlPhmbqtBsXAOeVttSePp8vTFTtvzh2hZbDgswwBdSCgPzmmwF+tLB259QzggvCmJqA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574" + }, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "sdk_contrib/prisma/node_modules/@prisma/engines-version": { + "version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574.tgz", + "integrity": "sha512-wvupDL4AA1vf4TQNANg7kR7y98ITqPsk6aacfBxZKtrJKRIsWjURHkZCGcQliHdqCiW/hGreO6d6ZuSv9MhdAA==", + "dev": true + }, + "sdk_contrib/prisma/node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } } }, "dependencies": { @@ -20555,6 +20615,7 @@ "aws-xray-sdk-mysql": "file:packages/mysql", "aws-xray-sdk-node": "file:", "aws-xray-sdk-postgres": "file:packages/postgres", + "aws-xray-sdk-prisma": "file:sdk_contrib/prisma", "aws-xray-sdk-restify": "file:packages/restify", "chai": "^4.2.0", "cls-hooked": "^4.2.2", @@ -20586,7 +20647,7 @@ "sinon-chai": "^3.5.0", "test-aws-xray-sdk-express": "file:packages/test_express", "tsd": "^0.25.0", - "typescript": "^4.4.4", + "typescript": "4", "upath": "^1.2.0" }, "dependencies": { @@ -24036,6 +24097,37 @@ "@types/pg": "*" } }, + "aws-xray-sdk-prisma": { + "version": "file:sdk_contrib/prisma", + "requires": { + "@prisma/client": "^5.4.2", + "eslint-plugin-promise": "^6.1.1" + }, + "dependencies": { + "@prisma/client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.4.2.tgz", + "integrity": "sha512-2xsPaz4EaMKj1WS9iW6MlPhmbqtBsXAOeVttSePp8vTFTtvzh2hZbDgswwBdSCgPzmmwF+tLB259QzggvCmJqA==", + "dev": true, + "requires": { + "@prisma/engines-version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574" + } + }, + "@prisma/engines-version": { + "version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574.tgz", + "integrity": "sha512-wvupDL4AA1vf4TQNANg7kR7y98ITqPsk6aacfBxZKtrJKRIsWjURHkZCGcQliHdqCiW/hGreO6d6ZuSv9MhdAA==", + "dev": true + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "requires": {} + } + } + }, "aws-xray-sdk-restify": { "version": "file:packages/restify", "requires": { @@ -33268,9 +33360,9 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "uc.micro": { @@ -33846,6 +33938,37 @@ "@types/pg": "*" } }, + "aws-xray-sdk-prisma": { + "version": "file:sdk_contrib/prisma", + "requires": { + "@prisma/client": "^5.4.2", + "eslint-plugin-promise": "^6.1.1" + }, + "dependencies": { + "@prisma/client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.4.2.tgz", + "integrity": "sha512-2xsPaz4EaMKj1WS9iW6MlPhmbqtBsXAOeVttSePp8vTFTtvzh2hZbDgswwBdSCgPzmmwF+tLB259QzggvCmJqA==", + "dev": true, + "requires": { + "@prisma/engines-version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574" + } + }, + "@prisma/engines-version": { + "version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574.tgz", + "integrity": "sha512-wvupDL4AA1vf4TQNANg7kR7y98ITqPsk6aacfBxZKtrJKRIsWjURHkZCGcQliHdqCiW/hGreO6d6ZuSv9MhdAA==", + "dev": true + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "requires": {} + } + } + }, "aws-xray-sdk-restify": { "version": "file:packages/restify", "requires": { @@ -43078,9 +43201,9 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "uc.micro": { diff --git a/package.json b/package.json index 0a3944a5..c59b1b76 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "sinon": "^9.0.2", "sinon-chai": "^3.5.0", "tsd": "^0.25.0", - "typescript": "^4.4.4", + "typescript": "^4.9.5", "upath": "^1.2.0" }, "engines": { @@ -71,6 +71,7 @@ "aws-xray-sdk-mysql": "file:packages/mysql", "aws-xray-sdk-node": "file:", "aws-xray-sdk-postgres": "file:packages/postgres", + "aws-xray-sdk-prisma": "file:sdk_contrib/prisma", "aws-xray-sdk-restify": "file:packages/restify", "test-aws-xray-sdk-express": "file:packages/test_express" } diff --git a/sdk_contrib/prisma/.eslintrc.json b/sdk_contrib/prisma/.eslintrc.json new file mode 100644 index 00000000..7a9f7314 --- /dev/null +++ b/sdk_contrib/prisma/.eslintrc.json @@ -0,0 +1,4 @@ +{ + "extends": "../../.eslintrc.json", + "plugins": ["promise"] +} diff --git a/sdk_contrib/prisma/.gitignore b/sdk_contrib/prisma/.gitignore new file mode 100644 index 00000000..0df55fc5 --- /dev/null +++ b/sdk_contrib/prisma/.gitignore @@ -0,0 +1 @@ +dev.db diff --git a/sdk_contrib/prisma/LICENSE b/sdk_contrib/prisma/LICENSE new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/sdk_contrib/prisma/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/sdk_contrib/prisma/NOTICE.txt b/sdk_contrib/prisma/NOTICE.txt new file mode 100644 index 00000000..75a4459c --- /dev/null +++ b/sdk_contrib/prisma/NOTICE.txt @@ -0,0 +1,5 @@ +AWS X-Ray SDK Prisma for JavaScript +Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +This product includes software developed at +Amazon Web Services, Inc. (http://aws.amazon.com/). diff --git a/sdk_contrib/prisma/README.md b/sdk_contrib/prisma/README.md new file mode 100644 index 00000000..76d7cf94 --- /dev/null +++ b/sdk_contrib/prisma/README.md @@ -0,0 +1,111 @@ +# Prisma-xray + +A prisma plugin to log requests and subsegments through AWSXray. + +![Screenshot of the AWS X-Ray console](/sdk_contrib/prisma/images/servicemap.png?raw=true) + +## Timeline + +![Screenshot of the AWS X-Ray console](/sdk_contrib/prisma/images/timeline.png?raw=true) + +## Requirements + +- AWS X-Ray SDK Core +- Prisma 4 or greater + +## AWS X-Ray and Prisma + +The AWS X-Ray Prisma package automatically records query information and request +and response data. Simply patch the Prisma package via `capturePrisma` as shown below. + +The AWS X-Ray SDK Core has two modes - `manual` and `automatic`. +Automatic mode uses the `cls-hooked` package and automatically +tracks the current segment and subsegment. This is the default mode. +Manual mode requires that you pass around the segment reference. See the examples below. + +## Automatic mode examples + +![Screenshot of the AWS X-Ray console](/sdk_contrib/prisma/images/auto.png?raw=true) + +```js +import { PrismaClient } from '@prisma/client'; +import AWSXRay from 'aws-xray-sdk'; +import { capturePrisma } from 'aws-xray-sdk-prisma'; + +const ns = AWSXRay.getNamespace(); + +const prisma = new PrismaClient(); + +const client = capturePrisma(prisma, { namespace: 'remote' }); + +const segment = new AWSXRay.Segment('prisma-xray-sample-auto'); + +ns.run(async () => { + const subSegment = segment.addNewSubsegment('Prisma'); + AWSXRay.setSegment(subSegment); + await client.company.upsert({ + create: { + name: 'Prisma', + createdAt: new Date(), + }, + update: {}, + where: { + id: 1, + }, + }); + const companies = await client.company.findMany(); + console.log(companies); + subSegment.close(); + // ... +}); +``` + +## Manual mode examples + +![Screenshot of the AWS X-Ray console](/sdk_contrib/prisma/images/manual.png?raw=true) + +```js +import { PrismaClient } from '@prisma/client'; +import AWSXRay from 'aws-xray-sdk-core'; +import { capturePrisma } from 'aws-xray-sdk-prisma'; + +AWSXRay.enableManualMode(); + +const prisma = new PrismaClient(); + +const client = capturePrisma(prisma, { namespace: 'remote' }); + +const segment = new AWSXRay.Segment('prisma-xray-sample'); + +const run = async () => { + const subSegment = segment.addNewSubsegment('Prisma'); + + await client.company.upsert( + { + create: { + name: 'Prisma', + createdAt: new Date(), + }, + update: {}, + where: { + id: 1, + }, + }, + // @ts-ignore + subSegment + ); + const companies = await client.company.findMany( + // @ts-ignore + subSegment + ); + console.log(companies); + subSegment.close(); + // ... +}; + +run(); +``` + +# Contributors + +- Eduard Castellanos , diff --git a/sdk_contrib/prisma/images/auto.png b/sdk_contrib/prisma/images/auto.png new file mode 100644 index 00000000..724231d7 Binary files /dev/null and b/sdk_contrib/prisma/images/auto.png differ diff --git a/sdk_contrib/prisma/images/manual.png b/sdk_contrib/prisma/images/manual.png new file mode 100644 index 00000000..fed57991 Binary files /dev/null and b/sdk_contrib/prisma/images/manual.png differ diff --git a/sdk_contrib/prisma/images/servicemap.png b/sdk_contrib/prisma/images/servicemap.png new file mode 100644 index 00000000..b6094aa9 Binary files /dev/null and b/sdk_contrib/prisma/images/servicemap.png differ diff --git a/sdk_contrib/prisma/images/timeline.png b/sdk_contrib/prisma/images/timeline.png new file mode 100644 index 00000000..44daf7aa Binary files /dev/null and b/sdk_contrib/prisma/images/timeline.png differ diff --git a/sdk_contrib/prisma/package-lock.json b/sdk_contrib/prisma/package-lock.json new file mode 100644 index 00000000..b8a7d484 --- /dev/null +++ b/sdk_contrib/prisma/package-lock.json @@ -0,0 +1,1411 @@ +{ + "name": "aws-xray-sdk-prisma", + "version": "3.5.2", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aws-xray-sdk-prisma", + "version": "3.5.2", + "license": "Apache-2.0", + "devDependencies": { + "@prisma/client": "^5.4.2", + "eslint-plugin-promise": "^6.1.1" + }, + "engines": { + "node": ">= 16.x" + }, + "peerDependencies": { + "@prisma/client": "^4.0.0 || ^5.0.0", + "aws-xray-sdk-core": "^3.5.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@aws-sdk/service-error-classification": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", + "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", + "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", + "peer": true, + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true, + "peer": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@prisma/client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.4.2.tgz", + "integrity": "sha512-2xsPaz4EaMKj1WS9iW6MlPhmbqtBsXAOeVttSePp8vTFTtvzh2hZbDgswwBdSCgPzmmwF+tLB259QzggvCmJqA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574" + }, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.4.1-2.ac9d7041ed77bcc8a8dbd2ab6616b39013829574.tgz", + "integrity": "sha512-wvupDL4AA1vf4TQNANg7kR7y98ITqPsk6aacfBxZKtrJKRIsWjURHkZCGcQliHdqCiW/hGreO6d6ZuSv9MhdAA==", + "dev": true + }, + "node_modules/@types/cls-hooked": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.4.tgz", + "integrity": "sha512-IBarK4du6E+0vRg7Pt33RtbhvtmXIO1Jfwd825/RbGBEBR0uzUjPBRvYsQ9MWYmRq/mkWSesytux8aHZXi6kyw==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "dev": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "node_modules/async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "peer": true, + "dependencies": { + "stack-chain": "^1.3.7" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3" + } + }, + "node_modules/atomic-batcher": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/atomic-batcher/-/atomic-batcher-1.0.2.tgz", + "integrity": "sha512-EFGCRj4kLX1dHv1cDzTk+xbjBFj1GnJDpui52YmEcxxHHEWjYyT6l51U7n6WQ28osZH4S9gSybxe56Vm7vB61Q==", + "peer": true + }, + "node_modules/aws-xray-sdk-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/aws-xray-sdk-core/-/aws-xray-sdk-core-3.5.0.tgz", + "integrity": "sha512-T3mL9mGwnfGyZrf7RsZp702+prTCEMzX7zrqD7flwMZeb6ymXlSgREmeXys80r/9CHFgq/+JR+IclM+hep0yRw==", + "peer": true, + "dependencies": { + "@aws-sdk/service-error-classification": "^3.4.1", + "@aws-sdk/types": "^3.4.1", + "@types/cls-hooked": "^4.3.3", + "atomic-batcher": "^1.0.2", + "cls-hooked": "^4.2.2", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 14.x" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "peer": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", + "peer": true, + "dependencies": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" + } + }, + "node_modules/cls-hooked/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "peer": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "peer": true, + "dependencies": { + "shimmer": "^1.2.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "dev": true, + "peer": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "peer": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "peer": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "peer": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "peer": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true, + "peer": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "peer": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "peer": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "peer": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "peer": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "peer": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "peer": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "peer": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "peer": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "peer": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "peer": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "peer": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "peer": true + }, + "node_modules/stack-chain": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==", + "peer": true + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "peer": true + }, + "node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "peer": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "peer": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/sdk_contrib/prisma/package.json b/sdk_contrib/prisma/package.json new file mode 100644 index 00000000..63041d3f --- /dev/null +++ b/sdk_contrib/prisma/package.json @@ -0,0 +1,50 @@ +{ + "name": "aws-xray-sdk-prisma", + "version": "3.5.2", + "description": "AWS X-Ray Patcher for prisma (Javascript)", + "author": "Cosva", + "contributors": [ + "Eduard Castellanos " + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "engines": { + "node": ">= 16.x" + }, + "directories": { + "test": "test" + }, + "peerDependencies": { + "@prisma/client": "^4.0.0 || ^5.0.0", + "aws-xray-sdk-core": "^3.5.0" + }, + "scripts": { + "test": "mocha --recursive ./test/ -R spec && tsd", + "test-d": "tsd", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "keywords": [ + "amazon", + "api", + "aws", + "prisma", + "xray", + "x-ray", + "x ray" + ], + "license": "Apache-2.0", + "repository": "https://github.com/aws/aws-xray-sdk-node/tree/master/packages/prisma", + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@prisma/client": "^5.4.2", + "eslint-plugin-promise": "^6.1.1" + } +} \ No newline at end of file diff --git a/sdk_contrib/prisma/samples/README.MD b/sdk_contrib/prisma/samples/README.MD new file mode 100644 index 00000000..21f8822f --- /dev/null +++ b/sdk_contrib/prisma/samples/README.MD @@ -0,0 +1,24 @@ +# Prisma X-Ray SDK + +To run this example locally, you need run the following commands: + +```sh +npm install +npm run generate +``` + +## Automatic mode example + +For run this example, you run the following command: + +```sh +npm run auto +``` + +## Manual mode example + +For run this example, you run the following command: + +```sh +npm run manual +``` diff --git a/sdk_contrib/prisma/samples/auto/simple.js b/sdk_contrib/prisma/samples/auto/simple.js new file mode 100644 index 00000000..c414ac99 --- /dev/null +++ b/sdk_contrib/prisma/samples/auto/simple.js @@ -0,0 +1,36 @@ +const { PrismaClient } = require('@prisma/client'); +const awsXray = require('aws-xray-sdk-core'); +const { capturePrisma } = require('aws-xray-sdk-prisma'); + +awsXray.enableAutomaticMode(); + +const prisma = new PrismaClient(); + +const client = capturePrisma(prisma, { namespace: 'remote' }); +const ns = awsXray.getNamespace(); + +const segment = new awsXray.Segment('prisma-xray-sample-auto'); + +ns.run(async () => { + const subSegment = segment.addNewSubsegment('Prisma'); + awsXray.setSegment(subSegment); + await client.company.upsert({ + create: { + name: 'Prisma', + createdAt: new Date(), + }, + update: {}, + where: { + id: 1, + }, + }); + const companies = await client.company.findMany(); + console.log(companies); + subSegment.close(); + const timeout = segment.addNewSubsegment('timeout'); + setTimeout(() => { + timeout.close(); + segment.close(); + }, 1000); + prisma.$disconnect(); +}); diff --git a/sdk_contrib/prisma/samples/manual/simple.js b/sdk_contrib/prisma/samples/manual/simple.js new file mode 100644 index 00000000..21fc83b9 --- /dev/null +++ b/sdk_contrib/prisma/samples/manual/simple.js @@ -0,0 +1,44 @@ +const { PrismaClient } = require('@prisma/client'); +const awsXray = require('aws-xray-sdk-core'); +const { capturePrisma } = require('aws-xray-sdk-prisma'); + +awsXray.enableManualMode(); + +const prisma = new PrismaClient(); + +const client = capturePrisma(prisma, { namespace: 'remote' }); + +const segment = new awsXray.Segment('prisma-xray-sample'); + +const run = async () => { + const subSegment = segment.addNewSubsegment('Prisma'); + + await client.company.upsert( + { + create: { + name: 'Prisma', + createdAt: new Date(), + }, + update: {}, + where: { + id: 1, + }, + }, + // @ts-ignore + subSegment + ); + const companies = await client.company.findMany( + // @ts-ignore + subSegment + ); + console.log(companies); + subSegment.close(); + const timeout = segment.addNewSubsegment('timeout'); + setTimeout(() => { + timeout.close(); + segment.close(); + }, 1000); + prisma.$disconnect(); +}; + +run(); diff --git a/sdk_contrib/prisma/samples/package-lock.json b/sdk_contrib/prisma/samples/package-lock.json new file mode 100644 index 00000000..415bc4e4 --- /dev/null +++ b/sdk_contrib/prisma/samples/package-lock.json @@ -0,0 +1,87 @@ +{ + "name": "aws-xray-sdk-prisma-samples", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aws-xray-sdk-prisma-samples", + "version": "1.0.0", + "dependencies": { + "@prisma/client": "^4.15.0", + "aws-xray-sdk-prisma": "file:.." + }, + "devDependencies": { + "prisma": "^4.15.0" + } + }, + "..": { + "name": "aws-xray-sdk-prisma", + "version": "3.5.0", + "license": "Apache-2.0", + "devDependencies": { + "@prisma/client": "^4.15.0" + }, + "engines": { + "node": ">= 14.x" + }, + "peerDependencies": { + "@prisma/client": "^4.0.0", + "aws-xray-sdk-core": "^3.5.0" + } + }, + "node_modules/@prisma/client": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.15.0.tgz", + "integrity": "sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.15.0.tgz", + "integrity": "sha512-FTaOCGs0LL0OW68juZlGxFtYviZa4xdQj/rQEdat2txw0s3Vu/saAPKjNVXfIgUsGXmQ72HPgNr6935/P8FNAA==", + "devOptional": true, + "hasInstallScript": true + }, + "node_modules/@prisma/engines-version": { + "version": "4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944.tgz", + "integrity": "sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==" + }, + "node_modules/aws-xray-sdk-prisma": { + "resolved": "..", + "link": true + }, + "node_modules/prisma": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.15.0.tgz", + "integrity": "sha512-iKZZpobPl48gTcSZVawLMQ3lEy6BnXwtoMj7hluoGFYu2kQ6F9LBuBrUyF95zRVnNo8/3KzLXJXJ5TEnLSJFiA==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "4.15.0" + }, + "bin": { + "prisma": "build/index.js", + "prisma2": "build/index.js" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/sdk_contrib/prisma/samples/package.json b/sdk_contrib/prisma/samples/package.json new file mode 100644 index 00000000..f00e19e5 --- /dev/null +++ b/sdk_contrib/prisma/samples/package.json @@ -0,0 +1,21 @@ +{ + "name": "aws-xray-sdk-prisma-samples", + "version": "1.0.0", + "description": "AWS X-Ray samples", + "author": "Eduard Castellanos", + "scripts": { + "generate": "prisma generate", + "auto": "node auto/simple.js", + "manual": "node manual/simple.js" + }, + "prisma": { + "schema": "prisma/schema.prisma" + }, + "devDependencies": { + "prisma": "^4.15.0" + }, + "dependencies": { + "@prisma/client": "^4.15.0", + "aws-xray-sdk-prisma": "file:.." + } +} \ No newline at end of file diff --git a/sdk_contrib/prisma/samples/prisma/schema.prisma b/sdk_contrib/prisma/samples/prisma/schema.prisma new file mode 100644 index 00000000..67e3d7c0 --- /dev/null +++ b/sdk_contrib/prisma/samples/prisma/schema.prisma @@ -0,0 +1,16 @@ +generator client { + provider = "prisma-client-js" + engineType = "binary" +} + +datasource db { + provider = "sqlite" + url = "file:dev.db" +} + +model Company { + id Int @id @default(autoincrement()) + name String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/sdk_contrib/prisma/src/captureActions.ts b/sdk_contrib/prisma/src/captureActions.ts new file mode 100644 index 00000000..aee5d389 --- /dev/null +++ b/sdk_contrib/prisma/src/captureActions.ts @@ -0,0 +1,84 @@ +import AWSXRay, { Segment, Subsegment } from 'aws-xray-sdk-core'; +import { isPrismaPromise } from './utils'; +import { DIVIDER, MODEL_PREFIX } from './constants'; +import { CommonOpts } from './types'; +import { captureFluid } from './captureFluid'; + +interface ActionsOptions extends CommonOpts { + modelKey: string; + action: string; +} +export function captureActions( + attr: any, + obj: any, + { + segment: baseSegment, + action, + namespace, + modelKey, + modelPrefix = MODEL_PREFIX, + divider = DIVIDER, + }: ActionsOptions +) { + return (...args: any[]): any => { + let segment = baseSegment; + const lastArg: Subsegment | null = args[args.length - 1]; + + if (AWSXRay.isAutomaticMode()) { + segment = AWSXRay.getSegment(); + } + if (lastArg instanceof Segment || lastArg instanceof Subsegment) { + args = args.slice(0, -1); + segment = lastArg; + } + + const call = () => attr.bind(obj)(...args); + if (!segment) { + return call(); + } + + const model = [modelPrefix, modelKey].filter(Boolean).join(divider); + const actionSegment = segment.addNewSubsegment( + [model, action].join(divider) + ); + actionSegment.namespace = namespace; + const res = call(); + const isPromise = isPrismaPromise(res); + const promises: Promise[] = []; + if (res instanceof Promise || isPromise) { + promises.push( + res.catch(e => { + actionSegment.addError(e); + }) + ); + } + + const close = async () => { + if (promises.length) { + for (const promise of promises) { + await new Promise(resolve => { + promise.finally(() => resolve()); + }); + } + } + actionSegment?.close(); + }; + + if (isPromise) { + const promiseFluid = captureFluid(res, { + callback: promise => { + promise && promises.push(promise); + close(); + }, + divider, + modelPrefix, + namespace, + segment: actionSegment, + model, + }); + return promiseFluid; + } + close(); + return res; + }; +} diff --git a/sdk_contrib/prisma/src/captureFluid.ts b/sdk_contrib/prisma/src/captureFluid.ts new file mode 100644 index 00000000..fb80e806 --- /dev/null +++ b/sdk_contrib/prisma/src/captureFluid.ts @@ -0,0 +1,51 @@ +import { isPrismaPromise } from './utils'; +import { prismaPromiseAttributes } from './constants'; +import { PrismaPromise, CaptureFluidOpts } from './types'; + +export function captureFluid( + promise: PrismaPromise, + { segment, model, callback, namespace, divider }: CaptureFluidOpts) { + return new Proxy(promise, { + get(obj, key) { + const attr = obj[key as keyof PrismaPromise]; + const actionKey = key.toString(); + + if (!prismaPromiseAttributes.has(actionKey) && + typeof attr === 'function') { + return (...args: any[]) => { + const res = attr.bind(obj)(...args); + const isPromise = isPrismaPromise(res); + + if (res instanceof Promise || isPromise) { + promise.then(() => { + try { + const actionSegment = segment.addNewSubsegment( + [model, actionKey].join(divider) + ); + actionSegment.namespace = namespace; + + res.catch(e => { + actionSegment.addError(e); + }); + + res.finally(() => { + actionSegment.close(); + }); + } catch (e) { + console.error(e); + } finally { + callback?.(res); + } + }); + } else { + callback?.(); + } + return res; + }; + } + callback?.(); + + return attr; + }, + }); +} diff --git a/sdk_contrib/prisma/src/captureModels.ts b/sdk_contrib/prisma/src/captureModels.ts new file mode 100644 index 00000000..0619951f --- /dev/null +++ b/sdk_contrib/prisma/src/captureModels.ts @@ -0,0 +1,38 @@ +import AWSXRay from 'aws-xray-sdk-core'; +import { isAction } from './utils'; +import { CommonOpts } from './types'; +import { captureActions } from './captureActions'; + +export function captureModels( + attr: Record, + modelKey: string, + { segment, ...rest }: CommonOpts +) { + if (AWSXRay.isAutomaticMode()) { + segment = AWSXRay.resolveSegment(segment); + } + + if (typeof attr !== 'object') { + return attr; + } + + return new Proxy(attr, { + get(obj, prop) { + const key = prop.toString(); + const attr = obj[key]; + if (isAction(key)) { + if (AWSXRay.isAutomaticMode() && segment) { + AWSXRay.setSegment(segment); + } + + return captureActions(attr, obj, { + segment, + modelKey, + action: key, + ...rest, + }); + } + return attr; + }, + }); +} diff --git a/sdk_contrib/prisma/src/capturePrisma.ts b/sdk_contrib/prisma/src/capturePrisma.ts new file mode 100644 index 00000000..07a0b0d2 --- /dev/null +++ b/sdk_contrib/prisma/src/capturePrisma.ts @@ -0,0 +1,57 @@ +import AWSXRay, { Segment, Subsegment } from 'aws-xray-sdk-core'; + +import { PrismaClient, CommonOpts } from './types'; +import { captureModels } from './captureModels'; + +export function capturePrisma( + prisma: T, + opts?: CommonOpts +): T { + let segment: Segment | Subsegment | undefined; + const { segment: baseSegment, ...rest } = { ...opts }; + if (!baseSegment) { + try { + segment = AWSXRay.resolveSegment(baseSegment); + } catch { + // ignore + } + } else { + segment = baseSegment; + } + if (AWSXRay.isAutomaticMode()) { + const ns = AWSXRay.getNamespace(); + return ns.runAndReturn(() => { + if (segment) { + AWSXRay.setSegment(segment); + } + return new Proxy(prisma, { + get(obj, modelKey): any { + const attr = obj[modelKey as keyof T]; + return ns.runAndReturn(() => { + if (segment) { + AWSXRay.setSegment(segment); + } + return captureModels(attr, modelKey.toString(), { + segment, + ...rest, + }); + }); + }, + }); + }); + } + + if (!segment) { + console.error('No segment provided when is manual mode'); + } + + return new Proxy(prisma, { + get(obj, modelKey): any { + const attr = obj[modelKey as keyof T]; + return captureModels(attr, modelKey.toString(), { + segment, + ...rest, + }); + }, + }); +} diff --git a/sdk_contrib/prisma/src/constants.ts b/sdk_contrib/prisma/src/constants.ts new file mode 100644 index 00000000..96674c49 --- /dev/null +++ b/sdk_contrib/prisma/src/constants.ts @@ -0,0 +1,9 @@ +export const prismaPromiseAttributes = new Set([ + 'then', + 'catch', + 'finally', + 'requestTransaction', +]); + +export const MODEL_PREFIX = null; +export const DIVIDER = '.'; diff --git a/sdk_contrib/prisma/src/index.ts b/sdk_contrib/prisma/src/index.ts new file mode 100644 index 00000000..1ea76783 --- /dev/null +++ b/sdk_contrib/prisma/src/index.ts @@ -0,0 +1,2 @@ +export * from './capturePrisma'; +export { CaptureFluidOpts, CommonOpts } from './types'; diff --git a/sdk_contrib/prisma/src/types.ts b/sdk_contrib/prisma/src/types.ts new file mode 100644 index 00000000..7161aa85 --- /dev/null +++ b/sdk_contrib/prisma/src/types.ts @@ -0,0 +1,21 @@ +import { Segment, Subsegment } from 'aws-xray-sdk-core'; + +declare const prisma: unique symbol; +export type PrismaPromise = Promise & { [prisma]: true } & { + [key: string]: (...args: any[]) => PrismaPromise; +}; + +export type PrismaClient = Record; + +export interface CommonOpts { + segment?: Segment | Subsegment; + namespace?: string; + modelPrefix?: string | null; + divider?: string; +} + +export interface CaptureFluidOpts extends CommonOpts { + segment: Subsegment; + model: string; + callback?: (promise?: Promise) => void; +} diff --git a/sdk_contrib/prisma/src/utils.ts b/sdk_contrib/prisma/src/utils.ts new file mode 100644 index 00000000..54cce696 --- /dev/null +++ b/sdk_contrib/prisma/src/utils.ts @@ -0,0 +1,9 @@ +import { DMMF } from '@prisma/client/runtime/binary'; +import { PrismaPromise } from './types'; + +const { ModelAction } = DMMF; + +export const isAction = (action: any): action is keyof typeof ModelAction => + !!ModelAction[action as keyof typeof ModelAction]; +export const isPrismaPromise = (res?: any): res is PrismaPromise => + res?.[Symbol.toStringTag] === 'PrismaPromise'; diff --git a/sdk_contrib/prisma/test-d/index.test-d.ts.js b/sdk_contrib/prisma/test-d/index.test-d.ts.js new file mode 100644 index 00000000..2ee966e2 --- /dev/null +++ b/sdk_contrib/prisma/test-d/index.test-d.ts.js @@ -0,0 +1,9 @@ +import { PrismaClient } from '@prisma/client'; +import { expectType } from 'tsd'; +import { capturePrisma } from '../dist'; + +const prisma = new PrismaClient(); + +const client = capturePrisma(prisma); + +expectType < PrismaClient > client; diff --git a/sdk_contrib/prisma/test/.eslintrc b/sdk_contrib/prisma/test/.eslintrc new file mode 100644 index 00000000..bc5b8bf6 --- /dev/null +++ b/sdk_contrib/prisma/test/.eslintrc @@ -0,0 +1,6 @@ +{ + "env": { + "mocha": true + }, + "extends": ["plugin:mocha/recommended"] +} diff --git a/sdk_contrib/prisma/test/unit/prisma.test.js b/sdk_contrib/prisma/test/unit/prisma.test.js new file mode 100644 index 00000000..1ce643fc --- /dev/null +++ b/sdk_contrib/prisma/test/unit/prisma.test.js @@ -0,0 +1,229 @@ +const xray = require('aws-xray-sdk-core'); +const assert = require('chai').assert; +const chai = require('chai'); +const sinon = require('sinon'); +const sinonChai = require('sinon-chai'); + +const { capturePrisma } = require('../../dist'); + +const Segment = xray.Segment; + +chai.should(); +chai.use(sinonChai); + +describe('Prisma', function () { + let prisma; + + beforeEach(function () { + prisma = { + $connect: sinon.stub(), + $disconnect: sinon.stub(), + $on: sinon.stub(), + $transaction: sinon.stub(), + $use: sinon.stub(), + $executeRaw: sinon.stub(), + $queryRaw: sinon.stub(), + $queryRawUnsafe: sinon.stub(), + $exists: sinon.stub(), + company: { + create: sinon.stub(), + findMany: sinon.stub(), + }, + }; + }); + + describe('capturePrisma', function () { + var client, sandbox, segment; + beforeEach(function () { + xray.enableManualMode(); + + segment = new Segment('test'); + client = capturePrisma(prisma, { + segment, + }); + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + xray.enableAutomaticMode(); + sandbox.restore(); + }); + + it('should return a prisma client', function () { + assert.isObject(client); + }); + + it('should return a prisma client with a $connect method', function () { + assert.isFunction(client.$connect); + }); + }); + + describe('capturePrisma with automatic mode', function () { + var client, segment, sandbox; + beforeEach(function () { + xray.enableAutomaticMode(); + client = capturePrisma(prisma); + segment = new Segment('test'); + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + xray.enableManualMode(); + sandbox.restore(); + }); + + it('Segment should be set', function () { + const ns = xray.getNamespace(); + ns.run(() => { + xray.setSegment(segment); + client.$connect(); + assert.isTrue(prisma.$connect.calledOnce); + assert.isTrue(prisma.$connect.calledWithExactly()); + }); + }); + + it('Segment should not be set', function () { + const ns = xray.getNamespace(); + const error = sinon.stub(); + const logger = xray.getLogger(); + logger.error = error; + ns.run(async () => { + client.company.create(); + assert.isTrue(error.calledOnce); + }); + }); + + it('Segment is called with correct arguments', function () { + const ns = xray.getNamespace(); + ns.run(() => { + xray.setSegment(segment); + const data = { + data: { + name: 'test', + }, + }; + client.company.create(data); + assert.isTrue(prisma.company.create.calledOnce); + assert.isTrue(prisma.company.create.calledWithExactly(data)); + }); + }); + + it('Segment have one subsegment', function () { + const ns = xray.getNamespace(); + ns.run(() => { + xray.setSegment(segment); + client.company.create(); + assert.equal(segment.subsegments.length, 1); + assert.equal(segment.subsegments[0].name, 'company.create'); + }); + }); + + it('Segment have two subsegments', function () { + const ns = xray.getNamespace(); + ns.run(() => { + xray.setSegment(segment); + client.company.create(); + assert.equal(segment.subsegments.length, 1); + client.company.findMany(); + assert.equal(segment.subsegments.length, 2); + assert.equal(segment.subsegments[0].name, 'company.create'); + assert.equal(segment.subsegments[1].name, 'company.findMany'); + }); + }); + }); + + describe('capturePrisma with manual mode', function () { + var client, segment, sandbox; + beforeEach(function () { + xray.enableManualMode(); + segment = new Segment('test'); + client = capturePrisma(prisma, { + segment, + }); + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + xray.enableManualMode(); + sandbox.restore(); + }); + + it('Segment is optional', function () { + client.company.create(); + assert.isTrue(prisma.company.create.calledOnce); + assert.isTrue(prisma.company.create.calledWithExactly()); + }); + + it('Segment is deleted', function () { + client.company.create(segment); + assert.isTrue(prisma.company.create.calledOnce); + assert.isTrue(prisma.company.create.calledWithExactly()); + }); + + it('Segment is called with correct arguments', function () { + const data = { + data: { + name: 'test', + }, + }; + client.company.create(data, segment); + assert.isTrue(prisma.company.create.calledOnce); + assert.isTrue(prisma.company.create.calledWithExactly(data)); + }); + + it('Segment have one subsegment', function () { + client.company.create(segment); + assert.equal(segment.subsegments.length, 1); + }); + + it('Segment have two subsegments', function () { + client.company.create(segment); + assert.equal(segment.subsegments.length, 1); + client.company.findMany(segment); + assert.equal(segment.subsegments.length, 2); + }); + }); + + describe('capturePrisma with manual mode and subsegment', function () { + var client, segment, subsegment, sandbox; + beforeEach(function () { + xray.enableManualMode(); + segment = new Segment('test'); + client = capturePrisma(prisma, { segment }); + subsegment = segment.addNewSubsegment('test'); + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + xray.enableManualMode(); + sandbox.restore(); + }); + + it('Subsegment is called with correct arguments', function () { + const data = { + data: { + name: 'test', + }, + }; + client.company.create(data, subsegment); + assert.isTrue(prisma.company.create.calledOnce); + assert.isTrue(prisma.company.create.calledWithExactly(data)); + }); + + it('Subsegment have one subsegment', function () { + client.company.create(subsegment); + assert.equal(segment.subsegments.length, 1); + }); + + it('Subsegment have two subsegments', function () { + client.company.create(subsegment); + assert.equal(segment.subsegments.length, 1); + client.company.findMany(subsegment); + assert.equal(segment.subsegments.length, 1); + }); + + it('Segment have one subsegment', function () { + assert.equal(segment.subsegments.length, 1); + }); + }); +}); diff --git a/sdk_contrib/prisma/tsconfig.json b/sdk_contrib/prisma/tsconfig.json new file mode 100644 index 00000000..6a082190 --- /dev/null +++ b/sdk_contrib/prisma/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2019", + "strict": true, + "strictNullChecks": true, + "declaration": true, + "esModuleInterop": true, + "skipLibCheck": true, + "allowJs": true, + "checkJs": false, + "outDir": "dist" + }, + "include": ["src"], + "exclude": ["dist", "node_modules"] +}