diff --git a/firestore-bigquery-export/CHANGELOG.md b/firestore-bigquery-export/CHANGELOG.md index 78cb72f8d..baae95d21 100644 --- a/firestore-bigquery-export/CHANGELOG.md +++ b/firestore-bigquery-export/CHANGELOG.md @@ -1,6 +1,12 @@ +## Version 0.1.59 + +docs - remove references to lifecycle backfill feature. + +docs - correct typo in maximum dispatches per second. + ## Version 0.1.58 -feat - move to Node.js 20 runtimes +feat - move to Node.js 20 runtimes. ## Version 0.1.57 diff --git a/firestore-bigquery-export/POSTINSTALL.md b/firestore-bigquery-export/POSTINSTALL.md index aba3d19b1..ebe9b9b12 100644 --- a/firestore-bigquery-export/POSTINSTALL.md +++ b/firestore-bigquery-export/POSTINSTALL.md @@ -101,14 +101,12 @@ For PowerShell script: ### _(Optional)_ Import existing documents -If you chose _not_ to automatically import existing documents when you installed this extension, you can backfill your BigQuery dataset with all the documents in your collection using the import script. +You can backfill your BigQuery dataset with all the documents in your collection using the import script. -If you don't either enable automatic import or run the import script, the extension only exports the content of documents that are created or changed after installation. +If you don't run the import script, the extension only exports the content of documents that are created or changed after installation. The import script can read all existing documents in a Cloud Firestore collection and insert them into the raw changelog table created by this extension. The script adds a special changelog for each document with the operation of `IMPORT` and the timestamp of epoch. This is to ensure that any operation on an imported document supersedes the `IMPORT`. -**Warning:** Make sure to not run the import script if you enabled automatic backfill during the extension installation, as it might result in data loss. - **Important:** Run the import script over the entire collection _after_ installing this extension, otherwise all writes to your database during the import might be lost. Learn more about using the import script to [backfill your existing collection](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md). diff --git a/firestore-bigquery-export/PREINSTALL.md b/firestore-bigquery-export/PREINSTALL.md index 6fcf0076d..f921378c5 100644 --- a/firestore-bigquery-export/PREINSTALL.md +++ b/firestore-bigquery-export/PREINSTALL.md @@ -37,15 +37,11 @@ Before installing this extension, you'll need to: #### Import existing documents -There are two ways to import existing Firestore documents into BigQuery - the backfill feature and the import script. - -To import documents that already exist at installation time into BigQuery, answer **Yes** when the installer asks "Import existing Firestore documents into BigQuery?" The extension will export existing documents as part of the installation and update processes. - -Alternatively, you can run the external [import script](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md) to backfill existing documents. If you plan to use this script, answer **No** when prompted to import existing documents. +To import existing documents you can run the external [import script](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md). **Important:** Run the external import script over the entire collection _after_ installing this extension, otherwise all writes to your database during the import might be lost. -If you don't either enable automatic import or run the import script, the extension only exports the content of documents that are created or changed after installation. +Without use of this import script, the extension only exports the content of documents that are created or changed after installation. #### Transform function diff --git a/firestore-bigquery-export/README.md b/firestore-bigquery-export/README.md index 03ca73e61..088e59bdb 100644 --- a/firestore-bigquery-export/README.md +++ b/firestore-bigquery-export/README.md @@ -45,15 +45,11 @@ Before installing this extension, you'll need to: #### Import existing documents -There are two ways to import existing Firestore documents into BigQuery - the backfill feature and the import script. - -To import documents that already exist at installation time into BigQuery, answer **Yes** when the installer asks "Import existing Firestore documents into BigQuery?" The extension will export existing documents as part of the installation and update processes. - -Alternatively, you can run the external [import script](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md) to backfill existing documents. If you plan to use this script, answer **No** when prompted to import existing documents. +To import existing documents you can run the external [import script](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md). **Important:** Run the external import script over the entire collection _after_ installing this extension, otherwise all writes to your database during the import might be lost. -If you don't either enable automatic import or run the import script, the extension only exports the content of documents that are created or changed after installation. +Without use of this import script, the extension only exports the content of documents that are created or changed after installation. #### Transform function @@ -281,7 +277,7 @@ essential for the script to insert data into an already partitioned table.) Note: Cluster columns must be top-level, non-repeated columns of one of the following types: BIGNUMERIC, BOOL, DATE, DATETIME, GEOGRAPHY, INT64, NUMERIC, RANGE, STRING, TIMESTAMP. Clustering will not be added if a field with an invalid type is present in this parameter. Available schema extensions table fields for clustering include: `document_id, document_name, timestamp, event_id, operation, data`. -* Maximum number of synced documents per second: This parameter will set the maximum number of syncronised documents per second with BQ. Please note, any other external updates to a Big Query table will be included within this quota. Ensure that you have a set a low enough number to compensate. Defaults to 10. +* Maximum number of synced documents per second: This parameter will set the maximum number of syncronised documents per second with BQ. Please note, any other external updates to a Big Query table will be included within this quota. Ensure that you have a set a low enough number to compensate. Defaults to 100. * View Type: Select the type of view to create in BigQuery. A regular view is a virtual table defined by a SQL query. A materialized view persists the results of a query for faster access, with either incremental or non-incremental updates. Please note that materialized views in this extension come with several important caveats and limitations - carefully review the pre-install documentation before selecting these options to ensure they are appropriate for your use case. diff --git a/firestore-bigquery-export/extension.yaml b/firestore-bigquery-export/extension.yaml index 0e51c1903..0e664fc1b 100644 --- a/firestore-bigquery-export/extension.yaml +++ b/firestore-bigquery-export/extension.yaml @@ -13,7 +13,7 @@ # limitations under the License. name: firestore-bigquery-export -version: 0.1.58 +version: 0.1.59 specVersion: v1beta displayName: Stream Firestore to BigQuery @@ -339,7 +339,7 @@ params: This parameter will set the maximum number of syncronised documents per second with BQ. Please note, any other external updates to a Big Query table will be included within this quota. Ensure that you have a set a low - enough number to compensate. Defaults to 10. + enough number to compensate. Defaults to 100. type: string validationRegex: ^([1-9]|[1-9][0-9]|[1-4][0-9]{2}|500)$ validationErrorMessage: Please select a number between 1 and 500 diff --git a/firestore-bigquery-export/functions/package-lock.json b/firestore-bigquery-export/functions/package-lock.json index ddc5c90e9..74c1ce6c6 100644 --- a/firestore-bigquery-export/functions/package-lock.json +++ b/firestore-bigquery-export/functions/package-lock.json @@ -575,7 +575,6 @@ "version": "1.1.39", "resolved": "https://registry.npmjs.org/@firebaseextensions/firestore-bigquery-change-tracker/-/firestore-bigquery-change-tracker-1.1.39.tgz", "integrity": "sha512-KLLdu6CN2azcisQtfxNnecXv44c4uypJ0II68jpKUbAUkfClSbutDCe5b25Wyt3Tkt7w4XGWFWhYx4IyuUPe8w==", - "license": "Apache-2.0", "dependencies": { "@google-cloud/bigquery": "^7.6.0", "@google-cloud/resource-manager": "^5.1.0", @@ -697,10 +696,9 @@ } }, "node_modules/@google-cloud/resource-manager": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/resource-manager/-/resource-manager-5.3.0.tgz", - "integrity": "sha512-uWJJf6S2PJL7oZ4ezv16aZl9+IJqPo5GzUv1pZ3/qRiMj13p0ylEgX1+LxBpX71eEPKTwMHoJV2IBBe3EAq7Xw==", - "license": "Apache-2.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/resource-manager/-/resource-manager-5.3.1.tgz", + "integrity": "sha512-/7fzwFY6xhvEqkTd2Li/Tg0KThuAoJSIR3zIWNsGS2VGCyqaIt6IgkzpnvFzEUWr/d5hjna+ol4J0fVTAS8puQ==", "dependencies": { "google-gax": "^4.0.3" }, @@ -1906,7 +1904,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" @@ -1926,7 +1923,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", @@ -1961,7 +1957,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -1982,7 +1977,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -2321,7 +2315,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", @@ -2336,10 +2329,9 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", - "license": "MIT", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -2349,13 +2341,12 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", - "license": "MIT", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -2804,7 +2795,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -2821,7 +2811,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -2838,7 +2827,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -2916,7 +2904,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2933,7 +2920,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -3068,7 +3054,6 @@ "version": "1.23.9", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", @@ -3146,10 +3131,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dependencies": { "es-errors": "^1.3.0" }, @@ -3161,7 +3145,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -3176,7 +3159,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "license": "MIT", "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", @@ -3549,7 +3531,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "license": "MIT", "dependencies": { "is-callable": "^1.2.7" }, @@ -3649,7 +3630,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -3674,7 +3654,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3788,17 +3767,16 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", - "license": "MIT", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -3845,7 +3823,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -3887,7 +3864,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -3989,7 +3965,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4008,7 +3983,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -4020,7 +3994,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.0" }, @@ -4047,7 +4020,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -4265,7 +4237,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", @@ -4293,7 +4264,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -4314,7 +4284,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "license": "MIT", "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", @@ -4333,7 +4302,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "license": "MIT", "dependencies": { "has-bigints": "^1.0.2" }, @@ -4348,7 +4316,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4364,7 +4331,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4386,7 +4352,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", @@ -4403,7 +4368,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -4419,7 +4383,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4448,7 +4411,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", @@ -4466,7 +4428,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4485,7 +4446,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4501,7 +4461,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", @@ -4519,7 +4478,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4531,7 +4489,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4556,7 +4513,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4572,7 +4528,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", @@ -4589,7 +4544,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" }, @@ -4610,7 +4564,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4622,7 +4575,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4637,7 +4589,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" @@ -4661,8 +4612,7 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "license": "MIT" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", @@ -7105,7 +7055,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7114,7 +7063,6 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -7169,7 +7117,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", @@ -7342,7 +7289,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7514,7 +7460,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -7536,7 +7481,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -7672,7 +7616,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -7709,7 +7652,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" @@ -7725,7 +7667,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7820,7 +7761,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7837,7 +7777,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7852,7 +7791,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", @@ -8146,7 +8084,6 @@ "version": "1.2.10", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -8167,7 +8104,6 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -8185,7 +8121,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8353,7 +8288,6 @@ "version": "0.6.11", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz", "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==", - "license": "MIT", "dependencies": { "gopd": "^1.2.0", "typedarray.prototype.slice": "^1.0.5", @@ -8509,7 +8443,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -8523,7 +8456,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", @@ -8542,7 +8474,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -8563,7 +8494,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -8592,7 +8522,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -8625,7 +8554,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", @@ -8767,7 +8695,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "license": "MIT", "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", @@ -8786,7 +8713,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", @@ -8813,7 +8739,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -8834,15 +8759,15 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", - "license": "MIT", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, diff --git a/firestore-bigquery-export/guides/GENERATE_SCHEMA_VIEWS.md b/firestore-bigquery-export/guides/GENERATE_SCHEMA_VIEWS.md index 58729dcd8..99f266554 100644 --- a/firestore-bigquery-export/guides/GENERATE_SCHEMA_VIEWS.md +++ b/firestore-bigquery-export/guides/GENERATE_SCHEMA_VIEWS.md @@ -1,38 +1,86 @@ -The `fs-bq-schema-views` script is for use with the official Firebase Extension -[_Stream Firestore to BigQuery_](https://github.com/firebase/extensions/tree/master/firestore-bigquery-export). +# Firebase Extension: Stream Firestore to BigQuery -## Overview +This guide explains how to use the `fs-bq-schema-views` script with the official Firebase Extension _Stream Firestore to BigQuery_, or the [import script](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md). -The `fs-bq-schema-views` script (referred to as the "schema-views script") -generates richly-typed BigQuery views of your raw changelog. +## What This Script Does -The _Stream Firestore to BigQuery_ extension only mirrors raw data, but it -doesn't apply schemas or types. This decoupling makes schema validation less -risky because no data can be lost due to schema mismatch or unknown fields. +The `fs-bq-schema-views` script creates richly-typed BigQuery views from your raw Firestore changelog data. While the extension mirrors your raw data to BigQuery, this script helps you apply proper schemas and types to make your data more queryable. -The schema-views script creates a BigQuery view, based on a JSON schema -configuration file, using -[BigQuery's built-in JSON functions](https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions). -The _Stream Firestore to BigQuery_ extension also provides some BigQuery -[user-defined functions](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/scripts/gen-schema-view/src/udf.ts) -that are helpful in converting Firestore document properties to richly-typed -BigQuery cells. +### Key Benefits -## Use the script +- Applies data types to your raw Firestore data in BigQuery +- Uses BigQuery's JSON functions to create structured views +- Preserves all raw data (no data loss due to schema mismatches) +- Supports complex Firestore data types like arrays, maps, and geopoints -The following steps are an example of how to use the schema-views script. In the -sections at the end of this file, you can review detailed information about -configuring a schema file and reviewing the resulting schema views. +## Prerequisites -### Step 1: Create a schema file +1. Node.js installed (to run npm and npx commands) -The schema-views script runs against "schema files" which specify your schema -configurations in a JSON format. +2. **Firebase Extension Installation**: -In any directory, create a schema file called `test_schema.json` -that contains the following: + - The ["Stream Firestore to BigQuery" Firebase Extension](https://extensions.dev/extensions/firebase/firestore-bigquery-export) must be installed and configured + - Or you must have run the import script so the changelog table and latest view exist in BigQuery +3. BigQuery dataset set up (the one specified when configuring the Firebase Extension) + +4. Firebase project with Firestore data (only required if using the AI schema generation feature) + +5. Authentication configured: + - Use gcloud CLI: `gcloud auth application-default login` + - Or use a service account with `bigquery.jobs.create` permissions + - Your service account needs the ["BigQuery Job User" role](https://cloud.google.com/iam/docs/understanding-roles#bigquery-roles) or equivalent + +## Getting Started + +### Option 1: Generate a Schema with Gemini AI (Recommended) + +The easiest way to create a schema file is to let Gemini generate one for you based on your actual Firestore data. + +#### Prerequisites + +- [Google AI API key](https://aistudio.google.com) + +#### Interactive Mode + +```bash +npx @firebaseextensions/fs-bq-schema-views ``` + +You'll be prompted for: + +- Firebase Project ID +- BigQuery Project ID +- BigQuery dataset ID +- Table Prefix +- Firestore collection path to sample +- Google AI API key +- Directory and filename for the schema + +#### Non-Interactive Mode + +```bash +npx @firebaseextensions/fs-bq-schema-views \ + --non-interactive \ + --project=my-firebase-project \ + --big-query-project=my-bq-project \ + --dataset=firestore_changelog \ + --table-name-prefix=user_profiles \ + --use-gemini=users_collection \ + --google-ai-key=$GOOGLE_API_KEY \ + --schema-directory=./schemas \ + --gemini-schema-file-name=user_schema +``` + +⚠️ **Important**: Always review generated schemas before using them in production. + +### Option 2: Create a Schema File Manually + +#### Create a Basic Schema + +Create a file (e.g., `test_schema.json`) containing: + +```json { "fields": [ { @@ -47,162 +95,89 @@ that contains the following: } ``` -SQL has a number of [reserved keywords](https://en.wikipedia.org/wiki/SQL_reserved_words) that can cause conflicts when creating a schema, `timestamp` is one such example. To ensure your Firestore document field names do not conflict, use the `column_name` option to override the field name. +#### Handle Reserved Keywords -Please see the example below... +SQL has reserved keywords that can cause conflicts. Use `column_name` to create a safe alias: -``` +```json { "fields": [ { - "name": "name", - "type": "string" - }, - { - "name": "age", - "type": "number", - "column_name": "new_column_name" + "name": "timestamp", // SQL reserved keyword + "type": "timestamp", + "column_name": "event_timestamp" // Safe alternative name } ] } ``` -Learn [How to configure schema files](#how-to-configure-schema-files) -later in this guide. - -### Step 2: Set up credentials +### Verify Your Authentication -The schema-views script uses Application Default Credentials to communicate with -BigQuery. +Make sure your authentication from the prerequisites is working correctly before proceeding. The script needs BigQuery access to create views. -One way to set up these credentials is to run the following command using the -[gcloud](https://cloud.google.com/sdk/gcloud/) CLI: +### Run the Script +```bash +npx @firebaseextensions/fs-bq-schema-views \ + --non-interactive \ + --project=YOUR_PROJECT_ID \ + --big-query-project=YOUR_BIGQUERY_PROJECT_ID \ + --dataset=YOUR_DATASET_ID \ + --table-name-prefix=YOUR_TABLE_PREFIX \ + --schema-files=./test_schema.json ``` -$ gcloud auth application-default login -``` - -Alternatively, you can -[create and use a service account](https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually). -This service account must be assigned a role that grants the permission of -`bigquery.jobs.create`, like the ["BigQuery Job User" role](https://cloud.google.com/iam/docs/understanding-roles#bigquery-roles). - -### Step 3: Run the script - -The schema-views script uses the following parameter values from your -installation of the extension: - -- `${param:PROJECT_ID}`: the project ID for the Firebase project in - which you installed the extension -- `${param:BIGQUERY_PROJECT_ID}`: the project ID for the GCP project that contains - the BigQuery instance. -- `${param:DATASET_ID}`: the ID that you specified for your dataset during - extension installation -- `${param:TABLE_ID}`: the common prefix of BigQuery views to generate - -Run the schema-views script using -[`npx` (the Node Package Runner)](https://github.com/npm/npx#npx1----execute-npm-package-binaries) -via `npm` (the Node Package Manager). - -1. Make sure that you've installed the required tools to run the - schema-views script: - - - To access the `npm` command tools, you need to install - [Node.js](https://www.nodejs.org/). - - If you use npm v5.1 or earlier, you need to explicitly install `npx`. - Run `npm install --global npx`. - -1. Run the schema-views script via `npx` by running the following command: - - ``` - $ npx @firebaseextensions/fs-bq-schema-views \ - --non-interactive \ - --project=${param:PROJECT_ID} \ - --big-query-project=${param:BIGQUERY_PROJECT_ID} \ - --dataset=${param:DATASET_ID} \ - --table-name-prefix=${param:TABLE_ID} \ - --schema-files=./test_schema.json - ``` - - **Note:** You can run the schema-views script from any directory, but - you need to specify the path to your schema file using the `--schema-files` - flag. To run the schema-views script against multiple schema files, specify - each file in a comma-separated list - (for example: `--schema-files=./test_schema.json,./test_schema2.json`). - -### Step 4: View results - -1. In the [BigQuery web UI](https://console.cloud.google.com/bigquery), - navigate to the generated schema changelog view: - `https://console.cloud.google.com/bigquery?project=${param:PROJECT_ID}&p=${param:PROJECT_ID}&d=${param:DATASET_ID}&t=${param:TABLE_ID}_schema_test_schema_changelog&page=table`. - - This view allows you to query document change events by fields specified in - the schema. -1. In the [Firebase console](https://console.firebase.google.com/), - go to the Cloud Firestore section, - then create a document called `test-schema-document` with two fields: +For multiple schema files, use comma separation: - - A field of type `string` called "name" - - A field of type `number` called "age" - -1. Back in BigQuery, run the following query in the schema changelog - view (that is, `https://console.cloud.google.com/bigquery?project=${param:PROJECT_ID}&p=${param:PROJECT_ID}&d=${param:DATASET_ID}&t=${param:TABLE_ID}_schema_test_schema_changelog&page=table`): +``` +--schema-files=./schema1.json,./schema2.json +``` - ``` - SELECT document_name, name, age - FROM ${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_test_schema_changelog - WHERE document_name = "test-schema-document" - ``` +## Testing Your Schema Views -1. Go back to the Cloud Firestore section of the console, then change - the type of the "age" field to be a string. +1. In the [BigQuery web UI](https://console.cloud.google.com/bigquery), navigate to your dataset and find the new view: `YOUR_TABLE_PREFIX_schema_test_schema_changelog` -1. Back in BigQuery, re-run the following query: + You can access this view directly using the URL: + `https://console.cloud.google.com/bigquery?project=YOUR_PROJECT_ID&p=YOUR_PROJECT_ID&d=YOUR_DATASET_ID&t=YOUR_TABLE_PREFIX_schema_test_schema_changelog&page=table` - ``` - SELECT document_name, name, age - FROM ${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_test_schema_changelog - WHERE document_name = "test-schema-document" - ``` +2. Create a test document in Firestore with fields matching your schema: - You'll see a new change with a `null` age column. If you query documents - that don't match the schema, then the view contains null values for the - corresponding schema fields. + - Add a document named `test-schema-document` + - Include fields like "name" (string) and "age" (number) -1. Back in the Cloud Firestore section in the console, delete - `test-schema-document`. +3. Run a query against your changelog view: -1. _(Optional)_ As with the raw views, you can also query events on the - view of the documents currently in the collection by using the latest - schema view - (that is, `https://console.cloud.google.com/bigquery?project=${param:PROJECT_ID}&p=${param:PROJECT_ID}&d=${param:DATASET_ID}&t=${param:COLLECTION_PATH}_schema_test_schema_latest&page=table`. + ```sql + SELECT document_name, name, age + FROM YOUR_PROJECT_ID.YOUR_DATASET_ID.YOUR_TABLE_PREFIX_schema_test_schema_changelog + WHERE document_name = "test-schema-document" + ``` - Back in BigQuery, if you run the following query, you'll receive no - results because the document no longer exists in the Cloud Firestore - collection. +4. Test schema validation by changing a field type in Firestore (e.g., change "age" from number to string) - ``` - SELECT document_name, name, age - FROM ${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_test_schema_latest - WHERE document_name = "test-schema-document" - ``` +5. Run the query again to see how type mismatches appear (as NULL values) -### Next Steps +6. _(Optional)_ You can also query events on the view of the documents currently in the collection by using the latest schema view at: + `https://console.cloud.google.com/bigquery?project=YOUR_PROJECT_ID&p=YOUR_PROJECT_ID&d=YOUR_DATASET_ID&t=YOUR_TABLE_PREFIX_schema_test_schema_latest&page=table` -- [Create your own schema files](#how-to-configure-schema-files) -- [Troubleshoot common issues](#common-schema-file-configuration-mistakes) -- [Learn about the columns in a schema view](#columns-in-a-schema-view) -- [Take a look at more SQL examples](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/EXAMPLE_QUERIES.md) +## Schema Configuration Details -## How to configure schema files +### Available Field Types -To generate schema views of your raw changelog, you must create at least one -schema JSON file. +- `string` +- `number` +- `boolean` +- `timestamp` +- `geopoint` +- `array` +- `map` +- `reference` +- `null` +- `stringified_map` (special type for converting maps to JSON strings) -Here's an example of a configuration that a schema file might contain: +### Example Schema with Various Types -``` +```json { "fields": [ { @@ -226,187 +201,66 @@ Here's an example of a configuration that a schema file might contain: "type": "stringified_map" }, { + "name": "friends", + "type": "map", "fields": [ { "name": "name", "type": "string" } - ], - "name": "friends", - "type": "map" + ] } ] } ``` -The root of the configuration must have a `fields` array that contains objects -which describe the elements in the schema. If one of the objects is of type -`map`, it must specify its own `fields` array describing the members of that -map. +### Generated Views -Each `fields` array must contain _at least one_ of the following types: +For each schema file, the script creates two views: -- `string` -- `array` -- `map` -- `boolean` -- `number` -- `timestamp` -- `geopoint` -- `reference` -- `null` -- `stringified_map` - -All but `stringified_map` correspond with Cloud Firestore's -[supported data types](https://firebase.google.com/docs/firestore/manage-data/data-types). -Make sure that the other types specified match the types of the fields in your -Cloud Firestore collection. - -The `stringified_map` type will create a JSON string out of a map in your Firestore record. This -could be useful if you are not sure of the properties in the map ahead of time, and thus -cannot specify in your schema. - -You may create any number of schema files to use with the schema-views script. -The schema-views script generates the following views for _each_ schema file: - -- `${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_${SCHEMA_FILE_NAME}_changelog` -- `${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_${SCHEMA_FILE_NAME}_latest` - -Here, `${SCHEMA_FILE_NAME}` is the name of each schema file that you provided as -an argument to run the schema-views script. - -### Common schema file configuration mistakes - -Be aware of the following common mistakes when configuring a schema file: - - - - - - - - - - - - - - - - - - - - - - - - - - -
Mistake in schema file configOutcome of mistake
Omitting a relevant fieldThe generated view will not contain a column for that field.
Specifying the wrong type for a relevant fieldType conversion (see previous section) will fail and the resulting column - will contain a BigQuery null value in lieu of the desired - value.
Specifying a schema field that doesn't exist in the underlying raw - changelogQuerying the column for that field will return a BigQuery null - value instead of the desired value.
Writing invalid JSONThe schema-views script cannot generate a view
- -Since all document data is stored in the schemaless changelog, mistakes in -schema configuration don't affect the underlying data and can be resolved by -re-running the schema-views script against an updated schema file. - -## About Schema Views - -### Views created by the script - -- `${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_${SCHEMA_FILE_NAME}_changelog` - - This view is a table which contains all rows present in the raw changelog. - This view is analogous to the raw change-log, only it has typed columns - corresponding to fields of the schema. - -- `${param:PROJECT_ID}.${param:DATASET_ID}.${param:TABLE_ID}_schema_${SCHEMA_FILE_NAME}_latest` - - This view stores typed rows for the documents currently in the collection. - This view is analogous to the "latest" view on the raw changelog, only it - includes the typed columns corresponding to fields in the corresponding - schema file. - - Since `GEOGRAPHY` fields are not groupable entities in BigQuery (and the - query which builds the latest view of a collection of documents requires - grouping on the schema columns), the latest schema omits any `GEOGRAPHY` - columns and, instead, splits them out into two `NUMERIC` columns called - `${FIRESTORE_GEOPOINT}_latitude` and `${FIRESTORE_GEOPOINT}_longitude`. - -### Columns in a schema view - -Each schema view carries with it the following fields from the raw changelog: - -- `document_name STRING REQUIRED` -- `timestamp TIMESTAMP REQUIRED` -- `operation STRING REQUIRED` - -The remaining columns correspond to fields of the schema and are assigned types -based on the corresponding Cloud Firestore types those fields have. With the -exception of `map` and `array`, the type conversion scheme is as follows: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cloud Firestore typeBigQuery type
stringSTRING
booleanBOOLEAN
numberNUMERIC
timestampTIMESTAMP
geopointGEOGRAPHY
referenceSTRING
(containing the path to the referenced document)
nullNULL
- -#### Cloud Firestore maps - -Cloud Firestore maps are interpreted recursively. If you include a map in your -schema configuration, the resulting view will contain columns for whatever -fields that map contains. If the map doesn't contain any fields, the map is -ignored by the schema-views script. If using the `stringified_map` type, the -map will be stringified. - -#### Cloud Firestore arrays - -Review [these examples](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/EXAMPLE_QUERIES.md#example-queries-for-an-array) for querying an array. - -Cloud Firestore arrays are -[unnested](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#unnest), -so all array fields of the document are -[cross joined](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#cross-join) -in the output table. The view retains the member and offset columns, which are -called `${FIRESTORE_ARRAY_NAME}_member` and `${FIRESTORE_ARRAY_NAME}_index`, -respectively. To make querying easier, the view includes these two columns -instead of the original `ARRAY` value field. - -If the array is empty, it will be ignored by the schema-views script. +1. **Changelog View**: `YOUR_TABLE_PREFIX_schema_SCHEMA_FILE_NAME_changelog` + + - Contains all document changes with typed columns + - Includes all historical data + +2. **Latest View**: `YOUR_TABLE_PREFIX_schema_SCHEMA_FILE_NAME_latest` + - Contains only the current state of documents + - Better for querying the present state of your data + +### Column Data Types + +| Firestore Type | BigQuery Type | Notes | +| -------------- | ---------------- | ------------------------------------------------------ | +| string | STRING | | +| boolean | BOOLEAN | | +| number | NUMERIC | | +| timestamp | TIMESTAMP | | +| geopoint | GEOGRAPHY | In latest views, split into latitude/longitude columns | +| reference | STRING | Contains path to referenced document | +| null | NULL | | +| map | Nested columns | Columns created for each field in the map | +| array | Unnested columns | Creates \_member and \_index columns | + +## Common Issues and Troubleshooting + +### Schema Configuration Mistakes + +| Issue | Result | Solution | +| -------------------------------- | --------------------- | -------------------------------------- | +| Missing field in schema | No column in the view | Add the field to your schema | +| Wrong field type | NULL values | Update schema with correct type | +| Field doesn't exist in Firestore | NULL values | Remove from schema or add to Firestore | +| Invalid JSON in schema file | View generation fails | Validate your JSON syntax | + +### Working with Arrays + +- Arrays are unnested in BigQuery views +- Each array element becomes a separate row +- Use `${ARRAY_NAME}_member` to access values +- Use `${ARRAY_NAME}_index` for position in array +- If the array is empty, it will be ignored by the `fs-bq-schema-views` script +- Review [these examples](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/EXAMPLE_QUERIES.md#example-queries-for-an-array) specifically for querying an array + +## Next Steps + +- [View example queries](https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/EXAMPLE_QUERIES.md) diff --git a/firestore-bigquery-export/scripts/gen-schema-view/package-lock.json b/firestore-bigquery-export/scripts/gen-schema-view/package-lock.json index e649ed665..8f6109a65 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/package-lock.json +++ b/firestore-bigquery-export/scripts/gen-schema-view/package-lock.json @@ -1,21 +1,23 @@ { "name": "@firebaseextensions/fs-bq-schema-views", - "version": "0.4.9", + "version": "0.4.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@firebaseextensions/fs-bq-schema-views", - "version": "0.4.9", + "version": "0.4.10", "license": "Apache-2.0", "dependencies": { - "@firebaseextensions/firestore-bigquery-change-tracker": "^1.1.36", + "@firebaseextensions/firestore-bigquery-change-tracker": "^1.1.38", + "@genkit-ai/googleai": "^1.1.0", "@google-cloud/bigquery": "^6.0.3", "commander": "5.0.0", "firebase-admin": "^12.1.0", "firebase-functions": "^4.2.0", "fs-find": "^0.4.0", "generate-schema": "^2.6.0", + "genkit": "^1.1.0", "glob": "7.1.5", "inquirer": "^6.4.0", "sql-formatter": "^2.3.3" @@ -27,52 +29,19 @@ "@types/chai": "^4.1.6", "@types/express": "^4.17.14", "@types/express-serve-static-core": "4.17.30", + "@types/inquirer": "^9.0.7", "@types/jest": "29.5.0", "chai": "^4.2.0", "exec": "^0.2.1", "jest": "29.5.0", "mocked-env": "^1.3.2", - "nyc": "^14.0.0", + "nyc": "^17.1.0", "rimraf": "^2.6.3", "ts-jest": "29.1.2", "ts-node": "^7.0.1", "typescript": "^4.9.3" } }, - "../../firestore-bigquery-change-tracker": { - "name": "@firebaseextensions/firestore-bigquery-change-tracker", - "version": "1.1.39", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@google-cloud/bigquery": "^7.6.0", - "@google-cloud/resource-manager": "^5.1.0", - "firebase-admin": "^12.0.0", - "firebase-functions": "^4.9.0", - "generate-schema": "^2.6.0", - "inquirer": "^6.4.0", - "lodash": "^4.17.14", - "node-fetch": "^2.6.1", - "sql-formatter": "^2.3.3", - "traverse": "^0.6.6" - }, - "devDependencies": { - "@types/chai": "^4.1.6", - "@types/jest": "^29.5.14", - "@types/node": "14.18.34", - "@types/traverse": "^0.6.32", - "chai": "^4.2.0", - "jest": "29.5.0", - "jest-config": "29.5.0", - "jest-environment-node": "29.5.0", - "jest-summarizing-reporter": "^1.1.4", - "mocked-env": "^1.3.2", - "nyc": "^17.1.0", - "rimraf": "^2.6.3", - "ts-jest": "29.1.2", - "typescript": "^4.9.4" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "dev": true, @@ -615,31 +584,26 @@ }, "node_modules/@fastify/busboy": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/@firebase/app-check-interop-types": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.1.tgz", - "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" + "license": "Apache-2.0" }, "node_modules/@firebase/app-types": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.1.tgz", - "integrity": "sha512-nFGqTYsnDFn1oXf1tCwPAc+hQPxyvBT/QB7qDjwK+IDYThOn63nGhzdUTXxVD9Ca8gUY/e5PQMngeo0ZW/E3uQ==" + "license": "Apache-2.0" }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.2.tgz", - "integrity": "sha512-k3NA28Jfoo0+o391bFjoV9X5QLnUL1WbLhZZRbTQhZdmdGYJfX8ixtNNlHsYQ94bwG0QRbsmvkzDnzuhHrV11w==" + "license": "Apache-2.0" }, "node_modules/@firebase/component": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", - "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", + "license": "Apache-2.0", "dependencies": { "@firebase/util": "1.9.5", "tslib": "^2.1.0" @@ -647,13 +611,11 @@ }, "node_modules/@firebase/component/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/@firebase/database": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.4.tgz", - "integrity": "sha512-k84cXh+dtpzvY6yOhfyr1B+I1vjvSMtmlqotE0lTNVylc8m5nmOohjzpTLEQDrBWvwACX/VP5fEyajAdmnOKqA==", + "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.1", "@firebase/auth-interop-types": "0.2.2", @@ -666,8 +628,7 @@ }, "node_modules/@firebase/database-compat": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.4.tgz", - "integrity": "sha512-GEEDAvsSMAkqy0BIFSVtFzoOIIcKHFfDM4aXHtWL/JCaNn4OOjH7td73jDfN3ALvpIN4hQki0FcxQ89XjqaTjQ==", + "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.6", "@firebase/database": "1.0.4", @@ -679,13 +640,11 @@ }, "node_modules/@firebase/database-compat/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/@firebase/database-types": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.2.tgz", - "integrity": "sha512-JRigr5JNLEHqOkI99tAGHDZF47469/cJz1tRAgGs8Feh+3ZmQy/vVChSqwMp2DuVUGp9PlmGsNSlpINJ/hDuIA==", + "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.1", "@firebase/util": "1.9.5" @@ -693,39 +652,32 @@ }, "node_modules/@firebase/database/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/@firebase/logger": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", - "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@firebase/logger/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/@firebase/util": { "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", - "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@firebase/util/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker": { "version": "1.1.39", - "resolved": "https://registry.npmjs.org/@firebaseextensions/firestore-bigquery-change-tracker/-/firestore-bigquery-change-tracker-1.1.39.tgz", - "integrity": "sha512-KLLdu6CN2azcisQtfxNnecXv44c4uypJ0II68jpKUbAUkfClSbutDCe5b25Wyt3Tkt7w4XGWFWhYx4IyuUPe8w==", "license": "Apache-2.0", "dependencies": { "@google-cloud/bigquery": "^7.6.0", @@ -742,8 +694,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/@google-cloud/bigquery": { "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-7.9.2.tgz", - "integrity": "sha512-Yo7oYE6m7bBT28tYDn6dBwbXZxCt+nWREj/0y5aoUq0rFUGwLUDKAXwgt6OQJ2htDzGiQ3s0yltCBjKFtqVCmA==", "license": "Apache-2.0", "dependencies": { "@google-cloud/common": "^5.0.0", @@ -764,8 +714,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/@google-cloud/common": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", - "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==", "license": "Apache-2.0", "dependencies": { "@google-cloud/projectify": "^4.0.0", @@ -784,8 +732,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/@google-cloud/paginator": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", "license": "Apache-2.0", "dependencies": { "arrify": "^2.0.0", @@ -797,8 +743,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/@google-cloud/projectify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", "license": "Apache-2.0", "engines": { "node": ">=14.0.0" @@ -806,8 +750,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/@google-cloud/promisify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -815,8 +757,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/agent-base": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "license": "MIT", "engines": { "node": ">= 14" @@ -824,8 +764,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/debug": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -841,8 +779,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/gaxios": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -857,8 +793,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/gaxios/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -870,8 +804,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/gcp-metadata": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "license": "Apache-2.0", "dependencies": { "gaxios": "^6.1.1", @@ -884,8 +816,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/google-auth-library": { "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -901,8 +831,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", "dependencies": { "gaxios": "^6.0.0", @@ -912,28 +840,12 @@ "node": ">=14.0.0" } }, - "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/retry-request": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", "license": "MIT", "dependencies": { "@types/request": "^2.48.8", @@ -946,8 +858,6 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/teeny-request": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", "license": "Apache-2.0", "dependencies": { "http-proxy-agent": "^5.0.0", @@ -962,8 +872,218 @@ }, "node_modules/@firebaseextensions/firestore-bigquery-change-tracker/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@genkit-ai/ai": { + "version": "1.1.0", + "license": "Apache-2.0", + "dependencies": { + "@genkit-ai/core": "1.1.0", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.11.19", + "colorette": "^2.0.20", + "dotprompt": "^1.0.0", + "json5": "^2.2.3", + "node-fetch": "^3.3.2", + "partial-json": "^0.1.7", + "uuid": "^10.0.0" + } + }, + "node_modules/@genkit-ai/ai/node_modules/node-fetch": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/@genkit-ai/ai/node_modules/uuid": { + "version": "10.0.0", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@genkit-ai/core": { + "version": "1.1.0", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.25.0", + "@opentelemetry/core": "^1.25.0", + "@opentelemetry/sdk-metrics": "^1.25.0", + "@opentelemetry/sdk-node": "^0.52.0", + "@opentelemetry/sdk-trace-base": "^1.25.0", + "@types/json-schema": "^7.0.15", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "async-mutex": "^0.5.0", + "body-parser": "^1.20.3", + "cors": "^2.8.5", + "dotprompt": "^1.0.0", + "express": "^4.21.0", + "get-port": "^5.1.0", + "json-schema": "^0.4.0", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.22.4" + } + }, + "node_modules/@genkit-ai/googleai": { + "version": "1.1.0", + "license": "Apache-2.0", + "dependencies": { + "@google/generative-ai": "^0.21.0", + "google-auth-library": "^9.6.3", + "node-fetch": "^3.3.2" + }, + "peerDependencies": { + "genkit": "^1.1.0" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/agent-base": { + "version": "7.1.3", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/debug": { + "version": "4.4.0", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@genkit-ai/googleai/node_modules/gaxios": { + "version": "6.7.1", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/gaxios/node_modules/node-fetch": { + "version": "2.7.0", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@genkit-ai/googleai/node_modules/gcp-metadata": { + "version": "6.1.1", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/google-auth-library": { + "version": "9.15.1", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/gtoken": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/https-proxy-agent": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/@genkit-ai/googleai/node_modules/node-fetch": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/@genkit-ai/googleai/node_modules/uuid": { + "version": "9.0.1", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -1014,8 +1134,7 @@ }, "node_modules/@google-cloud/firestore": { "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.6.0.tgz", - "integrity": "sha512-WUDbaLY8UnPxgwsyIaxj6uxCtSDAaUyvzWJykNH5rZ9i92/SZCsPNNMN0ajrVpAR81hPIL4amXTaMJ40y5L+Yg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -1040,8 +1159,6 @@ }, "node_modules/@google-cloud/precise-date": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/precise-date/-/precise-date-4.0.0.tgz", - "integrity": "sha512-1TUx3KdaU3cN7nfCdNf+UVqA/PSX29Cjcox3fZZBtINlRrXVTmUkQnCKv2MbBUbCopbK4olAT1IHl76uZyCiVA==", "license": "Apache-2.0", "engines": { "node": ">=14.0.0" @@ -1063,8 +1180,6 @@ }, "node_modules/@google-cloud/resource-manager": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/resource-manager/-/resource-manager-5.3.0.tgz", - "integrity": "sha512-uWJJf6S2PJL7oZ4ezv16aZl9+IJqPo5GzUv1pZ3/qRiMj13p0ylEgX1+LxBpX71eEPKTwMHoJV2IBBe3EAq7Xw==", "license": "Apache-2.0", "dependencies": { "google-gax": "^4.0.3" @@ -1075,8 +1190,7 @@ }, "node_modules/@google-cloud/storage": { "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.0.tgz", - "integrity": "sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@google-cloud/paginator": "^5.0.0", @@ -1101,8 +1215,7 @@ }, "node_modules/@google-cloud/storage/node_modules/@google-cloud/paginator": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", - "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "license": "Apache-2.0", "optional": true, "dependencies": { "arrify": "^2.0.0", @@ -1114,8 +1227,7 @@ }, "node_modules/@google-cloud/storage/node_modules/@google-cloud/projectify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=14.0.0" @@ -1123,8 +1235,7 @@ }, "node_modules/@google-cloud/storage/node_modules/@google-cloud/promisify": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=14" @@ -1132,8 +1243,7 @@ }, "node_modules/@google-cloud/storage/node_modules/agent-base": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", "optional": true, "dependencies": { "debug": "^4.3.4" @@ -1144,8 +1254,7 @@ }, "node_modules/@google-cloud/storage/node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", "optional": true, "dependencies": { "ms": "2.1.2" @@ -1161,8 +1270,7 @@ }, "node_modules/@google-cloud/storage/node_modules/gaxios": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.5.0.tgz", - "integrity": "sha512-R9QGdv8j4/dlNoQbX3hSaK/S0rkMijqjVvW3YM06CoBdbU/VdKd159j4hePpng0KuE6Lh6JJ7UdmVGJZFcAG1w==", + "license": "Apache-2.0", "optional": true, "dependencies": { "extend": "^3.0.2", @@ -1177,8 +1285,7 @@ }, "node_modules/@google-cloud/storage/node_modules/gaxios/node_modules/https-proxy-agent": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.0.2", @@ -1190,12 +1297,11 @@ }, "node_modules/@google-cloud/storage/node_modules/gaxios/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" @@ -1203,8 +1309,7 @@ }, "node_modules/@google-cloud/storage/node_modules/gcp-metadata": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "gaxios": "^6.0.0", @@ -1216,8 +1321,7 @@ }, "node_modules/@google-cloud/storage/node_modules/google-auth-library": { "version": "9.8.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.8.0.tgz", - "integrity": "sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==", + "license": "Apache-2.0", "optional": true, "dependencies": { "base64-js": "^1.3.0", @@ -1233,8 +1337,7 @@ }, "node_modules/@google-cloud/storage/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", "optional": true, "dependencies": { "gaxios": "^6.0.0", @@ -1244,28 +1347,14 @@ "node": ">=14.0.0" } }, - "node_modules/@google-cloud/storage/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "optional": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@google-cloud/storage/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==", + "license": "MIT", "optional": true }, "node_modules/@google-cloud/storage/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==", + "license": "MIT", "optional": true, "dependencies": { "yocto-queue": "^0.1.0" @@ -1279,8 +1368,7 @@ }, "node_modules/@google-cloud/storage/node_modules/retry-request": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", "optional": true, "dependencies": { "@types/request": "^2.48.8", @@ -1293,8 +1381,7 @@ }, "node_modules/@google-cloud/storage/node_modules/teeny-request": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", "optional": true, "dependencies": { "http-proxy-agent": "^5.0.0", @@ -1309,21 +1396,26 @@ }, "node_modules/@google-cloud/storage/node_modules/teeny-request/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" } }, + "node_modules/@google/generative-ai": { + "version": "0.21.0", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@grpc/grpc-js": { "version": "1.10.11", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.11.tgz", - "integrity": "sha512-3RaoxOqkHHN2c05bwtBNVJmOf/UwMam0rZYtdl7dsRpsvDwcNpv6LkGgzltQ7xVf822LzBoKEPRvf4D7+xeIDw==", + "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.7.13", "@js-sdsl/ordered-map": "^4.4.2" @@ -1334,8 +1426,7 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", @@ -1364,78 +1455,28 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/@jest/console": { + "version": "29.7.0", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/console/node_modules/ansi-styles": { @@ -1932,22 +1973,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@jest/reporters/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -1956,86 +1981,6 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-report": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-reports": { - "version": "3.1.7", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/reporters/node_modules/semver": { - "version": "7.6.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@jest/reporters/node_modules/strip-ansi": { "version": "6.0.1", "dev": true, @@ -2341,96 +2286,943 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "license": "BSD-3-Clause" + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "license": "BSD-3-Clause", + "node_modules/@opentelemetry/api-logs": { + "version": "0.52.1", + "license": "Apache-2.0", "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "license": "BSD-3-Clause" + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "license": "BSD-3-Clause" + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-grpc-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", "dependencies": { - "type-detect": "4.0.8" + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": ">= 10" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/exporter-zipkin": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/semver": { + "version": "7.7.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-transformer": "0.52.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-logs": "0.52.1", + "@opentelemetry/sdk-metrics": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-metrics": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/protobufjs": { + "version": "7.4.0", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.30.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.52.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/exporter-trace-otlp-grpc": "0.52.1", + "@opentelemetry/exporter-trace-otlp-http": "0.52.1", + "@opentelemetry/exporter-trace-otlp-proto": "0.52.1", + "@opentelemetry/exporter-zipkin": "1.25.1", + "@opentelemetry/instrumentation": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-logs": "0.52.1", + "@opentelemetry/sdk-metrics": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "@opentelemetry/sdk-trace-node": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/sdk-metrics": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.25.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/propagator-b3": "1.25.1", + "@opentelemetry/propagator-jaeger": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/context-async-hooks": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/semver": { + "version": "7.7.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -2495,8 +3287,7 @@ }, "node_modules/@types/caseless": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" + "license": "MIT" }, "node_modules/@types/chai": { "version": "4.3.4", @@ -2541,6 +3332,35 @@ "@types/node": "*" } }, + "node_modules/@types/handlebars": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "handlebars": "*" + } + }, + "node_modules/@types/inquirer": { + "version": "9.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/inquirer/node_modules/rxjs": { + "version": "7.8.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@types/inquirer/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "dev": true, @@ -2571,10 +3391,13 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "license": "MIT" + }, "node_modules/@types/long": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + "license": "MIT" }, "node_modules/@types/mime": { "version": "3.0.1", @@ -2582,8 +3405,7 @@ }, "node_modules/@types/node": { "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -2598,8 +3420,7 @@ }, "node_modules/@types/request": { "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", "dependencies": { "@types/caseless": "*", "@types/node": "*", @@ -2615,15 +3436,26 @@ "@types/node": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "license": "MIT" + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "dev": true, "license": "MIT" }, + "node_modules/@types/through": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.32", @@ -2660,11 +3492,8 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "dev": true, + "version": "8.14.1", "license": "MIT", - "optional": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2672,6 +3501,13 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-walk": { "version": "8.3.2", "dev": true, @@ -2711,6 +3547,47 @@ "version": "2.1.2", "license": "MIT" }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-escapes": { "version": "3.2.0", "license": "MIT", @@ -2748,14 +3625,14 @@ } }, "node_modules/append-transform": { - "version": "1.0.0", + "version": "2.0.0", "dev": true, "license": "MIT", "dependencies": { - "default-require-extensions": "^2.0.0" + "default-require-extensions": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/archy": { @@ -2780,8 +3657,6 @@ }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -2800,8 +3675,6 @@ }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -2836,17 +3709,25 @@ }, "node_modules/async-function": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "license": "MIT", "engines": { "node": ">= 0.4" } }, + "node_modules/async-mutex": { + "version": "0.5.0", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/async-mutex/node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, "node_modules/async-retry": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", "optional": true, "dependencies": { "retry": "0.13.1" @@ -2854,13 +3735,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -2971,14 +3849,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", "dev": true, @@ -2994,19 +3864,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", "dev": true, @@ -3100,8 +3957,7 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -3110,8 +3966,6 @@ }, "node_modules/bl/node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -3126,6 +3980,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -3133,8 +3988,7 @@ }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3146,8 +4000,7 @@ }, "node_modules/body-parser": { "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -3177,9 +4030,8 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -3270,58 +4122,41 @@ }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/caching-transform": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/caching-transform/node_modules/make-dir": { - "version": "2.1.0", + "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/caching-transform/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caching-transform/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/call-bind": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -3338,8 +4173,7 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -3350,8 +4184,7 @@ }, "node_modules/call-bound": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" @@ -3457,8 +4290,7 @@ }, "node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "license": "ISC" }, "node_modules/ci-info": { "version": "3.9.0", @@ -3476,9 +4308,16 @@ }, "node_modules/cjs-module-lexer": { "version": "1.2.3", - "dev": true, "license": "MIT" }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/cli-cursor": { "version": "2.1.0", "license": "MIT", @@ -3495,8 +4334,7 @@ }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3508,24 +4346,21 @@ }, "node_modules/cliui/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==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3537,8 +4372,7 @@ }, "node_modules/cliui/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==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3571,10 +4405,13 @@ "version": "1.1.3", "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3610,81 +4447,36 @@ }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "license": "MIT" - }, - "node_modules/cors": { - "version": "2.8.5", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cp-file": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cp-file/node_modules/make-dir": { - "version": "2.1.0", - "dev": true, "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/cp-file/node_modules/pify": { - "version": "4.0.1", + "node_modules/convert-source-map": { + "version": "1.9.0", "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/cp-file/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "node_modules/cookie-signature": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" } }, "node_modules/create-jest": { @@ -3904,7 +4696,7 @@ "peer": true }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "license": "MIT", "dependencies": { @@ -3916,24 +4708,15 @@ "node": ">= 8" } }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">= 12" } }, "node_modules/data-view-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3949,8 +4732,6 @@ }, "node_modules/data-view-byte-length": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -3966,8 +4747,6 @@ }, "node_modules/data-view-byte-offset": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -3983,8 +4762,7 @@ }, "node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -3999,8 +4777,7 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -4037,8 +4814,7 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -4052,20 +4828,21 @@ } }, "node_modules/default-require-extensions": { - "version": "2.0.0", + "version": "3.0.1", "dev": true, "license": "MIT", "dependencies": { - "strip-bom": "^3.0.0" + "strip-bom": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -4081,8 +4858,6 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -4098,24 +4873,21 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -4123,8 +4895,7 @@ }, "node_modules/detect-libc": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -4153,10 +4924,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dotprompt": { + "version": "1.0.1", + "license": "ISC", + "dependencies": { + "@types/handlebars": "^4.1.0", + "handlebars": "^4.7.8", + "yaml": "^2.5.0" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -4168,8 +4947,7 @@ }, "node_modules/duplexify": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", @@ -4198,8 +4976,7 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.4.736", @@ -4219,13 +4996,11 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4251,8 +5026,6 @@ }, "node_modules/es-abstract": { "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.2", @@ -4316,24 +5089,21 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -4343,8 +5113,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4358,8 +5126,6 @@ }, "node_modules/es-to-primitive": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "license": "MIT", "dependencies": { "is-callable": "^1.2.7", @@ -4387,8 +5153,7 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "1.0.5", @@ -4411,8 +5176,7 @@ }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -4460,17 +5224,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/exit": { "version": "0.1.2", "dev": true, @@ -4480,8 +5233,7 @@ }, "node_modules/expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" } @@ -4502,9 +5254,8 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -4525,7 +5276,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -4540,6 +5291,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/extend": { @@ -4560,9 +5315,8 @@ }, "node_modules/farmhash": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/farmhash/-/farmhash-3.3.1.tgz", - "integrity": "sha512-XUizHanzlr/v7suBr/o85HSakOoWh6HKXZjFYl5C2+Gj0f0rkw+XTUZzrd9odDsgI9G5tRUcF4wSbKaX04T0DQ==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "node-addon-api": "^5.1.0", "prebuild-install": "^7.1.2" @@ -4573,9 +5327,7 @@ }, "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==", - "optional": true + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -4586,10 +5338,22 @@ "version": "1.0.6", "license": "Apache-2.0" }, + "node_modules/fast-uri": { + "version": "3.0.6", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-xml-parser": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "funding": [ { "type": "github", @@ -4600,6 +5364,7 @@ "url": "https://paypal.me/naturalintelligence" } ], + "license": "MIT", "optional": true, "dependencies": { "strnum": "^1.0.5" @@ -4610,8 +5375,7 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -4627,6 +5391,27 @@ "bser": "2.1.1" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/figures": { "version": "2.0.0", "license": "MIT", @@ -4639,9 +5424,8 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4651,8 +5435,7 @@ }, "node_modules/finalhandler": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -4667,61 +5450,50 @@ } }, "node_modules/find-cache-dir": { - "version": "2.1.0", + "version": "3.3.2", "dev": true, "license": "MIT", "dependencies": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "2.1.0", + "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up": { - "version": "3.0.0", + "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/firebase-admin": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.1.0.tgz", - "integrity": "sha512-bU7uPKMmIXAihWxntpY/Ma9zucn5y3ec+HQPqFQ/zcEfP9Avk9E/6D8u+yT/VwKHNZyg7yDVWOoJi73TIdR4Ww==", + "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^2.1.0", "@firebase/database-compat": "^1.0.2", @@ -4751,8 +5523,7 @@ }, "node_modules/firebase-functions": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-4.9.0.tgz", - "integrity": "sha512-IqxOEsVAWGcRv9KRGzWQR5mOFuNsil3vsfkRPPiaV1U/ATC27/jbahh4z8I4rW8Xqa6cQE5xqnw0ueyMH7i7Ag==", + "license": "MIT", "dependencies": { "@types/cors": "^2.8.5", "@types/express": "4.17.3", @@ -4781,8 +5552,6 @@ }, "node_modules/for-each": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -4795,41 +5564,34 @@ } }, "node_modules/foreground-child": { - "version": "1.5.6", + "version": "3.3.1", "dev": true, "license": "ISC", "dependencies": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/lru-cache": { - "version": "4.1.5", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", "dev": true, "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/yallist": { - "version": "2.1.2", - "dev": true, - "license": "ISC" - }, "node_modules/form-data": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -4839,6 +5601,16 @@ "node": ">= 0.12" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "license": "MIT", @@ -4848,16 +5620,33 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/fromentries": { + "version": "1.3.2", + "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" + } + ], + "license": "MIT" + }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + "license": "MIT" }, "node_modules/fs-find": { "version": "0.4.0", @@ -4888,8 +5677,6 @@ }, "node_modules/function.prototype.name": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -4908,14 +5695,11 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", "optional": true }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4934,16 +5718,6 @@ "node": ">=12" } }, - "node_modules/gaxios/node_modules/is-stream": { - "version": "2.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gcp-metadata": { "version": "5.0.1", "license": "Apache-2.0", @@ -4970,6 +5744,26 @@ "version": "2.20.3", "license": "MIT" }, + "node_modules/genkit": { + "version": "1.1.0", + "license": "Apache-2.0", + "dependencies": { + "@genkit-ai/ai": "1.1.0", + "@genkit-ai/core": "1.1.0", + "uuid": "^10.0.0" + } + }, + "node_modules/genkit/node_modules/uuid": { + "version": "10.0.0", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "dev": true, @@ -4987,17 +5781,15 @@ }, "node_modules/get-func-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-intrinsic": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", @@ -5025,10 +5817,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-port": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -5050,8 +5851,6 @@ }, "node_modules/get-symbol-description": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -5067,8 +5866,7 @@ }, "node_modules/github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + "license": "MIT" }, "node_modules/glob": { "version": "7.1.5", @@ -5095,8 +5893,6 @@ }, "node_modules/globalthis": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "license": "MIT", "dependencies": { "define-properties": "^1.2.1", @@ -5129,8 +5925,7 @@ }, "node_modules/google-gax": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.2.tgz", - "integrity": "sha512-2mw7qgei2LPdtGrmd1zvxQviOcduTnsvAWYzCxhOWXK4IQKmQztHnDQwD0ApB690fBQJemFKSU7DnceAy3RLzw==", + "license": "Apache-2.0", "dependencies": { "@grpc/grpc-js": "~1.10.0", "@grpc/proto-loader": "^0.7.0", @@ -5151,8 +5946,7 @@ }, "node_modules/google-gax/node_modules/agent-base": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -5162,8 +5956,7 @@ }, "node_modules/google-gax/node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -5178,8 +5971,7 @@ }, "node_modules/google-gax/node_modules/gaxios": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.5.0.tgz", - "integrity": "sha512-R9QGdv8j4/dlNoQbX3hSaK/S0rkMijqjVvW3YM06CoBdbU/VdKd159j4hePpng0KuE6Lh6JJ7UdmVGJZFcAG1w==", + "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -5193,8 +5985,7 @@ }, "node_modules/google-gax/node_modules/gcp-metadata": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", "dependencies": { "gaxios": "^6.0.0", "json-bigint": "^1.0.0" @@ -5205,8 +5996,7 @@ }, "node_modules/google-gax/node_modules/google-auth-library": { "version": "9.8.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.8.0.tgz", - "integrity": "sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==", + "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -5221,8 +6011,7 @@ }, "node_modules/google-gax/node_modules/gtoken": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -5233,36 +6022,22 @@ }, "node_modules/google-gax/node_modules/https-proxy-agent": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/google-gax/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 14" } }, "node_modules/google-gax/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==" + "license": "MIT" }, "node_modules/google-gax/node_modules/retry-request": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", "dependencies": { "@types/request": "^2.48.8", "extend": "^3.0.2", @@ -5274,8 +6049,7 @@ }, "node_modules/google-gax/node_modules/teeny-request": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", "dependencies": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -5289,8 +6063,7 @@ }, "node_modules/google-gax/node_modules/teeny-request/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "dependencies": { "debug": "4" }, @@ -5300,8 +6073,7 @@ }, "node_modules/google-gax/node_modules/teeny-request/node_modules/https-proxy-agent": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -5312,20 +6084,17 @@ }, "node_modules/google-gax/node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/google-logging-utils": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -5346,8 +6115,7 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5372,10 +6140,27 @@ "node": ">=12.0.0" } }, + "node_modules/handlebars": { + "version": "4.7.8", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-bigints": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5393,8 +6178,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -5405,8 +6188,6 @@ }, "node_modules/has-proto": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.0" @@ -5420,8 +6201,7 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5431,8 +6211,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -5445,14 +6223,26 @@ } }, "node_modules/hasha": { - "version": "3.0.0", + "version": "5.2.2", "dev": true, "license": "MIT", "dependencies": { - "is-stream": "^1.0.1" + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" } }, "node_modules/hasown": { @@ -5465,15 +6255,8 @@ "node": ">= 0.4" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "dev": true, - "license": "ISC" - }, "node_modules/html-entities": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", "funding": [ { "type": "github", @@ -5493,8 +6276,7 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5508,8 +6290,7 @@ }, "node_modules/http-parser-js": { "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "5.0.0", @@ -5608,6 +6389,16 @@ ], "license": "BSD-3-Clause" }, + "node_modules/import-in-the-middle": { + "version": "1.13.1", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.1.0", "dev": true, @@ -5626,41 +6417,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", + "node_modules/imurmurhash": { + "version": "0.1.4", "dev": true, "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { - "node": ">=8" + "node": ">=0.8.19" } }, - "node_modules/import-local/node_modules/path-exists": { + "node_modules/indent-string": { "version": "4.0.0", "dev": true, "license": "MIT", @@ -5668,25 +6433,6 @@ "node": ">=8" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, "node_modules/inflight": { "version": "1.0.6", "license": "ISC", @@ -5701,8 +6447,7 @@ }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "license": "ISC" }, "node_modules/inquirer": { "version": "6.5.2", @@ -5728,8 +6473,6 @@ }, "node_modules/internal-slot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5756,8 +6499,6 @@ }, "node_modules/is-array-buffer": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -5778,8 +6519,6 @@ }, "node_modules/is-async-function": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "license": "MIT", "dependencies": { "async-function": "^1.0.0", @@ -5797,8 +6536,6 @@ }, "node_modules/is-bigint": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "license": "MIT", "dependencies": { "has-bigints": "^1.0.2" @@ -5812,8 +6549,6 @@ }, "node_modules/is-boolean-object": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -5828,8 +6563,6 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5840,7 +6573,6 @@ }, "node_modules/is-core-module": { "version": "2.13.1", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.0" @@ -5851,8 +6583,6 @@ }, "node_modules/is-data-view": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5868,8 +6598,6 @@ }, "node_modules/is-date-object": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5884,8 +6612,6 @@ }, "node_modules/is-finalizationregistry": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -5914,8 +6640,6 @@ }, "node_modules/is-generator-function": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -5932,8 +6656,6 @@ }, "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5944,17 +6666,14 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -5969,8 +6688,6 @@ }, "node_modules/is-regex": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5987,8 +6704,6 @@ }, "node_modules/is-set": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5999,8 +6714,6 @@ }, "node_modules/is-shared-array-buffer": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -6013,17 +6726,17 @@ } }, "node_modules/is-stream": { - "version": "1.1.0", - "dev": true, + "version": "2.0.1", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -6038,8 +6751,6 @@ }, "node_modules/is-symbol": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -6055,8 +6766,6 @@ }, "node_modules/is-typed-array": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -6068,10 +6777,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/is-weakmap": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -6082,8 +6794,6 @@ }, "node_modules/is-weakref": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -6097,8 +6807,6 @@ }, "node_modules/is-weakset": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -6111,10 +6819,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "node_modules/isexe": { @@ -6123,114 +6837,131 @@ "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "2.0.5", + "version": "3.2.2", "dev": true, "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/istanbul-lib-hook": { - "version": "2.0.7", + "version": "3.0.0", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "append-transform": "^1.0.0" + "append-transform": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "3.3.0", + "version": "6.0.3", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/istanbul-lib-report": { - "version": "2.0.8", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.1", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "2.1.0", + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/istanbul-lib-report/node_modules/pify": { - "version": "4.0.1", + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "5.7.2", + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "6.1.0", + "version": "7.2.0", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/istanbul-lib-source-maps": { - "version": "3.0.6", + "version": "4.0.1", "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", + "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.3.4", + "version": "4.4.0", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -6241,48 +6972,21 @@ } } }, - "node_modules/istanbul-lib-source-maps/node_modules/make-dir": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.2", + "version": "2.1.3", "dev": true, "license": "MIT" }, - "node_modules/istanbul-lib-source-maps/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/istanbul-reports": { - "version": "2.2.7", + "version": "3.1.7", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "html-escaper": "^2.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/jest": { @@ -7390,14 +8094,6 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -7822,8 +8518,7 @@ }, "node_modules/jose": { "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -7863,19 +8558,21 @@ "bignumber.js": "^9.0.0" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, "license": "MIT" }, + "node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -8014,38 +8711,23 @@ "node": ">=6" } }, - "node_modules/limiter": { - "version": "1.1.5" - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, + "node_modules/limiter": { + "version": "1.1.5" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, "node_modules/locate-path": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/lodash": { @@ -8054,8 +8736,7 @@ }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", @@ -8071,10 +8752,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "license": "MIT" + }, "node_modules/long": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "license": "Apache-2.0" }, "node_modules/loupe": { "version": "2.3.6", @@ -8157,36 +8841,25 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/merge-descriptors": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-source-map": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.6.1" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -8201,9 +8874,8 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -8214,8 +8886,7 @@ }, "node_modules/mime": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", "optional": true, "bin": { "mime": "cli.js" @@ -8251,8 +8922,7 @@ }, "node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -8290,8 +8960,7 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + "license": "MIT" }, "node_modules/mocked-env": { "version": "1.3.5", @@ -8328,10 +8997,13 @@ "dev": true, "license": "MIT" }, + "node_modules/module-details-from-path": { + "version": "1.0.3", + "license": "MIT" + }, "node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.7", @@ -8339,8 +9011,7 @@ }, "node_modules/napi-build-utils": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -8354,15 +9025,13 @@ "node": ">= 0.6" } }, - "node_modules/nested-error-stacks": { - "version": "2.1.1", - "dev": true, + "node_modules/neo-async": { + "version": "2.6.2", "license": "MIT" }, "node_modules/node-abi": { "version": "3.60.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.60.0.tgz", - "integrity": "sha512-zcGgwoXbzw9NczqbGzAWL/ToDYAxv1V8gL1D67ClbdkIfeeDBbY0GelZtC25ayLvVjr2q2cloHeQV1R0QAWqRQ==", + "license": "MIT", "dependencies": { "semver": "^7.3.5" }, @@ -8372,8 +9041,7 @@ }, "node_modules/node-abi/node_modules/semver": { "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -8386,13 +9054,28 @@ }, "node_modules/node-addon-api": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8408,22 +9091,6 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-forge": { "version": "1.3.1", "license": "(BSD-3-Clause OR GPL-2.0)", @@ -8436,29 +9103,21 @@ "dev": true, "license": "MIT" }, - "node_modules/node-releases": { - "version": "2.0.14", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", + "node_modules/node-preload": { + "version": "0.2.1", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", + "node_modules/node-releases": { + "version": "2.0.14", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -8480,118 +9139,183 @@ } }, "node_modules/nyc": { - "version": "14.1.1", + "version": "17.1.0", "dev": true, "license": "ISC", "dependencies": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^3.3.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^6.0.2", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" }, "bin": { "nyc": "bin/nyc.js" }, "engines": { - "node": ">=6" + "node": ">=18" + } + }, + "node_modules/nyc/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/nyc/node_modules/cliui": { - "version": "5.0.0", + "version": "6.0.0", "dev": true, "license": "ISC", "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/nyc/node_modules/emoji-regex": { - "version": "7.0.3", + "node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", "dev": true, "license": "MIT" }, - "node_modules/nyc/node_modules/make-dir": { - "version": "2.1.0", + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "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": ">=6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/nyc/node_modules/pify": { - "version": "4.0.1", + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/semver": { - "version": "5.7.2", + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", "dev": true, "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, "bin": { - "semver": "bin/semver" + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/nyc/node_modules/string-width": { - "version": "3.1.0", + "version": "4.2.3", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/nyc/node_modules/uuid": { - "version": "3.4.0", + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, "license": "MIT", - "bin": { - "uuid": "bin/uuid" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/nyc/node_modules/wrap-ansi": { - "version": "5.1.0", + "version": "6.2.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/nyc/node_modules/y18n": { @@ -8600,20 +9324,24 @@ "license": "ISC" }, "node_modules/nyc/node_modules/yargs": { - "version": "13.3.2", + "version": "15.4.1", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^3.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" } }, "node_modules/object-assign": { @@ -8625,16 +9353,14 @@ }, "node_modules/object-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/object-inspect": { "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8644,8 +9370,6 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8653,8 +9377,6 @@ }, "node_modules/object.assign": { "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -8673,8 +9395,7 @@ }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -8703,14 +9424,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "license": "MIT", @@ -8720,8 +9433,6 @@ }, "node_modules/own-keys": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.6", @@ -8770,14 +9481,25 @@ } }, "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.0.0" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/p-timeout": { @@ -8799,45 +9521,36 @@ } }, "node_modules/package-hash": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "license": "ISC", "dependencies": { "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", + "hasha": "^5.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/partial-json": { + "version": "0.1.7", + "license": "MIT" + }, "node_modules/path-exists": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { @@ -8855,26 +9568,13 @@ "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" - }, - "node_modules/path-type": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", @@ -8900,14 +9600,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/pirates": { "version": "4.0.6", "dev": true, @@ -8917,20 +9609,18 @@ } }, "node_modules/pkg-dir": { - "version": "3.0.0", + "version": "4.2.0", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^3.0.0" + "find-up": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/possible-typed-array-names": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8938,8 +9628,7 @@ }, "node_modules/prebuild-install": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -8992,6 +9681,17 @@ "node": ">= 0.6.0" } }, + "node_modules/process-on-spawn": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/prompts": { "version": "2.4.2", "dev": true, @@ -9006,8 +9706,7 @@ }, "node_modules/proto3-json-serializer": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", - "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "license": "Apache-2.0", "dependencies": { "protobufjs": "^7.2.5" }, @@ -9054,8 +9753,7 @@ }, "node_modules/pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9078,8 +9776,7 @@ }, "node_modules/qs": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -9097,16 +9794,14 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9119,8 +9814,7 @@ }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -9133,8 +9827,7 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9144,31 +9837,6 @@ "dev": true, "license": "MIT" }, - "node_modules/read-pkg": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/readable-stream": { "version": "4.2.0", "license": "MIT", @@ -9184,8 +9852,6 @@ }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9206,8 +9872,6 @@ }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9242,6 +9906,44 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.4.0", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/require-in-the-middle/node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, "node_modules/require-main-filename": { "version": "2.0.0", "dev": true, @@ -9249,7 +9951,6 @@ }, "node_modules/resolve": { "version": "1.22.8", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -9274,7 +9975,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "dev": true, "license": "MIT", @@ -9282,14 +9983,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve.exports": { "version": "2.0.2", "dev": true, @@ -9328,8 +10021,7 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "optional": true, "engines": { "node": ">= 4" @@ -9395,8 +10087,6 @@ }, "node_modules/safe-array-concat": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9432,8 +10122,6 @@ }, "node_modules/safe-push-apply": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -9448,8 +10136,6 @@ }, "node_modules/safe-regex-test": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -9477,8 +10163,7 @@ }, "node_modules/send": { "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9500,16 +10185,14 @@ }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/send/node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -9519,13 +10202,11 @@ }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "license": "MIT" }, "node_modules/serve-static": { "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -9543,8 +10224,6 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -9560,8 +10239,6 @@ }, "node_modules/set-function-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -9575,8 +10252,6 @@ }, "node_modules/set-proto": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -9589,8 +10264,7 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -9611,10 +10285,13 @@ "node": ">=8" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "license": "BSD-2-Clause" + }, "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -9631,8 +10308,7 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -9646,8 +10322,7 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -9663,8 +10338,7 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -9685,8 +10359,6 @@ }, "node_modules/simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -9700,12 +10372,11 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", @@ -9720,6 +10391,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", @@ -9741,7 +10413,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -9757,45 +10428,60 @@ } }, "node_modules/spawn-wrap": { - "version": "1.4.3", + "version": "2.0.0", "dev": true, "license": "ISC", "dependencies": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "which": "^1.3.0" + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/spdx-correct": { - "version": "3.1.1", + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", "dev": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", + "node_modules/spawn-wrap/node_modules/make-dir": { + "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", "dev": true, - "license": "CC0-1.0" + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/sprintf-js": { "version": "1.0.3", @@ -9830,8 +10516,7 @@ }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -9845,8 +10530,7 @@ }, "node_modules/stream-shift": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -9916,8 +10600,6 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9937,8 +10619,6 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9955,8 +10635,6 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -9981,11 +10659,11 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-final-newline": { @@ -10009,8 +10687,7 @@ }, "node_modules/strnum": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT", "optional": true }, "node_modules/stubs": { @@ -10029,7 +10706,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10040,8 +10716,7 @@ }, "node_modules/tar-fs": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "license": "MIT", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -10051,8 +10726,7 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -10066,8 +10740,7 @@ }, "node_modules/tar-stream/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -10099,17 +10772,16 @@ } }, "node_modules/test-exclude": { - "version": "5.2.3", + "version": "6.0.0", "dev": true, "license": "ISC", "dependencies": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/through": { @@ -10141,9 +10813,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10153,16 +10824,17 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, "node_modules/traverse": { "version": "0.6.11", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz", - "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==", "license": "MIT", "dependencies": { "gopd": "^1.2.0", @@ -10275,8 +10947,7 @@ }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" }, @@ -10305,8 +10976,7 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -10324,8 +10994,6 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -10338,8 +11006,6 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -10357,8 +11023,6 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -10378,8 +11042,6 @@ }, "node_modules/typed-array-length": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -10396,10 +11058,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/typedarray.prototype.slice": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", - "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -10430,10 +11098,19 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -10450,13 +11127,11 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10533,15 +11208,6 @@ "dev": true, "license": "MIT" }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/vary": { "version": "1.1.2", "license": "MIT", @@ -10557,10 +11223,20 @@ "makeerror": "1.0.12" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -10572,27 +11248,35 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { - "version": "1.3.1", + "version": "2.0.2", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/which-boxed-primitive": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "license": "MIT", "dependencies": { "is-bigint": "^1.1.0", @@ -10610,8 +11294,6 @@ }, "node_modules/which-builtin-type": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -10637,8 +11319,6 @@ }, "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "license": "MIT", "dependencies": { "is-map": "^2.0.3", @@ -10654,14 +11334,12 @@ } }, "node_modules/which-module": { - "version": "2.0.0", + "version": "2.0.1", "dev": true, "license": "ISC" }, "node_modules/which-typed-array": { "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -10678,10 +11356,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10696,16 +11377,14 @@ }, "node_modules/wrap-ansi/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==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/wrap-ansi/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==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -10718,8 +11397,7 @@ }, "node_modules/wrap-ansi/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==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -10729,21 +11407,18 @@ }, "node_modules/wrap-ansi/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==" + "license": "MIT" }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10755,8 +11430,7 @@ }, "node_modules/wrap-ansi/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==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10769,13 +11443,14 @@ "license": "ISC" }, "node_modules/write-file-atomic": { - "version": "2.4.3", + "version": "3.0.3", "dev": true, "license": "ISC", "dependencies": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "node_modules/y18n": { @@ -10789,10 +11464,19 @@ "version": "4.0.0", "license": "ISC" }, + "node_modules/yaml": { + "version": "2.7.0", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -10807,34 +11491,34 @@ } }, "node_modules/yargs-parser": { - "version": "13.1.2", + "version": "18.1.3", "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/yargs/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==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10846,8 +11530,7 @@ }, "node_modules/yargs/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==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10857,8 +11540,7 @@ }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -10881,6 +11563,20 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.24.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.3", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } } } } diff --git a/firestore-bigquery-export/scripts/gen-schema-view/package.json b/firestore-bigquery-export/scripts/gen-schema-view/package.json index 0c105a49b..950653d08 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/package.json +++ b/firestore-bigquery-export/scripts/gen-schema-view/package.json @@ -1,6 +1,6 @@ { "name": "@firebaseextensions/fs-bq-schema-views", - "version": "0.4.9", + "version": "0.4.10", "description": "Generate strongly-typed BigQuery Views based on raw JSON", "main": "./lib/index.js", "repository": { @@ -31,13 +31,15 @@ "author": "Jan Wyszynski ", "license": "Apache-2.0", "dependencies": { - "@firebaseextensions/firestore-bigquery-change-tracker": "^1.1.36", + "@firebaseextensions/firestore-bigquery-change-tracker": "^1.1.38", + "@genkit-ai/googleai": "^1.1.0", "@google-cloud/bigquery": "^6.0.3", "commander": "5.0.0", "firebase-admin": "^12.1.0", "firebase-functions": "^4.2.0", "fs-find": "^0.4.0", "generate-schema": "^2.6.0", + "genkit": "^1.1.0", "glob": "7.1.5", "inquirer": "^6.4.0", "sql-formatter": "^2.3.3" @@ -46,15 +48,16 @@ "@types/chai": "^4.1.6", "@types/express": "^4.17.14", "@types/express-serve-static-core": "4.17.30", + "@types/inquirer": "^9.0.7", + "@types/jest": "29.5.0", "chai": "^4.2.0", "exec": "^0.2.1", - "nyc": "^14.0.0", - "rimraf": "^2.6.3", - "ts-node": "^7.0.1", - "typescript": "^4.9.3", - "@types/jest": "29.5.0", "jest": "29.5.0", "mocked-env": "^1.3.2", - "ts-jest": "29.1.2" + "nyc": "^17.1.0", + "rimraf": "^2.6.3", + "ts-jest": "29.1.2", + "ts-node": "^7.0.1", + "typescript": "^4.9.3" } } diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/index.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/index.test.ts new file mode 100644 index 000000000..b7597bca9 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/index.test.ts @@ -0,0 +1,261 @@ +import { parseConfig } from "../../../src/config"; +import { promptInquirer } from "../../../src/config/interactive"; +import { + parseProgram, + validateNonInteractiveParams, +} from "../../../src/config/non-interactive"; +import { readSchemas } from "../../../src/schema-loader-utils"; + +// Mock dependencies +jest.mock("../../../src/config/interactive", () => ({ + promptInquirer: jest.fn(), +})); + +jest.mock("../../../src/config/non-interactive", () => ({ + parseProgram: jest.fn(), + validateNonInteractiveParams: jest.fn(), +})); + +jest.mock("../../../src/schema-loader-utils", () => ({ + readSchemas: jest.fn(), +})); + +// Mock process.exit to prevent tests from actually exiting +const mockExit = jest.spyOn(process, "exit").mockImplementation((code) => { + throw new Error(`Process exited with code ${code}`); +}); + +describe("parseConfig", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("Non-interactive mode", () => { + it("should return CLI config from command line arguments", async () => { + // Setup mocks for non-interactive mode + const mockProgram = { + nonInteractive: true, + project: "test-project", + bigQueryProject: "test-bq-project", + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: ["schema1.json", "schema2.json"], + outputHelp: jest.fn(), + }; + + const mockSchemas = { + schema1: { fields: { field1: { type: "string" } } }, + schema2: { fields: { field2: { type: "number" } } }, + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (validateNonInteractiveParams as jest.Mock).mockReturnValue(true); + (readSchemas as jest.Mock).mockReturnValue(mockSchemas); + + const result = await parseConfig(); + + expect(parseProgram).toHaveBeenCalled(); + expect(validateNonInteractiveParams).toHaveBeenCalledWith(mockProgram); + expect(readSchemas).toHaveBeenCalledWith(mockProgram.schemaFiles); + expect(result).toEqual({ + agentSampleSize: 100, + projectId: "test-project", + bigQueryProjectId: "test-bq-project", + datasetId: "test-dataset", + tableNamePrefix: "test-prefix", + schemas: mockSchemas, + geminiAnalyzeCollectionPath: undefined, + googleAiKey: undefined, + schemaDirectory: undefined, + useGemini: false, + }); + }); + + it("should use project as bigQueryProject if not specified", async () => { + // Setup mocks with missing bigQueryProject + const mockProgram = { + nonInteractive: true, + project: "test-project", + bigQueryProject: undefined, + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: ["schema.json"], + outputHelp: jest.fn(), + }; + + const mockSchemas = { schema: { fields: { field: { type: "string" } } } }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (validateNonInteractiveParams as jest.Mock).mockReturnValue(true); + (readSchemas as jest.Mock).mockReturnValue(mockSchemas); + + const result = await parseConfig(); + + expect(result.bigQueryProjectId).toBe("test-project"); + }); + + it("should use gemini if specified", async () => { + // Setup mocks with useGemini = true + const mockProgram = { + nonInteractive: true, + project: "test-project", + bigQueryProject: "test-bq-project", + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: ["schema.json"], + useGemini: "test-collection", + googleAiKey: "test-key", + geminiAnalyzeCollectionPath: "test-collection", + schemaDirectory: "test-directory", + outputHelp: jest.fn(), + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (validateNonInteractiveParams as jest.Mock).mockReturnValue(true); + + const result = await parseConfig(); + + expect(result.useGemini).toBe(true); + expect(result.googleAiKey).toBe("test-key"); + expect(result.geminiAnalyzeCollectionPath).toBe("test-collection"); + expect(result.schemaDirectory).toBe("test-directory"); + expect(result.agentSampleSize).toBe(100); + }); + + it("should exit if required parameters are missing", async () => { + const mockProgram = { + nonInteractive: true, + outputHelp: jest.fn(), + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (validateNonInteractiveParams as jest.Mock).mockReturnValue(false); + + await expect(parseConfig()).rejects.toThrow("Process exited with code 1"); + expect(mockProgram.outputHelp).toHaveBeenCalled(); + expect(mockExit).toHaveBeenCalledWith(1); + }); + }); + + describe("Interactive mode without Gemini", () => { + it("should return CLI config from inquirer prompts", async () => { + // Setup mocks for interactive mode + const mockProgram = { + nonInteractive: false, + }; + + const mockPromptResponse = { + projectId: "interactive-project", + bigQueryProjectId: "interactive-bq-project", + datasetId: "interactive-dataset", + tableNamePrefix: "interactive-prefix", + useGemini: false, + schemaFiles: "schema1.json, schema2.json", + }; + + const mockSchemas = { + schema1: { fields: { field1: { type: "string" } } }, + schema2: { fields: { field2: { type: "number" } } }, + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (promptInquirer as jest.Mock).mockResolvedValue(mockPromptResponse); + (readSchemas as jest.Mock).mockReturnValue(mockSchemas); + + const result = await parseConfig(); + + expect(parseProgram).toHaveBeenCalled(); + expect(promptInquirer).toHaveBeenCalled(); + // Expect the schemaFiles string to be passed as-is in an array + expect(readSchemas).toHaveBeenCalledWith(["schema1.json, schema2.json"]); + expect(result).toEqual({ + agentSampleSize: 100, + projectId: "interactive-project", + bigQueryProjectId: "interactive-bq-project", + datasetId: "interactive-dataset", + tableNamePrefix: "interactive-prefix", + schemas: mockSchemas, + geminiAnalyzeCollectionPath: undefined, + googleAiKey: undefined, + schemaDirectory: undefined, + useGemini: false, + }); + }); + + it("should properly handle schema file paths without trimming or splitting", async () => { + const mockProgram = { + nonInteractive: false, + }; + + const mockPromptResponse = { + project: "test-project", + bigQueryProject: "test-bq-project", + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + useGemini: false, + schemaFiles: " schema1.json, schema2.json , schema3.json", + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (promptInquirer as jest.Mock).mockResolvedValue(mockPromptResponse); + (readSchemas as jest.Mock).mockReturnValue({}); + + await parseConfig(); + + // Verify that the schemaFiles string is passed as-is within an array + expect(readSchemas).toHaveBeenCalledWith([ + " schema1.json, schema2.json , schema3.json", + ]); + }); + }); + + describe("Interactive mode with Gemini", () => { + it("should return CLI config from inquirer prompts", async () => { + // Setup mocks for interactive mode + const mockProgram = { + nonInteractive: false, + }; + + const mockPromptResponse = { + projectId: "interactive-project", + bigQueryProjectId: "interactive-bq-project", + datasetId: "interactive-dataset", + tableNamePrefix: "interactive-prefix", + useGemini: true, + googleAiKey: "test-key", + geminiAnalyzeCollectionPath: "test-collection", + schemaDirectory: "test-directory", + }; + + // Although we set up mockSchemas, in Gemini mode readSchemas is not called. + const mockSchemas = { + schema1: { fields: { field1: { type: "string" } } }, + schema2: { fields: { field2: { type: "number" } } }, + }; + + (parseProgram as jest.Mock).mockReturnValue(mockProgram); + (promptInquirer as jest.Mock).mockResolvedValue(mockPromptResponse); + (readSchemas as jest.Mock).mockReturnValue(mockSchemas); + + const result = await parseConfig(); + + expect(parseProgram).toHaveBeenCalled(); + expect(promptInquirer).toHaveBeenCalled(); + // In Gemini mode, schemaFiles may not be provided so readSchemas should not be called + expect(readSchemas).not.toHaveBeenCalled(); + // Expect schemas to be an empty object in Gemini mode + expect(result).toEqual({ + agentSampleSize: 100, + projectId: "interactive-project", + bigQueryProjectId: "interactive-bq-project", + datasetId: "interactive-dataset", + tableNamePrefix: "interactive-prefix", + schemas: {}, + geminiAnalyzeCollectionPath: "test-collection", + googleAiKey: "test-key", + schemaDirectory: "test-directory", + useGemini: true, + }); + }); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/interactive.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/interactive.test.ts new file mode 100644 index 000000000..46fa7672a --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/interactive.test.ts @@ -0,0 +1,245 @@ +import { + describe, + it, + expect, + beforeEach, + jest, + afterEach, +} from "@jest/globals"; + +// Mock inquirer before importing any modules +jest.mock("inquirer", () => ({ + prompt: jest.fn(), +})); + +// Import the modules after mocks are set up +import { questions, promptInquirer } from "../../config/interactive"; +import inquirer from "inquirer"; + +describe("Interactive Prompts", () => { + // Reset mocks before each test + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("questions array", () => { + it("should have the correct number of questions", () => { + expect(questions).toHaveLength(10); + }); + + it("should have properly formatted questions with required properties", () => { + questions.forEach((question) => { + expect(question).toHaveProperty("message"); + expect(question).toHaveProperty("name"); + expect(question).toHaveProperty("type"); + }); + }); + + it("should have proper validation for project ID question", () => { + const projectQuestion = questions.find((q) => q.name === "projectId"); + expect(projectQuestion).toBeDefined(); + + // Test validation function + const validate = projectQuestion.validate; + + // Empty value should return error message + expect(validate("")).toBe("Please supply a project ID"); + + // Invalid characters should return error message + expect(validate("project/with/slashes")).toBe( + "The project ID must only contain letters or spaces" + ); + + // Valid value should return true + expect(validate("valid-project-id")).toBe(true); + }); + + it("should have proper validation for BigQuery project ID question", () => { + const bigQueryQuestion = questions.find( + (q) => q.name === "bigQueryProjectId" + ); + expect(bigQueryQuestion).toBeDefined(); + + // Test validation function + const validate = bigQueryQuestion.validate; + + // Empty value should return error message + expect(validate("")).toBe("Please supply a BigQuery project ID"); + + // Invalid characters should return error message + expect(validate("UPPERCASE_PROJECT")).toBe( + "The BigQuery project ID must only contain letters or spaces" + ); + expect(validate("123-starts-with-number")).toBe( + "The BigQuery project ID must only contain letters or spaces" + ); + + // Valid value should return true + expect(validate("valid-project-id")).toBe(true); + }); + + it("should have proper validation for dataset ID question", () => { + const datasetQuestion = questions.find((q) => q.name === "datasetId"); + expect(datasetQuestion).toBeDefined(); + + // Test validation function + const validate = datasetQuestion.validate; + + // Empty value should return error message + expect(validate("")).toBe("Please supply a dataset ID"); + + // Invalid characters should return error message + expect(validate("dataset-with-hyphens")).toBe( + "The dataset ID must only contain letters or spaces" + ); + + // Valid value should return true + expect(validate("valid_dataset_id")).toBe(true); + }); + + it("should have proper validation for table name prefix question", () => { + const prefixQuestion = questions.find( + (q) => q.name === "tableNamePrefix" + ); + expect(prefixQuestion).toBeDefined(); + + // Test validation function + const validate = prefixQuestion.validate; + + // Empty value should return error message + expect(validate("")).toBe("Please supply a table name prefix"); + + // Invalid characters should return error message + expect(validate("prefix-with-hyphens")).toBe( + "The table name prefix must only contain letters or spaces" + ); + + // Valid value should return true + expect(validate("valid_prefix_123")).toBe(true); + }); + + it("should conditionally show schema files question when not using Gemini", () => { + const schemaFilesQuestion = questions.find( + (q) => q.name === "schemaFiles" + ); + expect(schemaFilesQuestion).toBeDefined(); + + // Test when function + const when = schemaFilesQuestion.when; + + // Should show when useGemini is false + expect(when({ useGemini: false })).toBe(true); + + // Should not show when useGemini is true + expect(when({ useGemini: true })).toBe(false); + }); + + it("should conditionally show Google AI API Key question when using Gemini", () => { + const apiKeyQuestion = questions.find((q) => q.name === "googleAiKey"); + expect(apiKeyQuestion).toBeDefined(); + + // Test when function + const when = apiKeyQuestion.when; + + // Should show when useGemini is true + expect(when({ useGemini: true })).toBe(true); + + // Should not show when useGemini is false + expect(when({ useGemini: false })).toBe(false); + + // Test validation + const validate = apiKeyQuestion.validate; + expect(validate("")).toBe("Google AI API Key is required"); + expect(validate("valid-api-key")).toBe(true); + }); + + it("should conditionally show collection path question when using Gemini", () => { + const collectionPathQuestion = questions.find( + (q) => q.name === "geminiAnalyzeCollectionPath" + ); + expect(collectionPathQuestion).toBeDefined(); + + // Test when function + const when = collectionPathQuestion.when; + + // Should show when useGemini is true + expect(when({ useGemini: true })).toBe(true); + + // Should not show when useGemini is false + expect(when({ useGemini: false })).toBe(false); + }); + + it("should conditionally show schema directory question with default value when using Gemini", () => { + const schemaDirQuestion = questions.find( + (q) => q.name === "schemaDirectory" + ); + expect(schemaDirQuestion).toBeDefined(); + + // Test when function + const when = schemaDirQuestion.when; + + // Should show when useGemini is true + expect(when({ useGemini: true })).toBe(true); + + // Should not show when useGemini is false + expect(when({ useGemini: false })).toBe(false); + + // Should have default value + expect(schemaDirQuestion.default).toBe("./schemas"); + }); + }); + + describe("promptInquirer function", () => { + it("should call inquirer.prompt with questions array", async () => { + // Setup mock return value + const mockAnswers = { project: "test-project" }; + ( + inquirer.prompt as jest.MockedFunction + ).mockResolvedValueOnce(mockAnswers); + + // Call the function + const result = await promptInquirer(); + + // Verify inquirer.prompt was called with questions + expect(inquirer.prompt).toHaveBeenCalledWith(questions); + + // Verify the function returns the mock answers + expect(result).toEqual(mockAnswers); + }); + + it("should propagate errors from inquirer.prompt", async () => { + // Setup mock to throw error + const mockError = new Error("Prompt failed"); + ( + inquirer.prompt as jest.MockedFunction + ).mockRejectedValueOnce(mockError); + + // Call the function and expect it to throw + await expect(promptInquirer()).rejects.toThrow("Prompt failed"); + }); + }); + + describe("validateInput function (indirectly tested through questions)", () => { + it("should handle various input cases for text validation", () => { + // Get validation functions from questions to test the validateInput indirectly + const projectValidate = questions.find( + (q) => q.name === "projectId" + ).validate; + + // Test empty values + expect(projectValidate("")).toBe("Please supply a project ID"); + expect(projectValidate(null)).toBe("Please supply a project ID"); + expect(projectValidate(undefined)).toBe("Please supply a project ID"); + expect(projectValidate(" ")).toBe("Please supply a project ID"); + + // Test invalid values (with slashes for Firestore validation) + expect(projectValidate("invalid/path")).toBe( + "The project ID must only contain letters or spaces" + ); + + // Test valid values + expect(projectValidate("valid-project")).toBe(true); + expect(projectValidate("another_valid_project")).toBe(true); + }); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/non-interactive.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/non-interactive.test.ts new file mode 100644 index 000000000..8a4bf0942 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/config/non-interactive.test.ts @@ -0,0 +1,268 @@ +import { + describe, + it, + expect, + beforeEach, + jest, + afterEach, +} from "@jest/globals"; + +// Mock package.json before importing any modules +jest.mock( + "../../../package.json", + () => ({ + description: "Test Description", + version: "1.0.0", + }), + { virtual: true } +); + +// Mock commander before importing any modules +jest.mock("commander", () => { + return { + name: jest.fn().mockReturnThis(), + description: jest.fn().mockReturnThis(), + version: jest.fn().mockReturnThis(), + option: jest.fn().mockReturnThis(), + parse: jest.fn().mockReturnThis(), + }; +}); + +// Import the modules after all mocks are set up +import { + collect, + configureProgram, + parseProgram, + validateNonInteractiveParams, +} from "../../config/non-interactive"; + +describe("Command Line Parser", () => { + describe("collect function", () => { + it("should add a value to an array", () => { + const previous = ["value1", "value2"]; + const result = collect("value3", previous); + expect(result).toEqual(["value1", "value2", "value3"]); + }); + + it("should handle empty arrays", () => { + const result = collect("value1", []); + expect(result).toEqual(["value1"]); + }); + }); + + describe("configureProgram function", () => { + let commander; + + beforeEach(() => { + // Get the mocked commander module + commander = require("commander"); + + // Clear all mocks + jest.clearAllMocks(); + }); + + it("should configure the program with all options", () => { + configureProgram(); + + expect(commander.name).toHaveBeenCalledWith("gen-schema-views"); + expect(commander.description).toHaveBeenCalledWith("Test Description"); + expect(commander.version).toHaveBeenCalledWith("1.0.0"); + + // Check that all options are configured + expect(commander.option).toHaveBeenCalledTimes(10); + + // Check specific options - just a sample to ensure we're setting up correctly + expect(commander.option).toHaveBeenCalledWith( + "--non-interactive", + "Parse all input from command line flags instead of prompting the caller.", + false + ); + + expect(commander.option).toHaveBeenCalledWith( + "-P, --project ", + "Firebase Project ID for project containing Cloud Firestore database." + ); + + expect(commander.option).toHaveBeenCalledWith( + "-f, --schema-files ", + "A collection of files from which to read schemas.", + collect, + [] + ); + }); + + it("should return the configured program", () => { + const result = configureProgram(); + // We're expecting the mock object to be returned + expect(result).toBe(commander); + }); + }); + + describe("parseProgram function", () => { + let commander; + const originalProcessArgv = process.argv; + + beforeEach(() => { + commander = require("commander"); + jest.clearAllMocks(); + // Mock process.argv + process.argv = ["node", "script.js", "-P", "test-project"]; + }); + + afterEach(() => { + // Restore original process.argv + process.argv = originalProcessArgv; + }); + + it("should configure and parse the program", () => { + const result = parseProgram(); + + expect(commander.parse).toHaveBeenCalledWith(process.argv); + expect(result).toBe(commander); + }); + }); + + describe("validateNonInteractiveParams function", () => { + it("should return true when all required parameters are present", () => { + const mockProgram = { + project: "test-project", + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: ["schema1.json", "schema2.json"], + }; + + const result = validateNonInteractiveParams(mockProgram); + expect(result).toBe(true); + }); + + it("should return false when project is missing", () => { + const mockProgram = { + project: undefined, + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: ["schema1.json"], + }; + + const result = validateNonInteractiveParams(mockProgram); + expect(result).toBe(false); + }); + + it("should return false when dataset is missing", () => { + const mockProgram = { + project: "test-project", + dataset: undefined, + tableNamePrefix: "test-prefix", + schemaFiles: ["schema1.json"], + }; + + const result = validateNonInteractiveParams(mockProgram); + expect(result).toBe(false); + }); + + it("should return false when tableNamePrefix is missing", () => { + const mockProgram = { + project: "test-project", + dataset: "test-dataset", + tableNamePrefix: undefined, + schemaFiles: ["schema1.json"], + }; + + const result = validateNonInteractiveParams(mockProgram); + expect(result).toBe(false); + }); + + it("should return false when schemaFiles is empty", () => { + const mockProgram = { + project: "test-project", + dataset: "test-dataset", + tableNamePrefix: "test-prefix", + schemaFiles: [], + }; + + const result = validateNonInteractiveParams(mockProgram); + expect(result).toBe(false); + }); + }); +}); + +// Skip integration tests for now since they need more configuration +describe.skip("Integration tests", () => { + const originalProcessArgv = process.argv; + + // Unmock commander for these tests + beforeEach(() => { + jest.resetModules(); + jest.unmock("commander"); + }); + + afterEach(() => { + // Restore original process.argv + process.argv = originalProcessArgv; + }); + + it("should correctly parse command line arguments", () => { + // Mock process.argv with realistic command line arguments + process.argv = [ + "node", + "script.js", + "-P", + "test-project", + "-B", + "test-bq-project", + "-d", + "test-dataset", + "-t", + "test-prefix", + "-f", + "schema1.json", + "-f", + "schema2.json", + "--schema-dir", + "./test-schemas", + ]; + + // Re-import the module + const { parseProgram } = require("../../config/non-interactive"); + + const program = parseProgram(); + + // Verify the parsed options + expect(program.opts().project).toBe("test-project"); + expect(program.opts().bigQueryProject).toBe("test-bq-project"); + expect(program.opts().dataset).toBe("test-dataset"); + expect(program.opts().tableNamePrefix).toBe("test-prefix"); + expect(program.opts().schemaFiles).toEqual([ + "schema1.json", + "schema2.json", + ]); + expect(program.opts().schemaDir).toBe("./test-schemas"); + expect(program.opts().nonInteractive).toBe(false); + }); + + it("should validate non-interactive parameters correctly", () => { + // Mock process.argv with all required parameters + process.argv = [ + "node", + "script.js", + "-P", + "test-project", + "-d", + "test-dataset", + "-t", + "test-prefix", + "-f", + "schema1.json", + ]; + + // Re-import the module + const { + parseProgram, + validateNonInteractiveParams, + } = require("../../config/non-interactive"); + + const program = parseProgram(); + const isValid = validateNonInteractiveParams(program.opts()); + + expect(isValid).toBe(true); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e.test.ts index c1ea4fb5a..148bf19ae 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e.test.ts +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e.test.ts @@ -1,242 +1,335 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import { jest } from "@jest/globals"; import { BigQuery } from "@google-cloud/bigquery"; import { getQueryResult, randomId, setupBQ } from "./helpers/setup"; -import executeScript from "./helpers/executeScript"; +import { FirestoreSchema } from "../../schema"; +import { CliConfig } from "../../config"; -const bq = new BigQuery({ projectId: "extensions-testing" }); +// Mock only the config module +jest.mock("../../config", () => ({ + parseConfig: jest.fn<() => Promise>(), +})); -const datasetPrefix = "e2e_test_"; - -describe("e2e", () => { - beforeEach(async () => { - /** Clear all bq datasets starting with test_ */ - const [datasets] = await bq.getDatasets(); +import { parseConfig } from "../../config"; +import { run } from "../.."; - const testDatasets = datasets.filter((d) => d.id.startsWith(datasetPrefix)); +const bq = new BigQuery({ projectId: "dev-extensions-testing" }); +const datasetPrefix = "e2e_test_"; - for (const dataset of testDatasets) { - console.log("Deleting dataset: ", dataset.id); - await dataset.delete({ force: true }); +async function verifySetupBQ( + datasetId: string, + tableId: string, + testData: any +) { + try { + const query = ` + SELECT data + FROM \`dev-extensions-testing.${datasetId}.${tableId}_raw_latest\` + LIMIT 1 + `; + + const [rows] = await bq.query({ query }); + + if (rows.length === 0) { + return { success: false, errors: ["No rows found in latest table"] }; } - }); - test("should generate a schame view based on a basic dataset and schema", async () => { - /** Set the schema to be tested */ - const schemaName = "basic"; + const rowData = JSON.parse(rows[0].data); + const success = Object.keys(testData).every( + (key) => JSON.stringify(rowData[key]) === JSON.stringify(testData[key]) + ); - /** Create the test for the db */ - const testData = { - name: "test", + return { + success, + errors: success ? [] : ["Data in table doesn't match expected test data"], }; + } catch (error) { + return { success: false, errors: [String(error)] }; + } +} - /** Generate Id */ - const id = randomId(); +describe("e2e (with real BigQuery)", () => { + let id: string; - /** Set the dataset and table names */ + beforeEach(async () => { + id = randomId(); + jest.clearAllMocks(); + }); + + test("should generate a schema view based on a basic dataset and schema", async () => { + const schemaName = "basic"; const datasetId = `${datasetPrefix}${id}`; const tableId = `table_${id}`; - /** Create dataset and table */ - const { dataset, rawChangeLogTable, rawLatestTable } = await setupBQ( - datasetId, - tableId, - testData - ); + const basicSchema: FirestoreSchema = { + fields: [{ name: "name", type: "string" }], + }; - console.log("Testing with dataset: ", dataset.id); - console.log("Testing with table: ", rawChangeLogTable.id); - console.log("Testing with table: ", rawLatestTable.id); + const testData = { name: "test" }; - /** await 5 seconds for the table to propogate */ - await new Promise((resolve) => setTimeout(resolve, 5000)); + const { dataset } = await setupBQ(datasetId, tableId, testData); - /** Run the gen-schema script */ - await executeScript(dataset.id, tableId, schemaName); + await new Promise((resolve) => setTimeout(resolve, 3000)); - console.log("Done executing"); + const verifySetup = await verifySetupBQ(datasetId, tableId, testData); + if (!verifySetup.success) + throw new Error(`Setup failed: ${verifySetup.errors.join(", ")}`); - /* wait 10 seconds for the view to propogate */ - await new Promise((resolve) => setTimeout(resolve, 10000)); + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId, + tableNamePrefix: tableId, + schemas: { [schemaName]: basicSchema }, + useGemini: false, + }); - /** Get the query result */ - const result = await getQueryResult(dataset.id, tableId, schemaName); + const result = await run(); + expect(result).toBe(0); - /** Assert data */ - expect(result.length).toBe(1); - expect(result[0].name).toBe("test"); - }, 80000); + await new Promise((resolve) => setTimeout(resolve, 10000)); - test("should generate a schame view based on a nestedMapSchema dataset and schema", async () => { - /** Set the schema to be tested */ + const queryResult = await getQueryResult(datasetId, tableId, schemaName); + expect(queryResult.length).toBe(1); + expect(queryResult[0].name).toBe("test"); + }, 60000); + + test("should generate a schema view based on a nestedMapSchema dataset and schema", async () => { const schemaName = "nestedMapSchema"; + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; - /** Create the test for the db */ - const testData = { - super: { - nested: { - schema: { - value: 1, - }, + const nestedMapSchema: FirestoreSchema = { + fields: [ + { + name: "super", + type: "map", + fields: [ + { + name: "nested", + type: "map", + fields: [ + { + name: "schema", + type: "map", + fields: [{ name: "value", type: "number" }], + }, + ], + }, + ], }, - }, + ], }; - /** Generate Id */ - const id = randomId(); + const testData = { super: { nested: { schema: { value: 1 } } } }; - /** Set the dataset and table names */ - const datasetId = `${datasetPrefix}${id}`; - const tableId = `table_${id}`; + const { dataset } = await setupBQ(datasetId, tableId, testData); - /** Create dataset and table */ - const { dataset, rawChangeLogTable, rawLatestTable } = await setupBQ( + await new Promise((resolve) => setTimeout(resolve, 3000)); + + const verifySetup = await verifySetupBQ(datasetId, tableId, testData); + if (!verifySetup.success) + throw new Error(`Setup failed: ${verifySetup.errors.join(", ")}`); + + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", datasetId, - tableId, - testData - ); + tableNamePrefix: tableId, + schemas: { [schemaName]: nestedMapSchema }, + useGemini: false, + }); - console.log("Testing with dataset: ", dataset.id); - console.log("Testing with table: ", rawChangeLogTable.id); - console.log("Testing with table: ", rawLatestTable.id); + const result = await run(); + expect(result).toBe(0); - /** await 5 seconds for the table to propogate */ - await new Promise((resolve) => setTimeout(resolve, 5000)); + await new Promise((resolve) => setTimeout(resolve, 10000)); - /** Run the gen-schema script */ - await executeScript(dataset.id, tableId, schemaName); + const queryResult = await getQueryResult(datasetId, tableId, schemaName); + expect(queryResult.length).toBe(1); + expect(queryResult[0].super_nested_schema_value.toString()).toBe("1"); + }, 60000); - console.log("Done executing"); + test("should generate a schema view based on an arraysNestedInMapsSchema dataset and schema", async () => { + const schemaName = "arraysNestedInMapsSchema"; + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; - /* wait 10 seconds for the view to propogate */ - await new Promise((resolve) => setTimeout(resolve, 10000)); + const arraysNestedInMapsSchema: FirestoreSchema = { + fields: [ + { + name: "map", + type: "map", + fields: [{ name: "array", type: "array" }], + }, + { + name: "map2", + type: "map", + fields: [{ name: "array", type: "array" }], + }, + ], + }; - /** Get the query result */ - const result = await getQueryResult(dataset.id, tableId, schemaName); + const testData = { map: { array: [] }, map2: { array: [] } }; - /** Assert data */ - expect(result.length).toBe(1); + const { dataset } = await setupBQ(datasetId, tableId, testData); - expect(result[0].super_nested_schema_value.toString()).toBe("1"); - }, 80000); + await new Promise((resolve) => setTimeout(resolve, 3000)); - test("should generate a schame view based on a arraysNestedInMapsSchema dataset and schema", async () => { - /** Set the schema to be tested */ - const schemaName = "arraysNestedInMapsSchema"; + const verifySetup = await verifySetupBQ(datasetId, tableId, testData); + if (!verifySetup.success) + throw new Error(`Setup failed: ${verifySetup.errors.join(", ")}`); - /** Create the test for the db */ - const testData = { - map: { - array: [], - }, - map2: { - array: [], - }, - }; + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId, + tableNamePrefix: tableId, + schemas: { [schemaName]: arraysNestedInMapsSchema }, + useGemini: false, + }); + + const result = await run(); + expect(result).toBe(0); + + await new Promise((resolve) => setTimeout(resolve, 10000)); - /** Generate Id */ - const id = randomId(); + const queryResult = await getQueryResult(datasetId, tableId, schemaName); + expect(queryResult.length).toBe(1); + expect(queryResult[0].map_array).toEqual([]); + expect(queryResult[0].map2_array).toEqual([]); + }, 60000); - /** Set the dataset and table names */ + test("should generate a schema view based on a simple mappedArray dataset and schema", async () => { + const schemaName = "mappedArray"; const datasetId = `${datasetPrefix}${id}`; const tableId = `table_${id}`; - /** Create dataset and table */ - const { dataset, rawChangeLogTable, rawLatestTable } = await setupBQ( - datasetId, - tableId, - testData - ); - - console.log("Testing with dataset: ", dataset.id); - console.log("Testing with table: ", rawChangeLogTable.id); - console.log("Testing with table: ", rawLatestTable.id); + const mappedArraySchema: FirestoreSchema = { + fields: [ + { name: "name", type: "string" }, + { name: "total", type: "number" }, + { + name: "cartItems", + type: "array", + fields: [{ name: "productName", type: "string" }], + }, + ], + }; - /** await 5 seconds for the table to propogate */ - await new Promise((resolve) => setTimeout(resolve, 5000)); + const testData = { + name: "test", + total: 1, + cartItems: [{ productName: "test" }], + }; - /** Run the gen-schema script */ - await executeScript(dataset.id, tableId, schemaName); + await setupBQ(datasetId, tableId, testData); - console.log("Done executing"); + await new Promise((resolve) => setTimeout(resolve, 3000)); - /* wait 10 seconds for the view to propogate */ - await new Promise((resolve) => setTimeout(resolve, 10000)); + const verifySetup = await verifySetupBQ(datasetId, tableId, testData); + if (!verifySetup.success) + throw new Error(`Setup failed: ${verifySetup.errors.join(", ")}`); - /** Get the query result */ - const result = await getQueryResult(dataset.id, tableId, schemaName); + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId, + tableNamePrefix: tableId, + schemas: { [schemaName]: mappedArraySchema }, + useGemini: false, + }); - /** Assert data */ - expect(result.length).toBe(1); + const result = await run(); + expect(result).toBe(0); - console.log("result: ", result[0]); - console.log("result: ", result[0].map_array); + await new Promise((resolve) => setTimeout(resolve, 10000)); - expect(JSON.stringify(result[0].map_array)).toBe(JSON.stringify([])); - expect(JSON.stringify(result[0].map2_array)).toBe(JSON.stringify([])); - expect(result[0].map_array_member).toBeNull(); - expect(result[0].map_array_index).toBeNull(); - expect(result[0].map2_array_member).toBeNull(); - expect(result[0].map2_array_index).toBeNull(); - }, 80000); + const queryResult = await getQueryResult(datasetId, tableId, schemaName); + expect(queryResult.length).toBe(1); + expect(queryResult[0].name).toBe("test"); + expect(queryResult[0].cartItems.length).toBe(1); + }, 60000); - test("should generate a schame view based on a mappedArray dataset and schema", async () => { - /** Set the schema to be tested */ + test("should generate a schema view based on a mappedArray dataset and schema", async () => { const schemaName = "mappedArray"; + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; - /** Create the test for the db */ - const testData = { - name: "test", - date: new Date(), - total: 1, - cartItems: [ + const mappedArraySchema: FirestoreSchema = { + fields: [ + { name: "name", type: "string" }, + { name: "date", type: "timestamp" }, + { name: "total", type: "number" }, { - productName: "test", - quantity: "test", - isGift: "Yes", + name: "cartItems", + type: "array", + fields: [ + { name: "productName", type: "string" }, + { name: "quantity", type: "string" }, + { name: "isGift", type: "string" }, + ], }, ], }; - /** Generate Id */ - const id = randomId(); - - /** Set the dataset and table names */ - const datasetId = `${datasetPrefix}${id}`; - const tableId = `table_${id}`; + const testData = { + name: "test", + date: new Date(), + total: 1, + cartItems: [{ productName: "test", quantity: "test", isGift: "Yes" }], + }; - /** Create dataset and table */ - const { dataset, rawChangeLogTable, rawLatestTable } = await setupBQ( - datasetId, - tableId, - testData - ); + const { dataset } = await setupBQ(datasetId, tableId, testData); - console.log("Testing with dataset: ", dataset.id); - console.log("Testing with table: ", rawChangeLogTable.id); - console.log("Testing with table: ", rawLatestTable.id); + await new Promise((resolve) => setTimeout(resolve, 3000)); - /** await 5 seconds for the table to propogate */ - await new Promise((resolve) => setTimeout(resolve, 5000)); + const verifySetup = await verifySetupBQ(datasetId, tableId, testData); + if (!verifySetup.success) + throw new Error(`Setup failed: ${verifySetup.errors.join(", ")}`); - /** Run the gen-schema script */ - await executeScript(dataset.id, tableId, schemaName); + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId, + tableNamePrefix: tableId, + schemas: { [schemaName]: mappedArraySchema }, + useGemini: false, + }); - console.log("Done executing"); + const result = await run(); + expect(result).toBe(0); - /* wait 10 seconds for the view to propogate */ await new Promise((resolve) => setTimeout(resolve, 10000)); - /** Get the query result */ - const result = await getQueryResult(dataset.id, tableId, schemaName); - - /** Assert data */ - expect(result.length).toBe(1); - - console.log("result: ", result[0]); - console.log("result: ", result[0].map_array); + const queryResult = await getQueryResult(datasetId, tableId, schemaName); - expect(result[0].productName).toBe("test"); - expect(result[0].quantity).toBe("test"); - expect(result[0].isGift).toBe("Yes"); - expect(result[0].total).toBe("1"); - }, 80000); + console.log("queryResult: ", queryResult[0]); + expect(queryResult.length).toBe(1); + expect(queryResult[0].name).toBe("test"); + // Depending on the BigQuery schema conversion, numeric fields may be returned as strings. + expect(JSON.stringify(JSON.parse(queryResult[0].total))).toBe("1"); + expect(queryResult[0].cartItems[0]).toBe( + '{"productName":"test","quantity":"test","isGift":"Yes"}' + ); + expect(queryResult[0].cartItems_index).toBe(0); + expect(queryResult[0].cartItems_member).toBe( + '{"productName":"test","quantity":"test","isGift":"Yes"}' + ); + }, 60000); }); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e_mocking.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e_mocking.test.ts new file mode 100644 index 000000000..ea2527e29 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/e2e_mocking.test.ts @@ -0,0 +1,352 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import { jest } from "@jest/globals"; +import { BigQuery } from "@google-cloud/bigquery"; +import { randomId } from "./helpers/setup"; +import { + FirestoreBigQuerySchemaViewFactory, + FirestoreSchema, +} from "../../schema"; +import { CliConfig } from "../../config"; // Import the CliConfig type + +// Mock the modules we want to replace +jest.mock("../../config", () => ({ + parseConfig: jest.fn<() => Promise>(), +})); + +jest.mock("../../schema-loader-utils", () => ({ + readSchemas: + jest.fn<(paths: string[]) => { [schemaName: string]: FirestoreSchema }>(), +})); + +// Enhanced firebase-admin mock with firestore function +jest.mock("firebase-admin", () => ({ + apps: [], + initializeApp: jest.fn(), + credential: { + applicationDefault: jest.fn(), + }, + firestore: jest.fn(() => ({ + settings: jest.fn(), + collection: jest.fn(() => ({ + doc: jest.fn(() => ({ + get: jest.fn(), + set: jest.fn(), + })), + })), + })), +})); + +// Import the mocked modules +import { parseConfig } from "../../config"; +import { readSchemas } from "../../schema-loader-utils"; +import { run } from "../.."; + +const bq = new BigQuery({ projectId: "dev-extensions-testing" }); +const datasetPrefix = "e2e_test_"; + +// Mock implementation of viewFactory.initializeSchemaViewResources +const mockInitializeSchemaViewResources = jest.fn(); + +// Mock the FirestoreBigQuerySchemaViewFactory class +jest.mock("../../schema", () => { + const originalModule = jest.requireActual("../../schema") as object; + return { + ...originalModule, + FirestoreBigQuerySchemaViewFactory: jest.fn().mockImplementation(() => { + return { + initializeSchemaViewResources: mockInitializeSchemaViewResources, + }; + }), + }; +}); + +describe("e2e (mocking bq)", () => { + beforeEach(() => { + // Reset all mocks + jest.clearAllMocks(); + + // Configure BigQuery mock + (mockInitializeSchemaViewResources as jest.Mock).mockResolvedValue( + undefined + ); + }); + + test("should generate a schema view based on a basic dataset and schema", async () => { + // Set the schema to be tested + const schemaName = "basic"; + + // Generate Id for unique dataset name + const id = randomId(); + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; + + // Create test schema + const basicSchema: FirestoreSchema = { + fields: [{ name: "name", type: "string" }], + }; + + // Mock the schemas object that would normally be loaded + const schemas = { + [schemaName]: basicSchema, + }; + + // Mock the config that parseConfig would return + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId: datasetId, + tableNamePrefix: tableId, + schemas: schemas, + useGemini: false, + }); + + // Mock readSchemas in case it gets called + ( + readSchemas as jest.Mock< + (paths: string[]) => { [schemaName: string]: FirestoreSchema } + > + ).mockReturnValue(schemas); + + // Run the function + const result = await run(); + + // Verify parseConfig was called + expect(parseConfig).toHaveBeenCalledTimes(1); + + // Verify FirestoreBigQuerySchemaViewFactory was initialized with the right project + expect(FirestoreBigQuerySchemaViewFactory).toHaveBeenCalledWith( + "dev-extensions-testing" + ); + + // Verify initializeSchemaViewResources was called with the right parameters + expect(mockInitializeSchemaViewResources).toHaveBeenCalledWith( + datasetId, + tableId, + schemaName, + basicSchema + ); + + // Verify the run function returned 0 (success) + expect(result).toBe(0); + }); + + test("should generate a schema view based on a nestedMapSchema dataset and schema", async () => { + // Set the schema to be tested + const schemaName = "nestedMapSchema"; + + // Generate Id for unique dataset name + const id = randomId(); + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; + + // Create test schema + const nestedMapSchema: FirestoreSchema = { + fields: [ + { + name: "super", + type: "map", + fields: [ + { + name: "nested", + type: "map", + fields: [ + { + name: "schema", + type: "map", + fields: [{ name: "value", type: "number" }], + }, + ], + }, + ], + }, + ], + }; + + // Mock the schemas object + const schemas = { + [schemaName]: nestedMapSchema, + }; + + // Mock the config + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId: datasetId, + tableNamePrefix: tableId, + schemas: schemas, + useGemini: false, + }); + + // Mock readSchemas + ( + readSchemas as jest.Mock< + (paths: string[]) => { [schemaName: string]: FirestoreSchema } + > + ).mockReturnValue(schemas); + + // Run the function + const result = await run(); + + // Verify initializeSchemaViewResources was called with the right parameters + expect(mockInitializeSchemaViewResources).toHaveBeenCalledWith( + datasetId, + tableId, + schemaName, + nestedMapSchema + ); + + // Verify the run function returned 0 (success) + expect(result).toBe(0); + }); + + test("should generate a schema view based on a arraysNestedInMapsSchema dataset and schema", async () => { + // Set the schema to be tested + const schemaName = "arraysNestedInMapsSchema"; + + // Generate Id for unique dataset name + const id = randomId(); + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; + + // Create test schema + const arraysNestedInMapsSchema: FirestoreSchema = { + fields: [ + { + name: "map", + type: "map", + fields: [ + { + name: "array", + type: "array", + }, + ], + }, + { + name: "map2", + type: "map", + fields: [ + { + name: "array", + type: "array", + }, + ], + }, + ], + }; + + // Mock the schemas object + const schemas = { + [schemaName]: arraysNestedInMapsSchema, + }; + + // Mock the config + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId: datasetId, + tableNamePrefix: tableId, + schemas: schemas, + useGemini: false, + }); + + // Mock readSchemas + ( + readSchemas as jest.Mock< + (paths: string[]) => { [schemaName: string]: FirestoreSchema } + > + ).mockReturnValue(schemas); + + // Run the function + const result = await run(); + + // Verify initializeSchemaViewResources was called with the right parameters + expect(mockInitializeSchemaViewResources).toHaveBeenCalledWith( + datasetId, + tableId, + schemaName, + arraysNestedInMapsSchema + ); + + // Verify the run function returned 0 (success) + expect(result).toBe(0); + }); + + test("should generate a schema view based on a mappedArray dataset and schema", async () => { + // Set the schema to be tested + const schemaName = "mappedArray"; + + // Generate Id for unique dataset name + const id = randomId(); + const datasetId = `${datasetPrefix}${id}`; + const tableId = `table_${id}`; + + // Create test schema + const mappedArraySchema: FirestoreSchema = { + fields: [ + { name: "name", type: "string" }, + { name: "date", type: "timestamp" }, + { name: "total", type: "number" }, + { + name: "cartItems", + type: "array", + fields: [ + { name: "productName", type: "string" }, + { name: "quantity", type: "string" }, + { name: "isGift", type: "string" }, + ], + }, + ], + }; + + // Mock the schemas object + const schemas = { + [schemaName]: mappedArraySchema, + }; + + // Mock the config + (parseConfig as jest.Mock<() => Promise>).mockResolvedValue({ + projectId: "dev-extensions-testing", + bigQueryProjectId: "dev-extensions-testing", + datasetId: datasetId, + tableNamePrefix: tableId, + schemas: schemas, + useGemini: false, + }); + + // Mock readSchemas + ( + readSchemas as jest.Mock< + (paths: string[]) => { [schemaName: string]: FirestoreSchema } + > + ).mockReturnValue(schemas); + + // Run the function + const result = await run(); + + // Verify initializeSchemaViewResources was called with the right parameters + expect(mockInitializeSchemaViewResources).toHaveBeenCalledWith( + datasetId, + tableId, + schemaName, + mappedArraySchema + ); + + // Verify the run function returned 0 (success) + expect(result).toBe(0); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/deleteDatasets.js b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/deleteDatasets.js new file mode 100644 index 000000000..6214cc016 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/deleteDatasets.js @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +// deleteDatasets.js +const { BigQuery } = require("@google-cloud/bigquery"); + +// Create a BigQuery client for the specified project. +const bq = new BigQuery({ projectId: "dev-extensions-testing" }); + +async function deleteAllDatasets() { + try { + // List all datasets in the project. + const [datasets] = await bq.getDatasets(); + console.log(`Found ${datasets.length} datasets.`); + + // Iterate over each dataset and delete it. + for (const dataset of datasets) { + if (dataset.id !== "2025_stress_test") { + console.log(`Deleting dataset: ${dataset.id}...`); + // The force option will delete the dataset along with all its tables. + await dataset.delete({ force: true }); + console.log(`Dataset ${dataset.id} deleted successfully.`); + } + } + + console.log("All datasets have been deleted."); + } catch (error) { + console.error("Error deleting datasets:", error); + } +} + +// Execute the deletion function. +deleteAllDatasets(); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/executeScript.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/executeScript.ts deleted file mode 100644 index 7238a7e8a..000000000 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/executeScript.ts +++ /dev/null @@ -1,41 +0,0 @@ -const path = require("path"); -const { exec } = require("child_process"); - -export default async function executeScript( - datasetId: string, - tableId: string, - schemaName: string -) { - /** Setup paths */ - const libPath = path.normalize(__dirname + "/../../../../lib/index.js"); - const schemaPath = path.normalize( - __dirname + `/../../../__tests__/e2e/schemas/${schemaName}` - ); - - const cmd = `node ${libPath} --project dev-extensions-testing -d ${datasetId} -t ${tableId} -f ${schemaPath} --non-interactive`; - console.log("Executing: ", cmd); - - function execAsync(command: string): Promise { - return new Promise((resolve, reject) => { - exec(command, (error, stdout, stderr) => { - const options = { - maxBuffer: 1024 * 500, // 500KB - shell: "/bin/bash", // Explicitly set the shell - }; - - exec(command, options, (error, stdout, stderr) => { - if (error) { - console.error(`Error: ${error}`); - console.error(`stderr: ${stderr}`); - reject(error); - return; - } - console.log(`stdout: ${stdout}`); - resolve(); - }); - }); - }); - } - - return execAsync(cmd); -} diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/setup.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/setup.ts index bad641e59..b1b4fb808 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/setup.ts +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/e2e/helpers/setup.ts @@ -98,3 +98,132 @@ export const getQueryResult = async ( return queryResult; }; + +export const verifySetupBQ = async ( + datasetId: string, + tableId: string, + expectedData: any +) => { + const bq = new BigQuery({ projectId: "dev-extensions-testing" }); + const dataset = bq.dataset(datasetId); + const results = { + success: true, + errors: [], + datasetExists: false, + changelogTableExists: false, + latestTableExists: false, + changelogData: null, + latestData: null, + }; + + try { + // Check if dataset exists + const [datasetExists] = await dataset.exists(); + if (!datasetExists) { + results.success = false; + results.errors.push(`Dataset ${datasetId} does not exist`); + return results; + } + results.datasetExists = true; + + // Check if tables exist + const changelogTableId = `${tableId}_raw_changelog`; + const latestTableId = `${tableId}_raw_latest`; + + const [changelogTableExists] = await dataset + .table(changelogTableId) + .exists(); + const [latestTableExists] = await dataset.table(latestTableId).exists(); + + if (!changelogTableExists) { + results.success = false; + results.errors.push(`Changelog table ${changelogTableId} does not exist`); + } else { + results.changelogTableExists = true; + } + + if (!latestTableExists) { + results.success = false; + results.errors.push(`Latest table ${latestTableId} does not exist`); + } else { + results.latestTableExists = true; + } + + // If tables don't exist, no need to check data + if (!changelogTableExists || !latestTableExists) { + return results; + } + + // Query tables to verify data was inserted + const [changelogRows] = await bq.query(` + SELECT * FROM \`${datasetId}.${changelogTableId}\` + WHERE document_id = 'test' + `); + + const [latestRows] = await bq.query(` + SELECT * FROM \`${datasetId}.${latestTableId}\` + WHERE document_id = 'test' + `); + + // Verify data exists in both tables + if (changelogRows.length === 0) { + results.success = false; + results.errors.push( + `No data found in changelog table ${changelogTableId}` + ); + } else { + results.changelogData = changelogRows[0]; + + // Check if data matches expected + try { + const parsedData = JSON.parse(changelogRows[0].data); + const dataMatches = + JSON.stringify(parsedData) === JSON.stringify(expectedData); + + if (!dataMatches) { + results.success = false; + results.errors.push( + `Data in changelog table doesn't match expected data` + ); + } + } catch (e) { + results.success = false; + results.errors.push( + `Failed to parse data in changelog table: ${e.message}` + ); + } + } + + if (latestRows.length === 0) { + results.success = false; + results.errors.push(`No data found in latest table ${latestTableId}`); + } else { + results.latestData = latestRows[0]; + + // Check if data matches expected + try { + const parsedData = JSON.parse(latestRows[0].data); + const dataMatches = + JSON.stringify(parsedData) === JSON.stringify(expectedData); + + if (!dataMatches) { + results.success = false; + results.errors.push( + `Data in latest table doesn't match expected data` + ); + } + } catch (e) { + results.success = false; + results.errors.push( + `Failed to parse data in latest table: ${e.message}` + ); + } + } + + return results; + } catch (error) { + results.success = false; + results.errors.push(`Verification failed with error: ${error.message}`); + return results; + } +}; diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/sampleFirestoreDocuments.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/sampleFirestoreDocuments.test.ts new file mode 100644 index 000000000..36272013b --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/sampleFirestoreDocuments.test.ts @@ -0,0 +1,139 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +interface FirestoreModule { + (): { + collection: jest.Mock; + where: jest.Mock; + limit: jest.Mock; + get: jest.Mock; + }; + GeoPoint: new (latitude: number, longitude: number) => { + latitude: number; + longitude: number; + }; + DocumentReference: new (path: string) => { path: string }; +} + +jest.mock("firebase-admin", () => { + const mockFirestore = { + collection: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + limit: jest.fn().mockReturnThis(), + get: jest.fn().mockResolvedValue({ + docs: [ + { + data: () => ({ name: "Doc 1", value: 100 }), + id: "doc1", + }, + { + data: () => ({ name: "Doc 2", value: 200 }), + id: "doc2", + }, + ], + }), + }; + + class GeoPoint { + latitude: number; + longitude: number; + constructor(latitude: number, longitude: number) { + this.latitude = latitude; + this.longitude = longitude; + } + } + + class DocumentReference { + path: string; + constructor(path: string) { + this.path = path; + } + } + + const firestoreModule = jest.fn( + () => mockFirestore + ) as unknown as FirestoreModule; + firestoreModule.GeoPoint = GeoPoint; + firestoreModule.DocumentReference = DocumentReference; + + return { + firestore: firestoreModule, + }; +}); + +import { sampleFirestoreDocuments } from "../../schema/genkit"; + +jest.mock("../../schema/genkit", () => { + const original = jest.requireActual("../../schema/genkit"); + return { + ...original, + serializeDocument: (data: any) => { + if (!data) return null; + if (data instanceof Date) { + return { _type: "timestamp", value: data.toISOString() }; + } + if (typeof data === "object" && !Array.isArray(data)) { + return Object.entries(data).reduce( + (result: Record, [key, value]) => { + result[key] = value; + return result; + }, + {} + ); + } + return data; + }, + }; +}); + +describe.skip("sampleFirestoreDocuments", () => { + it("should sample documents from Firestore collection", async () => { + const collectionPath = "test-collection"; + const sampleSize = 2; + + const result = await sampleFirestoreDocuments(collectionPath, sampleSize); + + const firebase = require("firebase-admin"); + const mockFirestore = firebase.firestore(); + + expect(mockFirestore.collection).toHaveBeenCalledWith(collectionPath); + expect(mockFirestore.where).toHaveBeenCalledWith( + "__name__", + ">=", + expect.any(String) + ); + expect(mockFirestore.limit).toHaveBeenCalledWith(sampleSize); + expect(mockFirestore.get).toHaveBeenCalled(); + + expect(result).toHaveLength(2); + expect(result[0]).toHaveProperty("name", "Doc 1"); + expect(result[0]).toHaveProperty("value", 100); + }); + + it("should handle errors properly", async () => { + const firebase = require("firebase-admin"); + const mockFirestore = firebase.firestore(); + + mockFirestore.get.mockRejectedValueOnce(new Error("Firestore error")); + + const collectionPath = "test-collection"; + const sampleSize = 2; + + await expect( + sampleFirestoreDocuments(collectionPath, sampleSize) + ).rejects.toThrow("Firestore error"); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/serializeDocument.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/serializeDocument.test.ts new file mode 100644 index 000000000..7569c71ed --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/genkit/serializeDocument.test.ts @@ -0,0 +1,186 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +// First, set up the mocks before any imports +// Create mock classes for Firestore special types +class MockGeoPoint { + latitude: number; + longitude: number; + constructor(lat: number, lng: number) { + this.latitude = lat; + this.longitude = lng; + } +} + +class MockDocumentReference { + path: string; + constructor(path: string) { + this.path = path; + } +} + +// Mock firebase-admin to use our mock classes - this must be done before importing firebase +jest.mock("firebase-admin", () => ({ + firestore: { + GeoPoint: MockGeoPoint, + DocumentReference: MockDocumentReference, + }, +})); + +// Now import the dependencies after the mocks are set up +import firebase = require("firebase-admin"); +import { serializeDocument } from "../../schema/genkit"; + +describe("serializeDocument", () => { + test("should handle null values", () => { + expect(serializeDocument(null)).toBeNull(); + expect(serializeDocument(undefined)).toBeNull(); + }); + + test("should handle primitive values", () => { + expect(serializeDocument("string")).toBe("string"); + expect(serializeDocument(123)).toBe(123); + expect(serializeDocument(true)).toBe(true); + }); + + test("should handle Date objects", () => { + const date = new Date("2023-01-01T12:00:00Z"); + const result = serializeDocument(date); + + expect(result).toEqual({ + _type: "timestamp", + value: "2023-01-01T12:00:00.000Z", + }); + }); + + test("should handle GeoPoint objects", () => { + const geoPoint = new MockGeoPoint(37.7749, -122.4194); + const result = serializeDocument(geoPoint); + + expect(result).toEqual({ + _type: "geopoint", + latitude: 37.7749, + longitude: -122.4194, + }); + }); + + test("should handle DocumentReference objects", () => { + const docRef = new MockDocumentReference("collections/docId"); + const result = serializeDocument(docRef); + + expect(result).toEqual({ + _type: "reference", + path: "collections/docId", + }); + }); + + test("should handle arrays", () => { + const array = [1, "two", new Date("2023-01-01T12:00:00Z")]; + const result = serializeDocument(array); + + expect(result).toEqual([ + 1, + "two", + { _type: "timestamp", value: "2023-01-01T12:00:00.000Z" }, + ]); + }); + + test("should handle nested objects", () => { + const obj = { + name: "Test", + timestamp: new Date("2023-01-01T12:00:00Z"), + location: new MockGeoPoint(37.7749, -122.4194), + ref: new MockDocumentReference("collections/docId"), + nested: { + array: [1, 2, 3], + value: "nested value", + }, + }; + + const result = serializeDocument(obj); + + expect(result).toEqual({ + name: "Test", + timestamp: { _type: "timestamp", value: "2023-01-01T12:00:00.000Z" }, + location: { _type: "geopoint", latitude: 37.7749, longitude: -122.4194 }, + ref: { _type: "reference", path: "collections/docId" }, + nested: { + array: [1, 2, 3], + value: "nested value", + }, + }); + }); + + test("should handle complex nested structures", () => { + const complex = { + users: [ + { + name: "User 1", + createdAt: new Date("2023-01-01T12:00:00Z"), + location: new MockGeoPoint(37.7749, -122.4194), + }, + { + name: "User 2", + createdAt: new Date("2023-01-02T12:00:00Z"), + references: [ + new MockDocumentReference("collections/doc1"), + new MockDocumentReference("collections/doc2"), + ], + }, + ], + metadata: { + updated: new Date("2023-01-03T12:00:00Z"), + nested: { + deeply: { + value: "nested deeply", + }, + }, + }, + }; + + const result = serializeDocument(complex); + + expect(result).toEqual({ + users: [ + { + name: "User 1", + createdAt: { _type: "timestamp", value: "2023-01-01T12:00:00.000Z" }, + location: { + _type: "geopoint", + latitude: 37.7749, + longitude: -122.4194, + }, + }, + { + name: "User 2", + createdAt: { _type: "timestamp", value: "2023-01-02T12:00:00.000Z" }, + references: [ + { _type: "reference", path: "collections/doc1" }, + { _type: "reference", path: "collections/doc2" }, + ], + }, + ], + metadata: { + updated: { _type: "timestamp", value: "2023-01-03T12:00:00.000Z" }, + nested: { + deeply: { + value: "nested deeply", + }, + }, + }, + }); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/readSchemas.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/readSchemas.test.ts new file mode 100644 index 000000000..9c7cd87de --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/readSchemas.test.ts @@ -0,0 +1,444 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import { readSchemas, filePathToSchemaName } from "../../schema-loader-utils"; +import * as fs from "fs"; +import * as glob from "glob"; +import * as path from "path"; + +// Mock dependencies +jest.mock("fs"); +jest.mock("glob"); +jest.mock("path"); + +describe("Schema Loader Utilities", () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + test("should handle comma-separated file paths", () => { + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path resolution + (path.basename as jest.Mock) + .mockReturnValueOnce("users.json") + .mockReturnValueOnce("posts.json"); + + // Mock glob expansion + (glob.sync as jest.Mock) + .mockReturnValueOnce(["/path/to/users.json"]) + .mockReturnValueOnce(["/path/to/posts.json"]); + + // Mock schemas + jest.mock( + "/path/to/users.json", + () => ({ + fields: { name: { type: "string" } }, + }), + { virtual: true } + ); + + jest.mock( + "/path/to/posts.json", + () => ({ + fields: { title: { type: "string" } }, + }), + { virtual: true } + ); + + // Call the function with comma-separated paths + const result = readSchemas(["users.json,posts.json"]); + + // Validate results + expect(glob.sync).toHaveBeenCalledTimes(2); + expect(fs.lstatSync).toHaveBeenCalledTimes(2); + expect(mockStats.isDirectory).toHaveBeenCalledTimes(2); + + // Verify schemas were loaded correctly + expect(result).toHaveProperty("users"); + expect(result).toHaveProperty("posts"); + }); + + test("should read schemas from a directory", () => { + // Mock file system stats to indicate a directory + const mockStats = { + isDirectory: jest.fn().mockReturnValue(true), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock directory reading + (fs.readdirSync as jest.Mock).mockReturnValue(["users.json", "posts.json"]); + + // Mock basename for each file + (path.basename as jest.Mock) + .mockReturnValueOnce("users.json") + .mockReturnValueOnce("posts.json"); + + // Mock glob expansion + (glob.sync as jest.Mock).mockReturnValue(["/path/to/schemas"]); + + // Mock schemas + jest.mock( + "/path/to/schemas/users.json", + () => ({ + fields: { name: { type: "string" } }, + }), + { virtual: true } + ); + + jest.mock( + "/path/to/schemas/posts.json", + () => ({ + fields: { title: { type: "string" } }, + }), + { virtual: true } + ); + + // Call the function + const result = readSchemas(["schemas"]); + + // Validate results + expect(glob.sync).toHaveBeenCalled(); + expect(fs.lstatSync).toHaveBeenCalled(); + expect(mockStats.isDirectory).toHaveBeenCalled(); + expect(fs.readdirSync).toHaveBeenCalled(); + + // Verify schemas were loaded + expect(result).toHaveProperty("users"); + expect(result).toHaveProperty("posts"); + }); + + test("should handle glob patterns", () => { + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path resolution + (path.basename as jest.Mock) + .mockReturnValueOnce("users.json") + .mockReturnValueOnce("admins.json"); + + // Mock glob expansion to return multiple files + (glob.sync as jest.Mock).mockReturnValue([ + "/path/to/users.json", + "/path/to/admins.json", + ]); + + // Mock schemas + jest.mock( + "/path/to/users.json", + () => ({ + fields: { name: { type: "string" } }, + }), + { virtual: true } + ); + + jest.mock( + "/path/to/admins.json", + () => ({ + fields: { email: { type: "string" } }, + }), + { virtual: true } + ); + + // Call the function with a glob pattern + const result = readSchemas(["*.json"]); + + // Validate results + expect(glob.sync).toHaveBeenCalledWith("*.json"); + expect(fs.lstatSync).toHaveBeenCalledTimes(2); + expect(mockStats.isDirectory).toHaveBeenCalledTimes(2); + + // Verify schemas were loaded + expect(result).toHaveProperty("users"); + expect(result).toHaveProperty("admins"); + }); + + test("should warn about duplicate schema names", () => { + // Mock console.log to detect warning + const consoleSpy = jest.spyOn(console, "log").mockImplementation(); + + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path resolution to return the same filename twice + (path.basename as jest.Mock) + .mockReturnValueOnce("users.json") + .mockReturnValueOnce("users.json"); + + // Mock glob expansion + (glob.sync as jest.Mock) + .mockReturnValueOnce(["/path/to/users.json"]) + .mockReturnValueOnce(["/path/to/other/users.json"]); + + // Mock schemas + jest.mock( + "/path/to/users.json", + () => ({ + fields: { name: { type: "string" } }, + }), + { virtual: true } + ); + + jest.mock( + "/path/to/other/users.json", + () => ({ + fields: { fullName: { type: "string" } }, + }), + { virtual: true } + ); + + // Call the function with two files that will generate the same schema name + const result = readSchemas(["users1.json", "users2.json"]); + + // Verify warning was logged + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining("Found multiple schema files named users!") + ); + + // Verify the last schema wins + expect(result).toHaveProperty("users"); + + consoleSpy.mockRestore(); + }); + + test("should convert file path to schema name correctly", () => { + // Test the filePathToSchemaName function + + // Setup mocking + (path.basename as jest.Mock).mockReturnValue("user-profile.json"); + + // Test hyphen conversion + expect(filePathToSchemaName("/path/to/user-profile.json")).toBe( + "user_profile" + ); + + // Reset and test multiple extensions + jest.resetAllMocks(); + (path.basename as jest.Mock).mockReturnValue("data.export.json"); + expect(filePathToSchemaName("/path/to/data.export.json")).toBe( + "data.export" + ); + }); + + describe("Schema Loader Edge Cases", () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + test("should handle non-existent files gracefully", () => { + // Mock glob.sync to return a file path + (glob.sync as jest.Mock).mockReturnValue(["/path/to/nonexistent.json"]); + + // Mock lstatSync to throw an error (file doesn't exist) + (fs.lstatSync as jest.Mock).mockImplementation(() => { + throw new Error("ENOENT: no such file or directory"); + }); + + // Verify that an error is thrown + expect(() => { + readSchemas(["nonexistent.json"]); + }).toThrow(); + }); + + test("should handle empty or invalid schema files", () => { + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path resolution + (path.basename as jest.Mock).mockReturnValue("empty.json"); + + // Mock glob expansion + (glob.sync as jest.Mock).mockReturnValue(["/path/to/empty.json"]); + + // Mock an empty schema + jest.mock("/path/to/empty.json", () => ({}), { virtual: true }); + + // Call the function + const result = readSchemas(["empty.json"]); + + // Verify an empty schema was loaded + expect(result).toHaveProperty("empty"); + expect(result.empty).toEqual({}); + }); + + test("should handle multiple glob patterns in array", () => { + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path resolution + (path.basename as jest.Mock) + .mockReturnValueOnce("users.json") + .mockReturnValueOnce("posts.json") + .mockReturnValueOnce("comments.json"); + + // Mock glob expansion for different patterns + (glob.sync as jest.Mock) + .mockReturnValueOnce(["/path/to/users.json"]) + .mockReturnValueOnce(["/path/to/posts.json", "/path/to/comments.json"]); + + // Mock schemas + jest.mock( + "/path/to/users.json", + () => ({ fields: { name: { type: "string" } } }), + { virtual: true } + ); + jest.mock( + "/path/to/posts.json", + () => ({ fields: { title: { type: "string" } } }), + { virtual: true } + ); + jest.mock( + "/path/to/comments.json", + () => ({ fields: { text: { type: "string" } } }), + { virtual: true } + ); + + // Call the function with multiple glob patterns + const result = readSchemas(["users.json", "post*.json"]); + + // Validate results + expect(glob.sync).toHaveBeenCalledTimes(2); + expect(glob.sync).toHaveBeenCalledWith("users.json"); + expect(glob.sync).toHaveBeenCalledWith("post*.json"); + + // Verify schemas were loaded + expect(result).toHaveProperty("users"); + expect(result).toHaveProperty("posts"); + expect(result).toHaveProperty("comments"); + }); + + test("should handle different path formats correctly", () => { + // Mock file system stats + const mockStats = { + isDirectory: jest.fn().mockReturnValue(false), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock path.basename + (path.basename as jest.Mock).mockReturnValue("schema.json"); + + // Mock glob expansion for different path formats + (glob.sync as jest.Mock) + .mockReturnValueOnce(["/absolute/path/schema.json"]) + .mockReturnValueOnce(["./relative/path/schema.json"]); + + // Setup mocks for resolveFilePath (checking path starts with) + const processCwdSpy = jest + .spyOn(process, "cwd") + .mockReturnValue("/current/dir"); + + // Mock schemas + jest.mock( + "/absolute/path/schema.json", + () => ({ fields: { absolute: { type: "string" } } }), + { virtual: true } + ); + jest.mock( + "/current/dir/./relative/path/schema.json", + () => ({ fields: { relative: { type: "string" } } }), + { virtual: true } + ); + + // Test absolute path + let result = readSchemas(["/absolute/path/schema.json"]); + expect(result).toHaveProperty("schema"); + expect(glob.sync).toHaveBeenCalledWith("/absolute/path/schema.json"); + + // Reset mocks for second test + jest.clearAllMocks(); + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + (path.basename as jest.Mock).mockReturnValue("schema.json"); + processCwdSpy.mockReturnValue("/current/dir"); + + // Test relative path + result = readSchemas(["./relative/path/schema.json"]); + expect(result).toHaveProperty("schema"); + expect(glob.sync).toHaveBeenCalledWith("./relative/path/schema.json"); + + processCwdSpy.mockRestore(); + }); + + test("should handle unusual filenames when converting to schema names", () => { + // Test various unusual filenames + + // Setup mocking + (path.basename as jest.Mock).mockReturnValueOnce( + "user-name.with-hyphens.json" + ); + expect(filePathToSchemaName("/path/to/user-name.with-hyphens.json")).toBe( + "user_name.with_hyphens" + ); + + // Multi-dot extensions + (path.basename as jest.Mock).mockReturnValueOnce( + "file.name.with.dots.json" + ); + expect(filePathToSchemaName("/path/to/file.name.with.dots.json")).toBe( + "file.name.with.dots" + ); + + // Spaces in filename + (path.basename as jest.Mock).mockReturnValueOnce( + "file name with spaces.json" + ); + expect(filePathToSchemaName("/path/to/file name with spaces.json")).toBe( + "file name with spaces" + ); + }); + + test("should handle empty directory", () => { + // Mock file system stats to indicate a directory + const mockStats = { + isDirectory: jest.fn().mockReturnValue(true), + }; + (fs.lstatSync as jest.Mock).mockReturnValue(mockStats); + + // Mock directory reading to return empty array (empty directory) + (fs.readdirSync as jest.Mock).mockReturnValue([]); + + // Mock glob expansion + (glob.sync as jest.Mock).mockReturnValue(["/path/to/empty-dir"]); + + // Call the function + const result = readSchemas(["empty-dir"]); + + // Validate results + expect(glob.sync).toHaveBeenCalled(); + expect(fs.lstatSync).toHaveBeenCalled(); + expect(mockStats.isDirectory).toHaveBeenCalled(); + expect(fs.readdirSync).toHaveBeenCalled(); + + // Verify no schemas were loaded + expect(Object.keys(result).length).toBe(0); + }); + }); +}); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/schema-loader-utils.test.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/schema-loader-utils.test.ts index 38fbb8bcd..5a9183888 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/schema-loader-utils.test.ts +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/__tests__/schema-loader-utils/schema-loader-utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2019 Google LLC + * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,37 +14,45 @@ * limitations under the License. */ -import * as fs_find from "fs-find"; -import { readdirSync } from "fs"; +import { readdirSync, statSync } from "fs"; import { dirname } from "path"; -import { promisify } from "util"; - -import * as chai from "chai"; import * as schema_loader_utils from "../../schema-loader-utils"; -const expect = chai.expect; - const fixturesDir = __dirname + "/../fixtures"; const schemaDir = fixturesDir + "/schema-files"; -const find = promisify(fs_find); +// Helper function to recursively get all files in a directory +function getAllFiles(dirPath: string, arrayOfFiles: string[] = []): string[] { + const files = readdirSync(dirPath); + + files.forEach((file) => { + const fullPath = dirPath + "/" + file; + if (statSync(fullPath).isDirectory()) { + arrayOfFiles = getAllFiles(fullPath, arrayOfFiles); + } else { + arrayOfFiles.push(fullPath); + } + }); + + return arrayOfFiles; +} describe("filesystem schema loading", () => { - it("should load no schemas from an empty directory", () => { + test("should load no schemas from an empty directory", () => { const schemas = schema_loader_utils.readSchemas([ `${schemaDir}/empty-directory`, ]); - expect(Object.keys(schemas).length).to.equal(0); + expect(Object.keys(schemas).length).toBe(0); }); - it("should load one schema from a single file", () => { + test("should load one schema from a single file", () => { const schemaFile = `${schemaDir}/full-directory/schema-1.json`; const schemas = Object.keys(schema_loader_utils.readSchemas([schemaFile])); - expect(schemas.length).to.equal(1); - expect(schemas[0]).to.equal( + expect(schemas.length).toBe(1); + expect(schemas[0]).toBe( schema_loader_utils.filePathToSchemaName(schemaFile) ); }); - it("should load many schemas from a full directory, but dedup overlapping names", () => { + test("should load many schemas from a full directory, but dedup overlapping names", () => { const directoryPath = `${schemaDir}/full-directory`; const expectedSchemaNames = [ ...new Set( @@ -54,9 +62,9 @@ describe("filesystem schema loading", () => { ), ]; const schemas = schema_loader_utils.readSchemas([directoryPath]); - expect(Object.keys(schemas)).to.have.members(expectedSchemaNames); + expect(new Set(Object.keys(schemas))).toEqual(new Set(expectedSchemaNames)); }); - it("should load only schemas with names matching glob pattern", () => { + test("should load only schemas with names matching glob pattern", () => { const globPattern = `${schemaDir}/full-directory/*.json`; const expectedSchemaNames = readdirSync(dirname(globPattern)) .filter((schemaName) => schemaName.endsWith(".json")) @@ -64,28 +72,26 @@ describe("filesystem schema loading", () => { schema_loader_utils.filePathToSchemaName(schemaFile) ); const schemas = schema_loader_utils.readSchemas([globPattern]); - expect(Object.keys(schemas)).to.have.members(expectedSchemaNames); + expect(new Set(Object.keys(schemas))).toEqual(new Set(expectedSchemaNames)); }); - it("should load all schemas with multiple hierarchy levels", async () => { - const globPattern = `${schemaDir}/**/*.json`; - const results: string[] = (await find(schemaDir)) - .filter((schemaFileInfo) => schemaFileInfo.file.endsWith(".json")) - .map((schemaFileInfo) => - schema_loader_utils.filePathToSchemaName(schemaFileInfo.file) - ); - const schemas = schema_loader_utils.readSchemas([globPattern]); - expect(Object.keys(schemas)).to.have.members(results); + test("should load all schemas with multiple hierarchy levels", () => { + const allFiles = getAllFiles(schemaDir) + .filter((file) => file.endsWith(".json")) + .map((file) => schema_loader_utils.filePathToSchemaName(file)); + + const schemas = schema_loader_utils.readSchemas([`${schemaDir}/**/*.json`]); + expect(new Set(Object.keys(schemas))).toEqual(new Set(allFiles)); }); - it("should load schemas from a comma-separated list of file paths", () => { + test("should load schemas from a comma-separated list of file paths", () => { const schemaFiles = `${schemaDir}/full-directory/schema-1.json,${schemaDir}/full-directory/schema-2.json`; const schemas = Object.keys(schema_loader_utils.readSchemas([schemaFiles])); - expect(schemas.length).to.equal(2); - expect(schemas).to.include( + expect(schemas.length).toBe(2); + expect(schemas).toContain( schema_loader_utils.filePathToSchemaName( `${schemaDir}/full-directory/schema-1.json` ) ); - expect(schemas).to.include( + expect(schemas).toContain( schema_loader_utils.filePathToSchemaName( `${schemaDir}/full-directory/schema-2.json` ) diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/config/index.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/config/index.ts new file mode 100644 index 000000000..25fbfaa82 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/config/index.ts @@ -0,0 +1,86 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import { FirestoreSchema } from "../schema"; +import { readSchemas } from "../schema-loader-utils"; +import { promptInquirer } from "./interactive"; +import { parseProgram, validateNonInteractiveParams } from "./non-interactive"; + +const DEFAULT_SAMPLE_SIZE = 100; + +export interface CliConfig { + projectId: string; + bigQueryProjectId: string; + datasetId: string; + tableNamePrefix: string; + schemas: { [schemaName: string]: FirestoreSchema }; + useGemini?: boolean; + geminiAnalyzeCollectionPath?: string; + agentSampleSize?: number; + googleAiKey?: string; + schemaDirectory?: string; + geminiSchemaFileName?: string; +} + +export async function parseConfig(): Promise { + const program = parseProgram(); + if (program.nonInteractive) { + if (!validateNonInteractiveParams(program)) { + program.outputHelp(); + process.exit(1); + } + + return { + projectId: program.project, + bigQueryProjectId: program.bigQueryProject || program.project, + datasetId: program.dataset, + tableNamePrefix: program.tableNamePrefix, + useGemini: !!program.useGemini, + schemas: !program.useGemini ? readSchemas(program.schemaFiles) : {}, + geminiAnalyzeCollectionPath: program.useGemini, + agentSampleSize: DEFAULT_SAMPLE_SIZE, + googleAiKey: program.googleAiKey, + schemaDirectory: program.schemaDirectory, + geminiSchemaFileName: program.geminiSchemaFileName, + }; + } + const { + projectId, + bigQueryProjectId, + datasetId, + tableNamePrefix, + schemaFiles, + useGemini, + geminiAnalyzeCollectionPath, + googleAiKey, + schemaDirectory, + geminiSchemaFileName, + } = await promptInquirer(); + + return { + projectId, + bigQueryProjectId, + datasetId, + tableNamePrefix, + schemas: !useGemini ? readSchemas([schemaFiles]) : {}, + useGemini, + geminiAnalyzeCollectionPath, + agentSampleSize: DEFAULT_SAMPLE_SIZE, + googleAiKey, + schemaDirectory, + geminiSchemaFileName, + }; +} diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/config/interactive.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/config/interactive.ts new file mode 100644 index 000000000..24104ebb5 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/config/interactive.ts @@ -0,0 +1,119 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import inquirer from "inquirer"; + +const BIGQUERY_VALID_CHARACTERS = /^[a-zA-Z0-9_]+$/; +const FIRESTORE_VALID_CHARACTERS = /^[^\/]+$/; +const GCP_PROJECT_VALID_CHARACTERS = /^[a-z][a-z0-9-]{0,29}$/; + +const validateInput = (value: any, name: string, regex: RegExp) => { + if (!value || value === "" || value.trim() === "") { + return `Please supply a ${name}`; + } + if (!value.match(regex)) { + return `The ${name} must only contain letters or spaces`; + } + return true; +}; + +export const questions = [ + { + message: "What is your Firebase project ID?", + name: "projectId", + type: "input", + validate: (value) => + validateInput(value, "project ID", FIRESTORE_VALID_CHARACTERS), + }, + { + message: + "What is your Google Cloud Project ID for BigQuery? (can be the same as the Firebase project ID)", + name: "bigQueryProjectId", + type: "input", + validate: (value) => + validateInput(value, "BigQuery project ID", GCP_PROJECT_VALID_CHARACTERS), + }, + { + message: + "What is the ID of the BigQuery dataset the raw changelog lives in? (The dataset and the raw changelog must already exist!)", + name: "datasetId", + type: "input", + validate: (value) => + validateInput(value, "dataset ID", BIGQUERY_VALID_CHARACTERS), + }, + { + message: + "What prefix is used for the names of the tables and views generated by the extension?", + name: "tableNamePrefix", + type: "input", + validate: (value) => + validateInput(value, "table name prefix", BIGQUERY_VALID_CHARACTERS), + }, + { + message: + "Would you like to use a Gemini to automatically analyze your data and generate a draft schema?", + name: "useGemini", + type: "confirm", + default: false, + }, + { + message: + "Where should this script look for schema definitions? (Enter a comma-separated list of, optionally globbed, paths to files or directories).", + name: "schemaFiles", + type: "input", + when: (answers) => !answers.useGemini, + }, + { + message: "Please provide your Google AI API Key:", + name: "googleAiKey", + type: "password", + when: (answers) => answers.useGemini, + validate: (value) => { + if (!value || value.trim() === "") { + return "Google AI API Key is required"; + } + return true; + }, + }, + { + message: + "What is the Firestore collection path you want Gemini to analyze?", + name: "geminiAnalyzeCollectionPath", + type: "input", + when: (answers) => answers.useGemini, + validate: (value) => + validateInput(value, "collection path", FIRESTORE_VALID_CHARACTERS), + }, + { + message: "Where should the generated schema files be stored?", + name: "schemaDirectory", + type: "input", + when: (answers) => answers.useGemini, + default: "./schemas", + }, + { + message: + "What name should be used for the generated schema json file (without .json extension)?", + name: "geminiSchemaFileName", + type: "input", + when: (answers) => answers.useGemini, + default: "schema", + }, +]; + +export const promptInquirer = () => { + return inquirer.prompt(questions); +}; diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/config/non-interactive.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/config/non-interactive.ts new file mode 100644 index 000000000..c6e659638 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/config/non-interactive.ts @@ -0,0 +1,103 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import program from "commander"; + +/** + * Helper function to collect multiple values for an option into an array + */ +export function collect(value: string, previous: string[]): string[] { + return previous.concat([value]); +} + +/** + * Configure the commander program with all needed options + */ +export const configureProgram = () => { + const packageJson = require("../../package.json"); + + program + .name("gen-schema-views") + .description(packageJson.description) + .version(packageJson.version) + .option( + "--non-interactive", + "Parse all input from command line flags instead of prompting the caller.", + false + ) + .option( + "-P, --project ", + "Firebase Project ID for project containing Cloud Firestore database." + ) + .option( + "-B, --big-query-project ", + "Google Cloud Project ID for BigQuery (can be the same as the Firebase project ID)." + ) + .option( + "-d, --dataset ", + "The ID of the BigQuery dataset containing a raw Cloud Firestore document changelog." + ) + .option( + "-t, --table-name-prefix ", + "A common prefix for the names of all views generated by this script." + ) + .option( + "-f, --schema-files ", + "A collection of files from which to read schemas.", + collect, + [] + ) + .option( + "-g, --use-gemini ", + "Use Gemini to automatically analyze your data and generate a draft schema. You will have a chance to manually view and approve this schema before it is used." + ) + .option( + "--schema-directory ", + "Directory to store generated schemas", + "./schemas" + ) + .option("--google-ai-key ", "Google AI API Key for Gemini") + .option( + "--gemini-schema-file-name ", + "Name of schema json file generated by Gemini (without .json extension)", + "schema" + ); + + return program; +}; + +/** + * Parse command line arguments + */ +export const parseProgram = () => { + const prog = configureProgram(); + prog.parse(process.argv); + return prog; +}; + +/** + * Validate required non-interactive parameters are present + * @returns {boolean} true if all required parameters are present + */ +export const validateNonInteractiveParams = (program: any): boolean => { + return !( + program.project === undefined || + program.dataset === undefined || + program.tableNamePrefix === undefined || + (!program.useGemini && program.schemaFiles.length === 0) || + program.useGemini === "" + ); +}; diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/index.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/index.ts index 7f5321038..81c382be1 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/index.ts +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/index.ts @@ -16,126 +16,18 @@ * limitations under the License. */ -import * as program from "commander"; -import * as firebase from "firebase-admin"; -import * as inquirer from "inquirer"; - +import firebase = require("firebase-admin"); import { FirestoreBigQuerySchemaViewFactory, FirestoreSchema } from "./schema"; - import { readSchemas } from "./schema-loader-utils"; +import { parseConfig } from "./config"; +import { generateSchemaFilesWithGemini } from "./schema/genkit"; -const BIGQUERY_VALID_CHARACTERS = /^[a-zA-Z0-9_]+$/; -const FIRESTORE_VALID_CHARACTERS = /^[^\/]+$/; -const GCP_PROJECT_VALID_CHARACTERS = /^[a-z][a-z0-9-]{0,29}$/; - -const validateInput = (value: any, name: string, regex: RegExp) => { - if (!value || value === "" || value.trim() === "") { - return `Please supply a ${name}`; - } - if (!value.match(regex)) { - return `The ${name} must only contain letters or spaces`; - } - return true; -}; - -function collect(value, previous) { - return previous.concat([value]); -} - -const packageJson = require("../package.json"); - -program - .name("gen-schema-views") - .description(packageJson.description) - .version(packageJson.version) - .option( - "--non-interactive", - "Parse all input from command line flags instead of prompting the caller.", - false - ) - .option( - "-P, --project ", - "Firebase Project ID for project containing Cloud Firestore database." - ) - .option( - "-B, --big-query-project ", - "Google Cloud Project ID for BigQuery (can be the same as the Firebase project ID)." - ) - .option( - "-d, --dataset ", - "The ID of the BigQuery dataset containing a raw Cloud Firestore document changelog." - ) - .option( - "-t, --table-name-prefix ", - "A common prefix for the names of all views generated by this script." - ) - .option( - "-f, --schema-files ", - "A collection of files from which to read schemas.", - collect, - [] - ); - -const questions = [ - { - message: "What is your Firebase project ID?", - name: "project", - default: process.env.PROJECT_ID, - type: "input", - validate: (value) => - validateInput(value, "project ID", FIRESTORE_VALID_CHARACTERS), - }, - { - message: - "What is your Google Cloud Project ID for BigQuery? (can be the same as the Firebase project ID)", - name: "bigQueryProject", - default: process.env.PROJECT_ID, - type: "input", - validate: (value) => - validateInput(value, "BigQuery project ID", GCP_PROJECT_VALID_CHARACTERS), - }, - { - message: - "What is the ID of the BigQuery dataset the raw changelog lives in? (The dataset and the raw changelog must already exist!)", - name: "dataset", - type: "input", - validate: (value) => - validateInput(value, "dataset ID", BIGQUERY_VALID_CHARACTERS), - }, - { - message: - "What is the name of the Cloud Firestore collection for which you want to generate a schema view?", - name: "tableNamePrefix", - type: "input", - validate: (value) => - validateInput(value, "table name prefix", BIGQUERY_VALID_CHARACTERS), - }, - { - message: - "Where should this script look for schema definitions? (Enter a comma-separated list of, optionally globbed, paths to files or directories).", - name: "schemaFiles", - type: "input", - }, -]; - -interface CliConfig { - projectId: string; - bigQueryProjectId: string; - datasetId: string; - tableNamePrefix: string; - schemas: { [schemaName: string]: FirestoreSchema }; -} - -async function run(): Promise { - // Get all configuration options via inquirer prompt or commander flags. - const config: CliConfig = await parseConfig(); +export async function run(): Promise { + const config = await parseConfig(); - // Set project ID so it can be used in BigQuery intialization process.env.PROJECT_ID = config.projectId; - // BigQuery actually requires this variable to set the project correctly. process.env.GOOGLE_CLOUD_PROJECT = config.bigQueryProjectId; - // Initialize Firebase if (!firebase.apps.length) { firebase.initializeApp({ credential: firebase.credential.applicationDefault(), @@ -143,67 +35,51 @@ async function run(): Promise { }); } - // @ts-ignore string not assignable to enum - if (Object.keys(config.schemas).length === 0) { - console.log(`No schema files found!`); - } const viewFactory = new FirestoreBigQuerySchemaViewFactory( config.bigQueryProjectId ); - for (const schemaName in config.schemas) { + + // Generate schema files using Gemini if enabled + // Otherwise, read schema files from the filesystem + let schemas = config.schemas; + if (config.useGemini) { + try { + await generateSchemaFilesWithGemini(config); + schemas = readSchemas([`./schemas/${config.geminiSchemaFileName}.json`]); + + console.log("Schema file generated successfully."); + } catch (error) { + console.error("Error during schema generation:", error); + throw error; + } + } else { + if (Object.keys(config.schemas).length === 0) { + console.log(`No schema files found!`); + } + } + + // Initialize schema views + for (const name in schemas) { await viewFactory.initializeSchemaViewResources( config.datasetId, config.tableNamePrefix, - schemaName, - config.schemas[schemaName] + name, + schemas[name] ); } + return 0; } -async function parseConfig(): Promise { - program.parse(process.argv); - if (program.nonInteractive) { - if ( - program.project === undefined || - program.bigQueryProject === undefined || - program.dataset === undefined || - program.tableNamePrefix === undefined || - program.schemaFiles.length === 0 - ) { - program.outputHelp(); - process.exit(1); - } - - return { - projectId: program.project, - bigQueryProjectId: program.bigQueryProject, - datasetId: program.dataset, - tableNamePrefix: program.tableNamePrefix, - schemas: readSchemas(program.schemaFiles), - }; - } - const { project, bigQueryProject, dataset, tableNamePrefix, schemaFiles } = - await inquirer.prompt(questions); - - return { - projectId: project, - bigQueryProjectId: bigQueryProject, - datasetId: dataset, - tableNamePrefix: tableNamePrefix, - schemas: readSchemas( - schemaFiles.split(",").map((schemaFileName) => schemaFileName.trim()) - ), - }; +if (process.env.NODE_ENV !== "test") { + run() + .then((result) => { + console.log("done."); + process.exit(); + }) + .catch((error) => { + console.log(JSON.stringify(error)); + console.error(error.message); + process.exit(); + }); } - -run() - .then((result) => { - console.log("done."); - process.exit(); - }) - .catch((error) => { - console.log(JSON.stringify(error)); - console.error(error.message); - process.exit(); - }); diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/schema/extractors.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/schema/extractors.ts index 7f31cb230..3d57712ec 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/src/schema/extractors.ts +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/schema/extractors.ts @@ -1,3 +1,19 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + /** * Extract a field from a raw JSON string that lives in the column * `dataFieldName`. The result of this function is a clause which can be used in diff --git a/firestore-bigquery-export/scripts/gen-schema-view/src/schema/genkit.ts b/firestore-bigquery-export/scripts/gen-schema-view/src/schema/genkit.ts new file mode 100644 index 000000000..46dc33a76 --- /dev/null +++ b/firestore-bigquery-export/scripts/gen-schema-view/src/schema/genkit.ts @@ -0,0 +1,305 @@ +/* + * Copyright 2025 Google LLC + * + * 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 + * + * https://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. + */ + +import type { CliConfig } from "../config"; +import firebase = require("firebase-admin"); +import { genkit, z } from "genkit"; +import { googleAI, gemini20Flash } from "@genkit-ai/googleai"; +import * as fs from "fs"; +import * as path from "path"; +import inquirer from "inquirer"; + +export async function sampleFirestoreDocuments( + collectionPath: string, + sampleSize: number +): Promise { + const db = firebase.firestore(); + + try { + const snapshot = await db + .collection(collectionPath) + .where("__name__", ">=", Math.random().toString()) + .limit(sampleSize) + .get(); + + const documents = snapshot.docs.map((doc) => { + const data = doc.data(); + return serializeDocument(data); + }); + + return documents; + } catch (error) { + console.error("Error sampling documents:", error); + throw error; + } +} + +export function serializeDocument(data: any): any { + if (!data) return null; + + if (data instanceof Date) { + return { _type: "timestamp", value: data.toISOString() }; + } + + if (data instanceof firebase.firestore.GeoPoint) { + return { + _type: "geopoint", + latitude: data.latitude, + longitude: data.longitude, + }; + } + + if (data instanceof firebase.firestore.DocumentReference) { + return { _type: "reference", path: data.path }; + } + + if (Array.isArray(data)) { + return data.map((item) => serializeDocument(item)); + } + + if (typeof data === "object") { + const result = {}; + for (const [key, value] of Object.entries(data)) { + result[key] = serializeDocument(value); + } + return result; + } + + return data; +} + +const biqquerySchemaPrompt = ({ + collectionPath, + sampleData, +}: { + collectionPath: string; + sampleData: any[]; +}) => ` + You are a Schema Management Agent for Generating BigQuery schemas from Firestore Collections. + Your primary tasks are: + 1. Analyze the provided sample documents + 2. Generate an appropriate BigQuery schema + + I will provide you with sample documents from the collection "${collectionPath}". + + Here are the sample documents to analyze: + ${JSON.stringify(sampleData, null, 2)} + + The schemas must follow this format: + { + "fields": [ + { + "name": "fieldName", + "type": "string|array|map|boolean|number|timestamp|geopoint|reference|null|stringified_map", + "description": "Detailed description of what this field represents", + "fields": [] // Only for type "map" + } + ] + } + + Important schema rules: + - Each field MUST have a "description" that explains its purpose and contents + - For "map" types, include descriptions for both the map and its nested fields + - Array fields should specify what type of elements they contain in the description + - Include any relevant business logic or constraints in the descriptions + - For fields with specific formats (like timestamps), include format information + + Example schema with good descriptions: + { + "fields": [ + { + "name": "name", + "type": "string", + "description": "User's full name in display format" + }, + { + "name": "favorite_numbers", + "type": "array", + "description": "Array of user's favorite numbers, stored as strings" + }, + { + "name": "last_login", + "type": "timestamp", + "description": "Timestamp of user's most recent login in UTC" + }, + { + "name": "last_location", + "type": "geopoint", + "description": "User's last known geographical location as latitude/longitude" + }, + { + "fields": [ + { + "name": "name", + "type": "string", + "description": "Friend's display name in the user's friend list" + } + ], + "name": "friends", + "type": "map", + "description": "Collection of user's friends and their associated data" + } + ] + } + + IMPORTANT: After analyzing the sample data: + 1. Generate a schema with detailed descriptions for ALL fields + 2. Make sure all fields are correctly represented in the schema, and described and formatted + 3. SQL has a number of reserved keywords that can cause conflicts when creating a schema, timestamp is one such example. + To ensure your Firestore document field names do not conflict, use the column_name option to override the field name. + for example: + { + "fields": [ + { + "name": "name", + "type": "string" + }, + { + "name": "age", + "type": "number", + "column_name": "new_column_name" + } + ] + } + + Begin by analyzing the sample data and then create a well-documented schema. + + Remember that there is no need to destructure timestamp or geopoint fields, they can be left for example as: + \`\`\` + { + "name": "last_login", + "type": "timestamp" + }, + { + "name": "last_location", + "type": "geopoint" + }, + \`\`\` + The script reading the generated schemas will deal with them appropriately. + + Please respond ONLY with the schema in json format + `; + +export const generateSchemaFilesWithGemini = async (config: CliConfig) => { + // get sample data from Firestore + const sampleData = await sampleFirestoreDocuments( + config.geminiAnalyzeCollectionPath!, + config.agentSampleSize! + ); + + if (sampleData.length === 0) { + console.log( + "Operation cancelled. No sample data found. Either the collection is empty or the collection path is incorrect." + ); + process.exit(0); + } + console.log( + `Successfully sampled ${sampleData.length} documents from collection ${config.geminiAnalyzeCollectionPath}` + ); + + const prompt = biqquerySchemaPrompt({ + collectionPath: config.geminiAnalyzeCollectionPath!, + sampleData, + }); + + // initialize genkit with googleAI plugin + const ai = genkit({ + plugins: [ + googleAI({ + apiKey: config.googleAiKey, + }), + ], + }); + + // prompt gemini with sample data to generate a schema file + const { text } = await ai.generate({ + model: gemini20Flash, + prompt, + output: { + format: "json", + schema: z.object({ + fields: z.array( + z.object({ + name: z.string(), + type: z.string(), + description: z.string(), + fields: z.array( + z.object({ + name: z.string(), + type: z.string(), + description: z.string(), + fields: z.array( + z.object({ + name: z.string(), + type: z.string(), + description: z.string(), + column_name: z.string().optional(), + }) + ), + }) + ), + }) + ), + }), + }, + }); + + const filePath = path.join( + config.schemaDirectory, + `${config.geminiSchemaFileName}.json` + ); + + // Check if a file exists + if (fs.existsSync(filePath)) { + const overwriteConfirm = await inquirer.prompt([ + { + type: "confirm", + name: "proceed", + message: "Schema file already exists. Would you like to overwrite it?", + default: false, + }, + ]); + + if (!overwriteConfirm.proceed) { + console.log( + "Operation cancelled. Please choose a different schema file name." + ); + process.exit(0); + } + } + await fs.promises.writeFile(filePath, text); + + const absoluteFilePath = path.resolve(filePath); + + console.log(`Schema file saved to: file://${absoluteFilePath}`); + + // confirm with user that schema file is correct + const confirmation = await inquirer.prompt([ + { + type: "confirm", + name: "proceed", + message: `Have you reviewed the schema, and want to proceed with creating the views?`, + default: false, + }, + ]); + + if (!confirmation.proceed) { + console.log( + "Operation cancelled. Please modify the schema file and run the script again." + ); + process.exit(0); + } +}; diff --git a/firestore-bigquery-export/scripts/gen-schema-view/tsconfig.json b/firestore-bigquery-export/scripts/gen-schema-view/tsconfig.json index 7cf2f14c0..029cbf35a 100644 --- a/firestore-bigquery-export/scripts/gen-schema-view/tsconfig.json +++ b/firestore-bigquery-export/scripts/gen-schema-view/tsconfig.json @@ -1,11 +1,14 @@ { "compilerOptions": { - "lib": ["es6"], - "module": "commonjs", + "lib": ["ESNext"], + "module": "CommonJS", + "moduleResolution": "node", "noImplicitReturns": true, "outDir": "lib", "sourceMap": false, - "target": "es6" + "target": "ES2020", + "esModuleInterop": true, + "skipLibCheck": true }, "compileOnSave": true, "include": ["src"] diff --git a/firestore-bigquery-export/scripts/import/package-lock.json b/firestore-bigquery-export/scripts/import/package-lock.json index 5e79eab5a..5b421f8ba 100644 --- a/firestore-bigquery-export/scripts/import/package-lock.json +++ b/firestore-bigquery-export/scripts/import/package-lock.json @@ -651,7 +651,6 @@ "version": "1.1.39", "resolved": "https://registry.npmjs.org/@firebaseextensions/firestore-bigquery-change-tracker/-/firestore-bigquery-change-tracker-1.1.39.tgz", "integrity": "sha512-KLLdu6CN2azcisQtfxNnecXv44c4uypJ0II68jpKUbAUkfClSbutDCe5b25Wyt3Tkt7w4XGWFWhYx4IyuUPe8w==", - "license": "Apache-2.0", "dependencies": { "@google-cloud/bigquery": "^7.6.0", "@google-cloud/resource-manager": "^5.1.0", @@ -669,7 +668,6 @@ "version": "7.9.2", "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-7.9.2.tgz", "integrity": "sha512-Yo7oYE6m7bBT28tYDn6dBwbXZxCt+nWREj/0y5aoUq0rFUGwLUDKAXwgt6OQJ2htDzGiQ3s0yltCBjKFtqVCmA==", - "license": "Apache-2.0", "dependencies": { "@google-cloud/common": "^5.0.0", "@google-cloud/paginator": "^5.0.2", @@ -691,7 +689,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==", - "license": "Apache-2.0", "dependencies": { "@google-cloud/projectify": "^4.0.0", "@google-cloud/promisify": "^4.0.0", @@ -711,7 +708,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "license": "Apache-2.0", "dependencies": { "arrify": "^2.0.0", "extend": "^3.0.2" @@ -724,7 +720,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "license": "Apache-2.0", "engines": { "node": ">=14.0.0" } @@ -733,7 +728,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "license": "Apache-2.0", "engines": { "node": ">=14" } @@ -742,7 +736,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "license": "MIT", "engines": { "node": ">= 14" } @@ -751,7 +744,6 @@ "version": "6.7.1", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", - "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -767,7 +759,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "4" @@ -780,7 +771,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", - "license": "Apache-2.0", "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", @@ -794,7 +784,6 @@ "version": "9.15.1", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", - "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -811,7 +800,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "license": "MIT", "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -824,7 +812,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", - "license": "MIT", "dependencies": { "@types/request": "^2.48.8", "extend": "^3.0.2", @@ -838,7 +825,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", - "license": "Apache-2.0", "dependencies": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -858,7 +844,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -931,7 +916,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@google-cloud/precise-date/-/precise-date-4.0.0.tgz", "integrity": "sha512-1TUx3KdaU3cN7nfCdNf+UVqA/PSX29Cjcox3fZZBtINlRrXVTmUkQnCKv2MbBUbCopbK4olAT1IHl76uZyCiVA==", - "license": "Apache-2.0", "engines": { "node": ">=14.0.0" } @@ -951,10 +935,9 @@ } }, "node_modules/@google-cloud/resource-manager": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/resource-manager/-/resource-manager-5.3.0.tgz", - "integrity": "sha512-uWJJf6S2PJL7oZ4ezv16aZl9+IJqPo5GzUv1pZ3/qRiMj13p0ylEgX1+LxBpX71eEPKTwMHoJV2IBBe3EAq7Xw==", - "license": "Apache-2.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/resource-manager/-/resource-manager-5.3.1.tgz", + "integrity": "sha512-/7fzwFY6xhvEqkTd2Li/Tg0KThuAoJSIR3zIWNsGS2VGCyqaIt6IgkzpnvFzEUWr/d5hjna+ol4J0fVTAS8puQ==", "dependencies": { "google-gax": "^4.0.3" }, @@ -2147,7 +2130,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" @@ -2167,7 +2149,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", @@ -2203,7 +2184,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -2224,7 +2204,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -2550,7 +2529,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", @@ -2578,13 +2556,12 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", - "license": "MIT", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -2917,7 +2894,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -2934,7 +2910,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -2951,7 +2926,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -3033,7 +3007,8 @@ }, "node_modules/define-data-property": { "version": "1.1.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -3050,7 +3025,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -3212,7 +3186,6 @@ "version": "1.23.9", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", @@ -3305,7 +3278,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -3320,7 +3292,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "license": "MIT", "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", @@ -3731,7 +3702,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "license": "MIT", "dependencies": { "is-callable": "^1.2.7" }, @@ -3788,7 +3758,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -3813,7 +3782,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3882,17 +3850,16 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", - "license": "MIT", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -3941,7 +3908,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -3989,7 +3955,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -4174,7 +4139,6 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", - "license": "Apache-2.0", "engines": { "node": ">=14" } @@ -4225,7 +4189,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4242,7 +4205,8 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { "es-define-property": "^1.0.0" }, @@ -4254,7 +4218,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.0" }, @@ -4281,7 +4244,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -4315,8 +4277,7 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ], - "license": "MIT" + ] }, "node_modules/html-escaper": { "version": "2.0.2", @@ -4521,7 +4482,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", @@ -4549,7 +4509,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -4571,7 +4530,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "license": "MIT", "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", @@ -4590,7 +4548,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "license": "MIT", "dependencies": { "has-bigints": "^1.0.2" }, @@ -4605,7 +4562,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4621,7 +4577,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4644,7 +4599,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", @@ -4661,7 +4615,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -4677,7 +4630,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4707,7 +4659,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", @@ -4725,7 +4676,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4745,7 +4695,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4761,7 +4710,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", @@ -4779,7 +4727,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4791,7 +4738,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4816,7 +4762,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -4832,7 +4777,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", @@ -4849,7 +4793,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" }, @@ -4864,7 +4807,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4876,7 +4818,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3" }, @@ -4891,7 +4832,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" @@ -4906,8 +4846,7 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "license": "MIT" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", @@ -6568,7 +6507,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -6577,7 +6515,6 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -6631,7 +6568,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", @@ -6825,7 +6761,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7034,7 +6969,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -7056,7 +6990,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -7188,7 +7121,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -7225,7 +7157,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" @@ -7241,7 +7172,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -7335,7 +7265,8 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7352,7 +7283,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7367,7 +7297,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", @@ -7631,7 +7560,6 @@ "version": "1.2.10", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -7652,7 +7580,6 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -7670,7 +7597,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7864,7 +7790,6 @@ "version": "0.6.11", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz", "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==", - "license": "MIT", "dependencies": { "gopd": "^1.2.0", "typedarray.prototype.slice": "^1.0.5", @@ -8040,7 +7965,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -8054,7 +7978,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", @@ -8073,7 +7996,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -8094,7 +8016,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -8114,7 +8035,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -8148,7 +8068,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", @@ -8302,7 +8221,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "license": "MIT", "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", @@ -8321,7 +8239,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", @@ -8348,7 +8265,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -8363,15 +8279,15 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", - "license": "MIT", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, diff --git a/firestore-translate-text/CHANGELOG.md b/firestore-translate-text/CHANGELOG.md index 09cdd3950..0a857c01a 100644 --- a/firestore-translate-text/CHANGELOG.md +++ b/firestore-translate-text/CHANGELOG.md @@ -1,3 +1,7 @@ +## Version 0.1.23 + +fixed - backfill feature is disabled for now + ## Version 0.1.22 feat - move to Node.js 20 runtimes diff --git a/firestore-translate-text/README.md b/firestore-translate-text/README.md index c4b3e0059..17fa75050 100644 --- a/firestore-translate-text/README.md +++ b/firestore-translate-text/README.md @@ -89,17 +89,12 @@ To install an extension, your project must be on the [Blaze (pay as you go) plan * Google AI API key: If you selected AI Translations Using Gemini to perform translations, please provide a Google AI API key, which you can create here: https://ai.google.dev/gemini-api/docs/api-key -* Translate existing documents?: Should existing documents in the Firestore collection be translated as well? If you've added new languages since a document was translated, this will fill those in as well. - - **Cloud Functions:** * **fstranslate:** Listens for writes of new strings to your specified Cloud Firestore collection, translates the strings, then writes the translated strings back to the same document. -* **fstranslatebackfill:** Searches your specified Cloud Firestore collection for existing documents, translates the strings into any missing languages, then writes the translated strings back to the same document. - **APIs Used**: diff --git a/firestore-translate-text/extension.yaml b/firestore-translate-text/extension.yaml index 9bde5f85f..3db3afd55 100644 --- a/firestore-translate-text/extension.yaml +++ b/firestore-translate-text/extension.yaml @@ -13,7 +13,7 @@ # limitations under the License. name: firestore-translate-text -version: 0.1.22 +version: 0.1.23 specVersion: v1beta tags: [ai] @@ -65,17 +65,18 @@ resources: eventType: providers/cloud.firestore/eventTypes/document.write resource: projects/${param:PROJECT_ID}/databases/(default)/documents/${param:COLLECTION_PATH}/{messageId} - - name: fstranslatebackfill - type: firebaseextensions.v1beta.function - description: - Searches your specified Cloud Firestore collection for existing documents, - translates the strings into any missing languages, then writes the - translated strings back to the same document. - properties: - runtime: nodejs20 - availableMemoryMb: 1024 - timeout: 540s - taskQueueTrigger: {} + # ! DO NOT UNCOMMENT THIS PARAMETER, IT IS CURRENTLY PROBLEMATIC + # - name: fstranslatebackfill + # type: firebaseextensions.v1beta.function + # description: + # Searches your specified Cloud Firestore collection for existing documents, + # translates the strings into any missing languages, then writes the + # translated strings back to the same document. + # properties: + # runtime: nodejs20 + # availableMemoryMb: 1024 + # timeout: 540s + # taskQueueTrigger: {} params: - param: LANGUAGES @@ -154,19 +155,20 @@ params: type: secret required: false - - param: DO_BACKFILL - label: Translate existing documents? - description: > - Should existing documents in the Firestore collection be translated as - well? If you've added new languages since a document was translated, this - will fill those in as well. - type: select - required: true - options: - - label: Yes - value: true - - label: No - value: false + # ! DO NOT UNCOMMENT THIS PARAMETER, IT IS CURRENTLY PROBLEMATIC + # - param: DO_BACKFILL + # label: Translate existing documents? + # description: > + # Should existing documents in the Firestore collection be translated as + # well? If you've added new languages since a document was translated, this + # will fill those in as well. + # type: select + # required: true + # options: + # - label: Yes + # value: true + # - label: No + # value: false events: - type: firebase.extensions.firestore-translate-text.v1.onStart @@ -188,6 +190,7 @@ events: description: Occurs when the function is settled. Provides no customized data other than the context. +# ! DO NOT UNCOMMENT THE BELOW, IT IS CURRENTLY PROBLEMATIC # lifecycleEvents: # onInstall: # function: fstranslatebackfill diff --git a/firestore-translate-text/functions/src/config.ts b/firestore-translate-text/functions/src/config.ts index 8f9081e83..4f6a3cc3b 100644 --- a/firestore-translate-text/functions/src/config.ts +++ b/firestore-translate-text/functions/src/config.ts @@ -15,7 +15,7 @@ */ export default { - doBackfill: process.env.DO_BACKFILL === "true", + doBackfill: false, languages: Array.from(new Set(process.env.LANGUAGES.split(","))), location: process.env.LOCATION, inputFieldName: process.env.INPUT_FIELD_NAME,